[
https://issues.apache.org/jira/browse/HTTPCLIENT-2074?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Eugen Covaci updated HTTPCLIENT-2074:
-------------------------------------
Description:
I do have a server socket listening on a local port. Using Postman, I'm making
a CONNECT request to the server socket for an random address, let's say
www.iana.org:443. Then I'm trying to parse the request using:
{code:java}
SessionInputBufferImpl inputBuffer = new SessionInputBufferImpl(bufferSize);
ClassicHttpRequest request = new DefaultHttpRequestParser().parse(inputBuffer,
localSocketChannel.getInputStream());
URI requestUri = request.getUri();
{code}
The requestUri I get is "/" instead of the initial "www.iana.org:443".
Also, calling request.toString() I get "CONNECT www.iana.org://null/" which is
definitely wrong.
Here is a full test:
{code:java}
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.impl.io.DefaultHttpRequestParser;
import org.apache.hc.core5.http.impl.io.SessionInputBufferImpl;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
class BugTests {
int SERVER_SOCKET_PORT = 3128;
private AsynchronousServerSocketChannel serverSocket;
@BeforeAll
void before() throws IOException {
serverSocket = AsynchronousServerSocketChannel.open()
.bind(new InetSocketAddress(SERVER_SOCKET_PORT));
serverSocket.accept(null, new
CompletionHandler<AsynchronousSocketChannel, Void>() {
public void completed(AsynchronousSocketChannel socketChanel, Void
att) {
try {
// accept the next connection
serverSocket.accept(null, this);
} catch (Exception e) {
e.printStackTrace();
}
// Handle this connection.
try {
// Prepare request parsing (this is the client's request)
SessionInputBufferImpl inputBuffer = new
SessionInputBufferImpl(4 * 1024);
InputStream inputStream = new InputStream() {
@Override
public int read() {
throw new RuntimeException("Do not use it");
}
@Override
public int read(byte[] b, int off, int len) throws
IOException {
ByteBuffer buffer = ByteBuffer.wrap(b, off, len);
try {
return socketChanel.read(buffer).get();
} catch (ExecutionException e) {
throw new IOException(e.getCause());
} catch (Exception e) {
throw new IOException(e);
}
}
};
// Parse the request (all but the message body)
ClassicHttpRequest request = new
DefaultHttpRequestParser().parse(inputBuffer, inputStream);
System.out.println("*** Request URI [" +
request.getRequestUri() + "]");
// We do not give a response back to the client
// so this connection will hang !!!
} catch (Exception e) {
e.printStackTrace();
}
}
public void failed(Throwable exc, Void att) {
if (!(exc instanceof
java.nio.channels.AsynchronousCloseException)) {
exc.printStackTrace();
}
}
});
}
@Test
void request_Connect() throws IOException, URISyntaxException {
try (CloseableHttpClient httpClient =
HttpClientBuilder.create().build()) {
HttpHost target = HttpHost.create("http://localhost:" +
SERVER_SOCKET_PORT);
BasicClassicHttpRequest request = new
BasicClassicHttpRequest("CONNECT", "www.iana.org:443");
try (CloseableHttpResponse response = httpClient.execute(target,
request)) {
// Ignore response
}
}
}
@AfterAll
void after() {
try {
serverSocket.close();
} catch (IOException e) {
// Ignore
}
}
}
{code}
was:
I do have a server socket listening on a local port. Using Postman, I'm making
a CONNECT request to the server socket for an random address, let's say
www.iana.org:443. Then I'm trying to parse the request using:
{code:java}
SessionInputBufferImpl inputBuffer = new SessionInputBufferImpl(bufferSize);
ClassicHttpRequest request = new DefaultHttpRequestParser().parse(inputBuffer,
localSocketChannel.getInputStream());
URI requestUri = request.getUri();
{code}
The requestUri I get is "/" instead of the initial "www.iana.org:443".
Also, calling request.toString() I get "CONNECT www.iana.org://null/" which is
definitely wrong.
Here is a full test:
{code:java}
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.impl.io.DefaultHttpRequestParser;
import org.apache.hc.core5.http.impl.io.SessionInputBufferImpl;
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.ExecutionException;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class BugTests {
int SERVER_SOCKET_PORT = 3128;
private AsynchronousServerSocketChannel serverSocket;
@BeforeAll
void before() throws IOException {
serverSocket = AsynchronousServerSocketChannel.open()
.bind(new InetSocketAddress(SERVER_SOCKET_PORT));
serverSocket.accept(null, new
CompletionHandler<AsynchronousSocketChannel, Void>() {
public void completed(AsynchronousSocketChannel socketChanel, Void
att) {
try {
// accept the next connection
serverSocket.accept(null, this);
} catch (Exception e) {
e.printStackTrace();
}
// Handle this connection.
try {
// Prepare request parsing (this is the client's request)
SessionInputBufferImpl inputBuffer = new
SessionInputBufferImpl(4 * 1024);
InputStream inputStream = new InputStream() {
@Override
public int read() {
throw new RuntimeException("Do not use it");
}
@Override
public int read(byte[] b, int off, int len) throws
IOException {
ByteBuffer buffer = ByteBuffer.wrap(b, off, len);
try {
return socketChanel.read(buffer).get();
} catch (ExecutionException e) {
throw new IOException(e.getCause());
} catch (Exception e) {
throw new IOException(e);
}
}
};
// Parse the request (all but the message body)
ClassicHttpRequest request = new
DefaultHttpRequestParser().parse(inputBuffer, inputStream);
System.out.println("*** Request URI [" +
request.getRequestUri() + "]");
// We do not give a response back to the client
// so this connection will hang !!!
} catch (Exception e) {
e.printStackTrace();
}
}
public void failed(Throwable exc, Void att) {
if (!(exc instanceof
java.nio.channels.AsynchronousCloseException)) {
exc.printStackTrace();
}
}
});
}
@Test
void request_Connect() throws IOException, URISyntaxException {
try (CloseableHttpClient httpClient =
HttpClientBuilder.create().build()) {
HttpHost target = HttpHost.create("http://localhost:" +
SERVER_SOCKET_PORT);
BasicClassicHttpRequest request = new
BasicClassicHttpRequest("CONNECT", "www.iana.org:443");
try (CloseableHttpResponse response = httpClient.execute(target,
request)) {
// Ignore response
}
}
}
@AfterAll
void after() {
try {
serverSocket.close();
} catch (IOException e) {
// Ignore
}
}
}
{code}
> HttpClient incorrectly parses the CONNECT request URI
> ------------------------------------------------------
>
> Key: HTTPCLIENT-2074
> URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2074
> Project: HttpComponents HttpClient
> Issue Type: Bug
> Components: HttpClient (classic)
> Affects Versions: 5.0
> Reporter: Eugen Covaci
> Priority: Major
>
> I do have a server socket listening on a local port. Using Postman, I'm
> making a CONNECT request to the server socket for an random address, let's
> say www.iana.org:443. Then I'm trying to parse the request using:
> {code:java}
> SessionInputBufferImpl inputBuffer = new SessionInputBufferImpl(bufferSize);
> ClassicHttpRequest request = new
> DefaultHttpRequestParser().parse(inputBuffer,
> localSocketChannel.getInputStream());
> URI requestUri = request.getUri();
> {code}
> The requestUri I get is "/" instead of the initial "www.iana.org:443".
> Also, calling request.toString() I get "CONNECT www.iana.org://null/" which
> is definitely wrong.
> Here is a full test:
> {code:java}
> import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
> import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
> import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
> import org.apache.hc.core5.http.ClassicHttpRequest;
> import org.apache.hc.core5.http.HttpHost;
> import org.apache.hc.core5.http.impl.io.DefaultHttpRequestParser;
> import org.apache.hc.core5.http.impl.io.SessionInputBufferImpl;
> import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
> import org.junit.jupiter.api.AfterAll;
> import org.junit.jupiter.api.BeforeAll;
> import org.junit.jupiter.api.Test;
> import org.junit.jupiter.api.TestInstance;
> import java.io.IOException;
> import java.io.InputStream;
> import java.net.InetSocketAddress;
> import java.net.URISyntaxException;
> import java.nio.ByteBuffer;
> import java.nio.channels.AsynchronousServerSocketChannel;
> import java.nio.channels.AsynchronousSocketChannel;
> import java.nio.channels.CompletionHandler;
> import java.util.concurrent.ExecutionException;
> class BugTests {
> int SERVER_SOCKET_PORT = 3128;
> private AsynchronousServerSocketChannel serverSocket;
> @BeforeAll
> void before() throws IOException {
> serverSocket = AsynchronousServerSocketChannel.open()
> .bind(new InetSocketAddress(SERVER_SOCKET_PORT));
> serverSocket.accept(null, new
> CompletionHandler<AsynchronousSocketChannel, Void>() {
> public void completed(AsynchronousSocketChannel socketChanel,
> Void att) {
> try {
> // accept the next connection
> serverSocket.accept(null, this);
> } catch (Exception e) {
> e.printStackTrace();
> }
> // Handle this connection.
> try {
> // Prepare request parsing (this is the client's request)
> SessionInputBufferImpl inputBuffer = new
> SessionInputBufferImpl(4 * 1024);
> InputStream inputStream = new InputStream() {
> @Override
> public int read() {
> throw new RuntimeException("Do not use it");
> }
> @Override
> public int read(byte[] b, int off, int len) throws
> IOException {
> ByteBuffer buffer = ByteBuffer.wrap(b, off, len);
> try {
> return socketChanel.read(buffer).get();
> } catch (ExecutionException e) {
> throw new IOException(e.getCause());
> } catch (Exception e) {
> throw new IOException(e);
> }
> }
> };
> // Parse the request (all but the message body)
> ClassicHttpRequest request = new
> DefaultHttpRequestParser().parse(inputBuffer, inputStream);
> System.out.println("*** Request URI [" +
> request.getRequestUri() + "]");
> // We do not give a response back to the client
> // so this connection will hang !!!
> } catch (Exception e) {
> e.printStackTrace();
> }
> }
> public void failed(Throwable exc, Void att) {
> if (!(exc instanceof
> java.nio.channels.AsynchronousCloseException)) {
> exc.printStackTrace();
> }
> }
> });
> }
> @Test
> void request_Connect() throws IOException, URISyntaxException {
> try (CloseableHttpClient httpClient =
> HttpClientBuilder.create().build()) {
> HttpHost target = HttpHost.create("http://localhost:" +
> SERVER_SOCKET_PORT);
> BasicClassicHttpRequest request = new
> BasicClassicHttpRequest("CONNECT", "www.iana.org:443");
> try (CloseableHttpResponse response = httpClient.execute(target,
> request)) {
> // Ignore response
> }
> }
> }
> @AfterAll
> void after() {
> try {
> serverSocket.close();
> } catch (IOException e) {
> // Ignore
> }
> }
> }
> {code}
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]