Fix possible NPE when using HttpClientCodec (#9465)
Motivation: It was possible to produce a NPE when we for examples received more responses as requests as we did not check if the queue did not contain a method before trying to compare method names. Modifications: - Add extra null check - Add unit tet Result: Fixes https://github.com/netty/netty/issues/9459
This commit is contained in:
parent
d4038d0937
commit
9ec3411c91
@ -160,7 +160,7 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg instanceof HttpRequest && !done) {
|
||||
if (msg instanceof HttpRequest) {
|
||||
queue.offer(((HttpRequest) msg).method());
|
||||
}
|
||||
|
||||
@ -233,6 +233,9 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
|
||||
// current response.
|
||||
HttpMethod method = queue.poll();
|
||||
|
||||
// If the remote peer did for example send multiple responses for one request (which is not allowed per
|
||||
// spec but may still be possible) method will be null so guard against it.
|
||||
if (method != null) {
|
||||
char firstChar = method.name().charAt(0);
|
||||
switch (firstChar) {
|
||||
case 'H':
|
||||
@ -261,8 +264,8 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
|
||||
// Successful CONNECT request results in a response with empty body.
|
||||
if (statusCode == 200) {
|
||||
if (HttpMethod.CONNECT.equals(method)) {
|
||||
// Proxy connection established - Parse HTTP only if configured by parseHttpAfterConnectRequest,
|
||||
// else pass through.
|
||||
// Proxy connection established - Parse HTTP only if configured by
|
||||
// parseHttpAfterConnectRequest, else pass through.
|
||||
if (!parseHttpAfterConnectRequest) {
|
||||
done = true;
|
||||
queue.clear();
|
||||
@ -272,7 +275,7 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return super.isContentAlwaysEmpty(msg);
|
||||
}
|
||||
|
||||
|
@ -331,4 +331,28 @@ public class HttpClientCodecTest {
|
||||
|
||||
assertThat(ch.readInbound(), is(nullValue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleResponses() {
|
||||
String response = "HTTP/1.1 200 OK\r\n" +
|
||||
"Content-Length: 0\r\n\r\n";
|
||||
|
||||
HttpClientCodec codec = new HttpClientCodec(4096, 8192, 8192, true);
|
||||
EmbeddedChannel ch = new EmbeddedChannel(codec, new HttpObjectAggregator(1024));
|
||||
|
||||
HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "http://localhost/");
|
||||
assertTrue(ch.writeOutbound(request));
|
||||
|
||||
assertTrue(ch.writeInbound(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8)));
|
||||
assertTrue(ch.writeInbound(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8)));
|
||||
FullHttpResponse resp = ch.readInbound();
|
||||
assertTrue(resp.decoderResult().isSuccess());
|
||||
resp.release();
|
||||
|
||||
resp = ch.readInbound();
|
||||
assertTrue(resp.decoderResult().isSuccess());
|
||||
resp.release();
|
||||
assertTrue(ch.finishAndReleaseAll());
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user