|
|
@@ -20,7 +20,11 @@
|
|
|
package org.elasticsearch.http.netty4;
|
|
|
|
|
|
import io.netty.bootstrap.Bootstrap;
|
|
|
+import io.netty.buffer.ByteBufAllocator;
|
|
|
import io.netty.buffer.ByteBufUtil;
|
|
|
+import io.netty.buffer.PoolArenaMetric;
|
|
|
+import io.netty.buffer.PooledByteBufAllocator;
|
|
|
+import io.netty.buffer.PooledByteBufAllocatorMetric;
|
|
|
import io.netty.buffer.Unpooled;
|
|
|
import io.netty.channel.ChannelFuture;
|
|
|
import io.netty.channel.ChannelHandlerAdapter;
|
|
|
@@ -178,13 +182,13 @@ public class Netty4HttpServerTransportTests extends ESTestCase {
|
|
|
request.headers().set(HttpHeaderNames.EXPECT, expectation);
|
|
|
HttpUtil.setContentLength(request, contentLength);
|
|
|
|
|
|
- final FullHttpResponse response = client.post(remoteAddress.address(), request);
|
|
|
+ final FullHttpResponse response = client.send(remoteAddress.address(), request);
|
|
|
try {
|
|
|
assertThat(response.status(), equalTo(expectedStatus));
|
|
|
if (expectedStatus.equals(HttpResponseStatus.CONTINUE)) {
|
|
|
final FullHttpRequest continuationRequest =
|
|
|
new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/", Unpooled.EMPTY_BUFFER);
|
|
|
- final FullHttpResponse continuationResponse = client.post(remoteAddress.address(), continuationRequest);
|
|
|
+ final FullHttpResponse continuationResponse = client.send(remoteAddress.address(), continuationRequest);
|
|
|
try {
|
|
|
assertThat(continuationResponse.status(), is(HttpResponseStatus.OK));
|
|
|
assertThat(
|
|
|
@@ -266,7 +270,7 @@ public class Netty4HttpServerTransportTests extends ESTestCase {
|
|
|
final String url = "/" + new String(new byte[maxInitialLineLength], Charset.forName("UTF-8"));
|
|
|
final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url);
|
|
|
|
|
|
- final FullHttpResponse response = client.post(remoteAddress.address(), request);
|
|
|
+ final FullHttpResponse response = client.send(remoteAddress.address(), request);
|
|
|
try {
|
|
|
assertThat(response.status(), equalTo(HttpResponseStatus.BAD_REQUEST));
|
|
|
assertThat(
|
|
|
@@ -282,6 +286,66 @@ public class Netty4HttpServerTransportTests extends ESTestCase {
|
|
|
assertThat(causeReference.get(), instanceOf(TooLongFrameException.class));
|
|
|
}
|
|
|
|
|
|
+ public void testLargeCompressedResponse() throws InterruptedException {
|
|
|
+ final String responseString = randomAlphaOfLength(4 * 1024 * 1024);
|
|
|
+ final String url = "/thing";
|
|
|
+ final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void dispatchRequest(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) {
|
|
|
+ if (url.equals(request.uri())) {
|
|
|
+ channel.sendResponse(new BytesRestResponse(OK, responseString));
|
|
|
+ } else {
|
|
|
+ logger.error("--> Unexpected successful uri [{}]", request.uri());
|
|
|
+ throw new AssertionError();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void dispatchBadRequest(final RestChannel channel, final ThreadContext threadContext, final Throwable cause) {
|
|
|
+ logger.error(new ParameterizedMessage("--> Unexpected bad request [{}]",
|
|
|
+ FakeRestRequest.requestToString(channel.request())), cause);
|
|
|
+ throw new AssertionError();
|
|
|
+ }
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ try (Netty4HttpServerTransport transport = new Netty4HttpServerTransport(
|
|
|
+ Settings.EMPTY, networkService, bigArrays, threadPool, xContentRegistry(), dispatcher, clusterSettings,
|
|
|
+ new SharedGroupFactory(Settings.EMPTY))) {
|
|
|
+ transport.start();
|
|
|
+ final TransportAddress remoteAddress = randomFrom(transport.boundAddress().boundAddresses());
|
|
|
+
|
|
|
+ try (Netty4HttpClient client = new Netty4HttpClient()) {
|
|
|
+ DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url);
|
|
|
+ request.headers().add(HttpHeaderNames.ACCEPT_ENCODING, randomFrom("deflate", "gzip"));
|
|
|
+ long numOfHugeAllocations = getHugeAllocationCount();
|
|
|
+ final FullHttpResponse response = client.send(remoteAddress.address(), request);
|
|
|
+ try {
|
|
|
+ assertThat(getHugeAllocationCount(), equalTo(numOfHugeAllocations));
|
|
|
+ assertThat(response.status(), equalTo(HttpResponseStatus.OK));
|
|
|
+ byte[] bytes = new byte[response.content().readableBytes()];
|
|
|
+ response.content().readBytes(bytes);
|
|
|
+ assertThat(new String(bytes, StandardCharsets.UTF_8), equalTo(responseString));
|
|
|
+ } finally {
|
|
|
+ response.release();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private long getHugeAllocationCount() {
|
|
|
+ long numOfHugAllocations = 0;
|
|
|
+ ByteBufAllocator allocator = NettyAllocator.getAllocator();
|
|
|
+ assert allocator instanceof NettyAllocator.NoDirectBuffers;
|
|
|
+ ByteBufAllocator delegate = ((NettyAllocator.NoDirectBuffers) allocator).getDelegate();
|
|
|
+ if (delegate instanceof PooledByteBufAllocator) {
|
|
|
+ PooledByteBufAllocatorMetric metric = ((PooledByteBufAllocator) delegate).metric();
|
|
|
+ numOfHugAllocations = metric.heapArenas().stream().mapToLong(PoolArenaMetric::numHugeAllocations).sum();
|
|
|
+ }
|
|
|
+ return numOfHugAllocations;
|
|
|
+ }
|
|
|
+
|
|
|
public void testCorsRequest() throws InterruptedException {
|
|
|
final HttpServerTransport.Dispatcher dispatcher = new HttpServerTransport.Dispatcher() {
|
|
|
|
|
|
@@ -318,7 +382,7 @@ public class Netty4HttpServerTransportTests extends ESTestCase {
|
|
|
request.headers().add(CorsHandler.ORIGIN, "elastic.co");
|
|
|
request.headers().add(CorsHandler.ACCESS_CONTROL_REQUEST_METHOD, "POST");
|
|
|
|
|
|
- final FullHttpResponse response = client.post(remoteAddress.address(), request);
|
|
|
+ final FullHttpResponse response = client.send(remoteAddress.address(), request);
|
|
|
try {
|
|
|
assertThat(response.status(), equalTo(HttpResponseStatus.OK));
|
|
|
assertThat(response.headers().get(CorsHandler.ACCESS_CONTROL_ALLOW_ORIGIN), equalTo("elastic.co"));
|
|
|
@@ -334,7 +398,7 @@ public class Netty4HttpServerTransportTests extends ESTestCase {
|
|
|
final FullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
|
|
|
request.headers().add(CorsHandler.ORIGIN, "elastic2.co");
|
|
|
|
|
|
- final FullHttpResponse response = client.post(remoteAddress.address(), request);
|
|
|
+ final FullHttpResponse response = client.send(remoteAddress.address(), request);
|
|
|
try {
|
|
|
assertThat(response.status(), equalTo(HttpResponseStatus.FORBIDDEN));
|
|
|
} finally {
|