Correctly handle WebSockets 00 when using HttpClientCodec.

Motivation:

7995afee8f introduced a change that broke special handling of WebSockets 00.

Modifications:

Correctly delegate to super method which has special handling for WebSockets 00.

Result:

Fixes [#7362].
This commit is contained in:
Norman Maurer 2017-11-03 08:28:34 +01:00
parent 93130b172a
commit e0bbff74f7
2 changed files with 29 additions and 9 deletions

View File

@ -225,7 +225,8 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
final int statusCode = ((HttpResponse) msg).status().code(); final int statusCode = ((HttpResponse) msg).status().code();
if (statusCode == 100 || statusCode == 101) { if (statusCode == 100 || statusCode == 101) {
// 100-continue and 101 switching protocols response should be excluded from paired comparison. // 100-continue and 101 switching protocols response should be excluded from paired comparison.
return true; // Just delegate to super method which has all the needed handling.
return super.isContentAlwaysEmpty(msg);
} }
// Get the getMethod of the HTTP request that corresponds to the // Get the getMethod of the HTTP request that corresponds to the
@ -236,7 +237,7 @@ public final class HttpClientCodec extends CombinedChannelDuplexHandler<HttpResp
switch (firstChar) { switch (firstChar) {
case 'H': case 'H':
// According to 4.3, RFC2616: // According to 4.3, RFC2616:
// All responses to the HEAD request getMethod MUST NOT include a // All responses to the HEAD request method MUST NOT include a
// message-body, even though the presence of entity-header fields // message-body, even though the presence of entity-header fields
// might lead one to believe they do. // might lead one to believe they do.
if (HttpMethod.HEAD.equals(method)) { if (HttpMethod.HEAD.equals(method)) {

View File

@ -42,14 +42,9 @@ import java.util.concurrent.CountDownLatch;
import static io.netty.util.ReferenceCountUtil.release; import static io.netty.util.ReferenceCountUtil.release;
import static java.util.concurrent.TimeUnit.SECONDS; import static java.util.concurrent.TimeUnit.SECONDS;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.*;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class HttpClientCodecTest { public class HttpClientCodecTest {
@ -312,4 +307,28 @@ public class HttpClientCodecTest {
((FullHttpResponse) finalResponse).release(); ((FullHttpResponse) finalResponse).release();
assertTrue("Channel finish failed", ch.finishAndReleaseAll()); assertTrue("Channel finish failed", ch.finishAndReleaseAll());
} }
@Test
public void testWebSocket00Response() {
byte[] data = ("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" +
"Upgrade: WebSocket\r\n" +
"Connection: Upgrade\r\n" +
"Sec-WebSocket-Origin: http://localhost:8080\r\n" +
"Sec-WebSocket-Location: ws://localhost/some/path\r\n" +
"\r\n" +
"1234567812345678").getBytes();
EmbeddedChannel ch = new EmbeddedChannel(new HttpClientCodec());
assertTrue(ch.writeInbound(Unpooled.wrappedBuffer(data)));
HttpResponse res = ch.readInbound();
assertThat(res.protocolVersion(), sameInstance(HttpVersion.HTTP_1_1));
assertThat(res.status(), is(HttpResponseStatus.SWITCHING_PROTOCOLS));
HttpContent content = ch.readInbound();
assertThat(content.content().readableBytes(), is(16));
content.release();
assertThat(ch.finish(), is(false));
assertThat(ch.readInbound(), is(nullValue()));
}
} }