Use allocator when constructing ByteBufHolder sub-types or use Unpool… (#9377)
Motivation: In many places Netty uses Unpooled.buffer(0) while should use EMPTY_BUFFER. We can't change this due to back compatibility in the constructors but can use Unpooled.EMPTY_BUFFER in some cases to ensure we not allocate at all. In others we can directly use the allocator either from the Channel / ChannelHandlerContext or the request / response. Modification: - Use Unpooled.EMPTY_BUFFER where possible - Use allocator where possible Result: Fixes #9345 for websockets and http package
This commit is contained in:
parent
82ac20bec0
commit
e4995be33c
@ -228,7 +228,8 @@ public class CorsHandler implements ChannelHandler {
|
||||
}
|
||||
|
||||
private static void forbidden(final ChannelHandlerContext ctx, final HttpRequest request) {
|
||||
HttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), FORBIDDEN);
|
||||
HttpResponse response = new DefaultFullHttpResponse(
|
||||
request.protocolVersion(), FORBIDDEN, ctx.alloc().buffer(0));
|
||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, HttpHeaderValues.ZERO);
|
||||
release(request);
|
||||
respond(ctx, request, response);
|
||||
|
@ -108,7 +108,7 @@ public class WebSocket00FrameDecoder extends ReplayingDecoder<Void> implements W
|
||||
|
||||
if (type == (byte) 0xFF && frameSize == 0) {
|
||||
receivedClosingHandshake = true;
|
||||
return new CloseWebSocketFrame();
|
||||
return new CloseWebSocketFrame(true, 0, ctx.alloc().buffer(0));
|
||||
}
|
||||
ByteBuf payload = readBytes(ctx.alloc(), buffer, (int) frameSize);
|
||||
return new BinaryWebSocketFrame(payload);
|
||||
|
@ -179,7 +179,8 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
URI wsURL = uri();
|
||||
|
||||
// Format request
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL));
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL),
|
||||
Unpooled.wrappedBuffer(key3));
|
||||
HttpHeaders headers = request.headers();
|
||||
|
||||
if (customHeaders != null) {
|
||||
@ -201,7 +202,6 @@ public class WebSocketClientHandshaker00 extends WebSocketClientHandshaker {
|
||||
// Set Content-Length to workaround some known defect.
|
||||
// See also: http://www.ietf.org/mail-archive/web/hybi/current/msg02149.html
|
||||
headers.set(HttpHeaderNames.CONTENT_LENGTH, key3.length);
|
||||
request.content().writeBytes(key3);
|
||||
return request;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
@ -211,7 +212,8 @@ public class WebSocketClientHandshaker07 extends WebSocketClientHandshaker {
|
||||
}
|
||||
|
||||
// Format request
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL));
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL),
|
||||
Unpooled.EMPTY_BUFFER);
|
||||
HttpHeaders headers = request.headers();
|
||||
|
||||
if (customHeaders != null) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
@ -213,7 +214,8 @@ public class WebSocketClientHandshaker08 extends WebSocketClientHandshaker {
|
||||
}
|
||||
|
||||
// Format request
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL));
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL),
|
||||
Unpooled.EMPTY_BUFFER);
|
||||
HttpHeaders headers = request.headers();
|
||||
|
||||
if (customHeaders != null) {
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpRequest;
|
||||
import io.netty.handler.codec.http.FullHttpResponse;
|
||||
@ -214,7 +215,8 @@ public class WebSocketClientHandshaker13 extends WebSocketClientHandshaker {
|
||||
}
|
||||
|
||||
// Format request
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL));
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, upgradeUrl(wsURL),
|
||||
Unpooled.EMPTY_BUFFER);
|
||||
HttpHeaders headers = request.headers();
|
||||
|
||||
if (customHeaders != null) {
|
||||
|
@ -141,7 +141,8 @@ public class WebSocketServerHandshaker00 extends WebSocketServerHandshaker {
|
||||
|
||||
// Create the WebSocket handshake response.
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, new HttpResponseStatus(101,
|
||||
isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake"));
|
||||
isHixie76 ? "WebSocket Protocol Handshake" : "Web Socket Protocol Handshake"),
|
||||
req.content().alloc().buffer(0));
|
||||
if (headers != null) {
|
||||
res.headers().add(headers);
|
||||
}
|
||||
|
@ -134,7 +134,8 @@ public class WebSocketServerHandshaker07 extends WebSocketServerHandshaker {
|
||||
}
|
||||
|
||||
FullHttpResponse res =
|
||||
new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS);
|
||||
new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
|
||||
req.content().alloc().buffer(0));
|
||||
|
||||
if (headers != null) {
|
||||
res.headers().add(headers);
|
||||
|
@ -140,7 +140,8 @@ public class WebSocketServerHandshaker08 extends WebSocketServerHandshaker {
|
||||
throw new WebSocketHandshakeException("not a WebSocket request: missing key");
|
||||
}
|
||||
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS);
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
|
||||
req.content().alloc().buffer(0));
|
||||
|
||||
if (headers != null) {
|
||||
res.headers().add(headers);
|
||||
|
@ -139,7 +139,8 @@ public class WebSocketServerHandshaker13 extends WebSocketServerHandshaker {
|
||||
throw new WebSocketHandshakeException("not a WebSocket request: missing key");
|
||||
}
|
||||
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS);
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.SWITCHING_PROTOCOLS,
|
||||
req.content().alloc().buffer(0));
|
||||
if (headers != null) {
|
||||
res.headers().add(headers);
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ public class WebSocketServerHandshakerFactory {
|
||||
public static ChannelFuture sendUnsupportedVersionResponse(Channel channel, ChannelPromise promise) {
|
||||
HttpResponse res = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1,
|
||||
HttpResponseStatus.UPGRADE_REQUIRED);
|
||||
HttpResponseStatus.UPGRADE_REQUIRED, channel.alloc().buffer(0));
|
||||
res.headers().set(HttpHeaderNames.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue());
|
||||
HttpUtil.setContentLength(res, 0);
|
||||
return channel.writeAndFlush(res, promise);
|
||||
|
@ -265,7 +265,7 @@ public class WebSocketServerProtocolHandler extends WebSocketProtocolHandler {
|
||||
if (msg instanceof FullHttpRequest) {
|
||||
((FullHttpRequest) msg).release();
|
||||
FullHttpResponse response =
|
||||
new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN);
|
||||
new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN, ctx.alloc().buffer(0));
|
||||
ctx.channel().writeAndFlush(response);
|
||||
} else {
|
||||
ctx.fireChannelRead(msg);
|
||||
|
@ -77,7 +77,7 @@ class WebSocketServerProtocolHandshakeHandler implements ChannelInboundHandler {
|
||||
|
||||
try {
|
||||
if (!GET.equals(req.method())) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN, ctx.alloc().buffer(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ package io.netty.handler.codec.http.websocketx;
|
||||
|
||||
import io.netty.util.concurrent.FastThreadLocal;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Base64;
|
||||
|
@ -53,6 +53,7 @@ public class CorsHandlerTest {
|
||||
public void nonCorsRequest() {
|
||||
final HttpResponse response = simpleRequest(forAnyOrigin().build(), null);
|
||||
assertThat(response.headers().contains(ACCESS_CONTROL_ALLOW_ORIGIN), is(false));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -60,6 +61,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = simpleRequest(forAnyOrigin().build(), "http://localhost:7777");
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is("*"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -70,6 +72,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is("null"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(equalTo("true")));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -78,6 +81,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = simpleRequest(forOrigin(origin).build(), origin);
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(origin));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -88,9 +92,12 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response1 = simpleRequest(forOrigins(origins).build(), origin1);
|
||||
assertThat(response1.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(origin1));
|
||||
assertThat(response1.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response1), is(true));
|
||||
|
||||
final HttpResponse response2 = simpleRequest(forOrigins(origins).build(), origin2);
|
||||
assertThat(response2.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(origin2));
|
||||
assertThat(response2.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response2), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -100,6 +107,7 @@ public class CorsHandlerTest {
|
||||
forOrigins("https://localhost:8888").build(), origin);
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(nullValue()));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -112,6 +120,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_METHODS), containsString("GET"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_METHODS), containsString("DELETE"));
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -127,6 +136,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), containsString("content-type"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_HEADERS), containsString("xheader1"));
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -136,6 +146,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(CONTENT_LENGTH), is("0"));
|
||||
assertThat(response.headers().get(DATE), is(notNullValue()));
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -147,6 +158,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(of("CustomHeader")), equalTo("somevalue"));
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(response.headers().get(CONTENT_LENGTH), is("0"));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -155,6 +167,7 @@ public class CorsHandlerTest {
|
||||
final CorsConfig config = forOrigin("http://localhost").build();
|
||||
final HttpResponse response = preflightRequest(config, origin, "xheader1");
|
||||
assertThat(response.headers().contains(ACCESS_CONTROL_ALLOW_ORIGIN), is(false));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -168,6 +181,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = preflightRequest(config, "http://localhost:8888", "content-type, xheader1");
|
||||
assertValues(response, headerName, value1, value2);
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -181,6 +195,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = preflightRequest(config, "http://localhost:8888", "content-type, xheader1");
|
||||
assertValues(response, headerName, value1, value2);
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -190,6 +205,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = preflightRequest(config, "http://localhost:8888", "content-type, xheader1");
|
||||
assertThat(response.headers().get(of("GenHeader")), equalTo("generatedValue"));
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -202,6 +218,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = preflightRequest(config, origin, "content-type, xheader1");
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(equalTo("null")));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(equalTo("true")));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -210,6 +227,7 @@ public class CorsHandlerTest {
|
||||
final CorsConfig config = forOrigin(origin).allowCredentials().build();
|
||||
final HttpResponse response = preflightRequest(config, origin, "content-type, xheader1");
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(equalTo("true")));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -218,6 +236,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = preflightRequest(config, "http://localhost:8888", "");
|
||||
// the only valid value for Access-Control-Allow-Credentials is true.
|
||||
assertThat(response.headers().contains(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(false));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -227,6 +246,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), equalTo("*"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_EXPOSE_HEADERS), containsString("custom1"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_EXPOSE_HEADERS), containsString("custom2"));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -234,6 +254,7 @@ public class CorsHandlerTest {
|
||||
final CorsConfig config = forAnyOrigin().allowCredentials().build();
|
||||
final HttpResponse response = simpleRequest(config, "http://localhost:7777");
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), equalTo("true"));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -241,6 +262,7 @@ public class CorsHandlerTest {
|
||||
final CorsConfig config = forAnyOrigin().build();
|
||||
final HttpResponse response = simpleRequest(config, "http://localhost:7777");
|
||||
assertThat(response.headers().contains(ACCESS_CONTROL_ALLOW_CREDENTIALS), is(false));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -250,6 +272,7 @@ public class CorsHandlerTest {
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_CREDENTIALS), equalTo("true"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), equalTo("http://localhost:7777"));
|
||||
assertThat(response.headers().get(VARY), equalTo(ORIGIN.toString()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -258,6 +281,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = simpleRequest(config, "http://localhost:7777");
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_EXPOSE_HEADERS), containsString("one"));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_EXPOSE_HEADERS), containsString("two"));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -266,6 +290,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = simpleRequest(config, "http://localhost:7777");
|
||||
assertThat(response.status(), is(FORBIDDEN));
|
||||
assertThat(response.headers().get(CONTENT_LENGTH), is("0"));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -274,6 +299,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = simpleRequest(config, "http://localhost:7777");
|
||||
assertThat(response.status(), is(OK));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -282,6 +308,7 @@ public class CorsHandlerTest {
|
||||
final HttpResponse response = simpleRequest(config, null);
|
||||
assertThat(response.status(), is(OK));
|
||||
assertThat(response.headers().get(ACCESS_CONTROL_ALLOW_ORIGIN), is(nullValue()));
|
||||
assertThat(ReferenceCountUtil.release(response), is(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -473,7 +500,9 @@ public class CorsHandlerTest {
|
||||
httpRequest.headers().set(ACCESS_CONTROL_REQUEST_HEADERS, requestHeaders);
|
||||
}
|
||||
assertThat(channel.writeInbound(httpRequest), is(false));
|
||||
return (HttpResponse) channel.readOutbound();
|
||||
HttpResponse response = channel.readOutbound();
|
||||
assertThat(channel.finish(), is(false));
|
||||
return response;
|
||||
}
|
||||
|
||||
private static HttpResponse preflightRequest(final CorsConfig config,
|
||||
|
@ -76,6 +76,7 @@ public class WebSocket08EncoderDecoderTest {
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(expectedStatus.code(), response.statusCode());
|
||||
Assert.assertEquals(errorMessage, response.reasonText());
|
||||
response.release();
|
||||
|
||||
// Without auto-close
|
||||
config = WebSocketDecoderConfig.newBuilder()
|
||||
|
@ -259,7 +259,9 @@ public abstract class WebSocketClientHandshakerTest {
|
||||
// Create a EmbeddedChannel which we will use to encode a BinaryWebsocketFrame to bytes and so use these
|
||||
// to test the actual handshaker.
|
||||
WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory(url, null, false);
|
||||
WebSocketServerHandshaker socketServerHandshaker = factory.newHandshaker(shaker.newHandshakeRequest());
|
||||
FullHttpRequest request = shaker.newHandshakeRequest();
|
||||
WebSocketServerHandshaker socketServerHandshaker = factory.newHandshaker(request);
|
||||
request.release();
|
||||
EmbeddedChannel websocketChannel = new EmbeddedChannel(socketServerHandshaker.newWebSocketEncoder(),
|
||||
socketServerHandshaker.newWebsocketDecoder());
|
||||
assertTrue(websocketChannel.writeOutbound(new BinaryWebSocketFrame(Unpooled.wrappedBuffer(data))));
|
||||
|
@ -28,6 +28,7 @@ import io.netty.handler.codec.http.HttpMethod;
|
||||
import io.netty.handler.codec.http.HttpRequest;
|
||||
import io.netty.handler.codec.http.HttpRequestDecoder;
|
||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import io.netty.util.ReferenceCountUtil;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -58,6 +59,7 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
assertEquals(SWITCHING_PROTOCOLS, response.status());
|
||||
response.release();
|
||||
assertNotNull(WebSocketServerProtocolHandler.getHandshaker(handshakerCtx.channel()));
|
||||
assertFalse(ch.finish());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -74,6 +76,7 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
response = responses.remove();
|
||||
assertEquals(FORBIDDEN, response.status());
|
||||
response.release();
|
||||
assertFalse(ch.finish());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -93,6 +96,7 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
assertEquals(BAD_REQUEST, response.status());
|
||||
assertEquals("not a WebSocket handshake request: missing upgrade", getResponseMessage(response));
|
||||
response.release();
|
||||
assertFalse(ch.finish());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -113,6 +117,7 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
assertEquals(BAD_REQUEST, response.status());
|
||||
assertEquals("not a WebSocket request: missing key", getResponseMessage(response));
|
||||
response.release();
|
||||
assertFalse(ch.finish());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -121,6 +126,10 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
EmbeddedChannel ch = createChannel(customTextFrameHandler);
|
||||
writeUpgradeRequest(ch);
|
||||
|
||||
FullHttpResponse response = responses.remove();
|
||||
assertEquals(SWITCHING_PROTOCOLS, response.status());
|
||||
response.release();
|
||||
|
||||
if (ch.pipeline().context(HttpRequestDecoder.class) != null) {
|
||||
// Removing the HttpRequestDecoder because we are writing a TextWebSocketFrame and thus
|
||||
// decoding is not necessary.
|
||||
@ -130,6 +139,7 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
ch.writeInbound(new TextWebSocketFrame("payload"));
|
||||
|
||||
assertEquals("processed: payload", customTextFrameHandler.getContent());
|
||||
assertFalse(ch.finish());
|
||||
}
|
||||
|
||||
private EmbeddedChannel createChannel() {
|
||||
@ -150,7 +160,7 @@ public class WebSocketServerProtocolHandlerTest {
|
||||
}
|
||||
|
||||
private static String getResponseMessage(FullHttpResponse response) {
|
||||
return new String(response.content().array());
|
||||
return response.content().toString(CharsetUtil.UTF_8);
|
||||
}
|
||||
|
||||
private class MockOutboundHandler implements ChannelHandler {
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
package io.netty.example.http.cors;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
@ -30,7 +31,8 @@ import io.netty.handler.codec.http.HttpVersion;
|
||||
public class OkResponseHandler extends SimpleChannelInboundHandler<Object> {
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, Object msg) {
|
||||
final FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
|
||||
final FullHttpResponse response = new DefaultFullHttpResponse(
|
||||
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.EMPTY_BUFFER);
|
||||
response.headers().set("custom-response-header", "Some value");
|
||||
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||
}
|
||||
|
@ -272,9 +272,6 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
|
||||
private static final Pattern ALLOWED_FILE_NAME = Pattern.compile("[^-\\._]?[^<>&\\\"]*");
|
||||
|
||||
private void sendListing(ChannelHandlerContext ctx, File dir, String dirPath) {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
|
||||
|
||||
StringBuilder buf = new StringBuilder()
|
||||
.append("<!DOCTYPE html>\r\n")
|
||||
.append("<html><head><meta charset='utf-8' /><title>")
|
||||
@ -307,15 +304,18 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
|
||||
}
|
||||
|
||||
buf.append("</ul></body></html>\r\n");
|
||||
ByteBuf buffer = Unpooled.copiedBuffer(buf, CharsetUtil.UTF_8);
|
||||
response.content().writeBytes(buffer);
|
||||
buffer.release();
|
||||
|
||||
ByteBuf buffer = ctx.alloc().buffer(buf.length());
|
||||
buffer.writeCharSequence(buf.toString(), CharsetUtil.UTF_8);
|
||||
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, buffer);
|
||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html; charset=UTF-8");
|
||||
|
||||
this.sendAndCleanupConnection(ctx, response);
|
||||
}
|
||||
|
||||
private void sendRedirect(ChannelHandlerContext ctx, String newUri) {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, FOUND);
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, FOUND, Unpooled.EMPTY_BUFFER);
|
||||
response.headers().set(HttpHeaderNames.LOCATION, newUri);
|
||||
|
||||
this.sendAndCleanupConnection(ctx, response);
|
||||
@ -336,7 +336,7 @@ public class HttpStaticFileServerHandler extends SimpleChannelInboundHandler<Ful
|
||||
* Context
|
||||
*/
|
||||
private void sendNotModified(ChannelHandlerContext ctx) {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED);
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED, Unpooled.EMPTY_BUFFER);
|
||||
setDateHeader(response);
|
||||
|
||||
this.sendAndCleanupConnection(ctx, response);
|
||||
|
@ -16,6 +16,7 @@
|
||||
package io.netty.example.http.snoop;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.MultithreadEventLoopGroup;
|
||||
@ -84,7 +85,7 @@ public final class HttpSnoopClient {
|
||||
|
||||
// Prepare the HTTP request.
|
||||
HttpRequest request = new DefaultFullHttpRequest(
|
||||
HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath());
|
||||
HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath(), Unpooled.EMPTY_BUFFER);
|
||||
request.headers().set(HttpHeaderNames.HOST, host);
|
||||
request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
|
||||
request.headers().set(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
|
||||
|
@ -185,7 +185,7 @@ public class HttpSnoopServerHandler extends SimpleChannelInboundHandler<Object>
|
||||
}
|
||||
|
||||
private static void send100Continue(ChannelHandlerContext ctx) {
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, CONTINUE);
|
||||
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, CONTINUE, Unpooled.EMPTY_BUFFER);
|
||||
ctx.write(response);
|
||||
}
|
||||
|
||||
|
@ -72,13 +72,13 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
|
||||
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
|
||||
// Handle a bad request.
|
||||
if (!req.decoderResult().isSuccess()) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST, Unpooled.EMPTY_BUFFER));
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow only GET methods.
|
||||
if (!GET.equals(req.method())) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN, Unpooled.EMPTY_BUFFER));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ public class WebSocketServerHandler extends SimpleChannelInboundHandler<Object>
|
||||
return;
|
||||
}
|
||||
if ("/favicon.ico".equals(req.uri())) {
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND);
|
||||
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND, Unpooled.EMPTY_BUFFER);
|
||||
sendHttpResponse(ctx, req, res);
|
||||
return;
|
||||
}
|
||||
|
@ -57,13 +57,13 @@ public class WebSocketIndexPageHandler extends SimpleChannelInboundHandler<FullH
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
|
||||
// Handle a bad request.
|
||||
if (!req.decoderResult().isSuccess()) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST, Unpooled.EMPTY_BUFFER));
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow only GET methods.
|
||||
if (!GET.equals(req.method())) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN, Unpooled.EMPTY_BUFFER));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ public class WebSocketIndexPageHandler extends SimpleChannelInboundHandler<FullH
|
||||
|
||||
sendHttpResponse(ctx, req, res);
|
||||
} else {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND, Unpooled.EMPTY_BUFFER));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
package io.netty.example.http2.helloworld.client;
|
||||
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
@ -114,7 +115,7 @@ public final class Http2Client {
|
||||
System.err.println("Sending request(s)...");
|
||||
if (URL != null) {
|
||||
// Create a simple GET request.
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, URL);
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, URL, Unpooled.EMPTY_BUFFER);
|
||||
request.headers().add(HttpHeaderNames.HOST, hostName);
|
||||
request.headers().add(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), scheme.name());
|
||||
request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, HttpHeaderValues.GZIP);
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
package io.netty.example.http2.helloworld.client;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@ -137,7 +138,7 @@ public class Http2ClientInitializer extends ChannelInitializer<SocketChannel> {
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
DefaultFullHttpRequest upgradeRequest =
|
||||
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
|
||||
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/", Unpooled.EMPTY_BUFFER);
|
||||
|
||||
// Set HOST header as the remote peer may require it.
|
||||
InetSocketAddress remote = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
|
@ -28,6 +28,7 @@ import static java.util.Objects.requireNonNull;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
@ -49,7 +50,7 @@ public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<FullHttp
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
|
||||
if (HttpUtil.is100ContinueExpected(req)) {
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE, Unpooled.EMPTY_BUFFER));
|
||||
}
|
||||
boolean keepAlive = HttpUtil.isKeepAlive(req);
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package io.netty.example.http2.tiles;
|
||||
|
||||
import static io.netty.buffer.Unpooled.EMPTY_BUFFER;
|
||||
import static io.netty.buffer.Unpooled.copiedBuffer;
|
||||
import static io.netty.buffer.Unpooled.unreleasableBuffer;
|
||||
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
|
||||
@ -47,7 +48,7 @@ public final class FallbackRequestHandler extends SimpleChannelInboundHandler<Ht
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
|
||||
if (HttpUtil.is100ContinueExpected(req)) {
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE, EMPTY_BUFFER));
|
||||
}
|
||||
|
||||
ByteBuf content = ctx.alloc().buffer();
|
||||
|
@ -23,6 +23,8 @@ import static io.netty.handler.codec.http.HttpUtil.isKeepAlive;
|
||||
import static io.netty.handler.codec.http.HttpResponseStatus.CONTINUE;
|
||||
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_0;
|
||||
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.http.DefaultFullHttpResponse;
|
||||
@ -40,7 +42,7 @@ public final class Http1RequestHandler extends Http2RequestHandler {
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
|
||||
if (HttpUtil.is100ContinueExpected(request)) {
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE, Unpooled.EMPTY_BUFFER));
|
||||
}
|
||||
super.channelRead0(ctx, request);
|
||||
}
|
||||
|
@ -21,6 +21,7 @@ import java.math.BigInteger;
|
||||
import javax.net.ssl.SSLSession;
|
||||
import javax.security.cert.X509Certificate;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelInboundHandler;
|
||||
import io.netty.channel.MultithreadEventLoopGroup;
|
||||
import io.netty.channel.nio.NioHandler;
|
||||
@ -165,7 +166,8 @@ public class OcspClientExample {
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) throws Exception {
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
|
||||
FullHttpRequest request = new DefaultFullHttpRequest(
|
||||
HttpVersion.HTTP_1_1, HttpMethod.GET, "/", Unpooled.EMPTY_BUFFER);
|
||||
request.headers().set(HttpHeaderNames.HOST, host);
|
||||
request.headers().set(HttpHeaderNames.USER_AGENT, "netty-ocsp-example/1.0");
|
||||
|
||||
|
@ -73,13 +73,13 @@ public class AutobahnServerHandler implements ChannelInboundHandler {
|
||||
throws Exception {
|
||||
// Handle a bad request.
|
||||
if (!req.decoderResult().isSuccess()) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST, ctx.alloc().buffer(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow only GET methods.
|
||||
if (!GET.equals(req.method())) {
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN));
|
||||
sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN, ctx.alloc().buffer(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<FullHttp
|
||||
@Override
|
||||
public void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception {
|
||||
if (HttpUtil.is100ContinueExpected(req)) {
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
|
||||
ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE, ctx.alloc().buffer(0)));
|
||||
}
|
||||
boolean keepAlive = HttpUtil.isKeepAlive(req);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user