use of io.netty.handler.codec.http.DefaultLastHttpContent in project netty by netty.
the class Http2StreamFrameToHttpObjectCodecTest method testEncodeDataEndWithTrailersAsClient.
@Test
public void testEncodeDataEndWithTrailersAsClient() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(false));
ByteBuf hello = Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8);
LastHttpContent trailers = new DefaultLastHttpContent(hello, true);
HttpHeaders headers = trailers.trailingHeaders();
headers.set("key", "value");
assertTrue(ch.writeOutbound(trailers));
Http2DataFrame dataFrame = ch.readOutbound();
try {
assertThat(dataFrame.content().toString(CharsetUtil.UTF_8), is("hello world"));
assertFalse(dataFrame.isEndStream());
} finally {
dataFrame.release();
}
Http2HeadersFrame headerFrame = ch.readOutbound();
assertThat(headerFrame.headers().get("key").toString(), is("value"));
assertTrue(headerFrame.isEndStream());
assertThat(ch.readOutbound(), is(nullValue()));
assertFalse(ch.finish());
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project netty by netty.
the class HttpPostMultiPartRequestDecoderTest method commonNotBadReleaseBuffersDuringDecoding.
private static void commonNotBadReleaseBuffersDuringDecoding(HttpDataFactory factory, boolean inMemory) throws IOException {
int nbItems = 20;
int bytesPerItem = 1000;
int maxMemory = 500;
String prefix1 = "\n--861fbeab-cd20-470c-9609-d40a0f704466\n" + "Content-Disposition: form-data; name=\"image";
String prefix2 = "\"; filename=\"guangzhou.jpeg\"\n" + "Content-Type: image/jpeg\n" + "Content-Length: " + bytesPerItem + "\n" + "\n";
String suffix = "\n--861fbeab-cd20-470c-9609-d40a0f704466--\n";
HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/upload");
request.headers().set("content-type", "multipart/form-data; boundary=861fbeab-cd20-470c-9609-d40a0f704466");
request.headers().set("content-length", nbItems * (prefix1.length() + prefix2.length() + 2 + bytesPerItem) + suffix.length());
HttpPostMultipartRequestDecoder decoder = new HttpPostMultipartRequestDecoder(factory, request);
decoder.setDiscardThreshold(maxMemory);
for (int rank = 0; rank < nbItems; rank++) {
byte[] bp1 = prefix1.getBytes(CharsetUtil.UTF_8);
byte[] bp2 = prefix2.getBytes(CharsetUtil.UTF_8);
byte[] prefix = new byte[bp1.length + 2 + bp2.length];
for (int i = 0; i < bp1.length; i++) {
prefix[i] = bp1[i];
}
byte[] brank = Integer.toString(10 + rank).getBytes(CharsetUtil.UTF_8);
prefix[bp1.length] = brank[0];
prefix[bp1.length + 1] = brank[1];
for (int i = 0; i < bp2.length; i++) {
prefix[bp1.length + 2 + i] = bp2[i];
}
ByteBuf buf = Unpooled.wrappedBuffer(prefix);
DefaultHttpContent httpContent = new DefaultHttpContent(buf);
decoder.offer(httpContent);
httpContent.release();
byte[] body = new byte[bytesPerItem];
Arrays.fill(body, (byte) rank);
ByteBuf content = Unpooled.wrappedBuffer(body, 0, bytesPerItem);
httpContent = new DefaultHttpContent(content);
decoder.offer(httpContent);
httpContent.release();
}
byte[] lastbody = suffix.getBytes(CharsetUtil.UTF_8);
ByteBuf content2 = Unpooled.wrappedBuffer(lastbody, 0, lastbody.length);
DefaultHttpContent httpContent = new DefaultHttpContent(content2);
decoder.offer(httpContent);
httpContent.release();
decoder.offer(new DefaultLastHttpContent());
for (int rank = 0; rank < nbItems; rank++) {
FileUpload data = (FileUpload) decoder.getBodyHttpData("image" + (10 + rank));
assertEquals(bytesPerItem, data.length());
assertEquals(inMemory, data.isInMemory());
byte[] body = new byte[bytesPerItem];
Arrays.fill(body, (byte) rank);
assertTrue(Arrays.equals(body, data.get()));
}
// Not mandatory since implicitely called during destroy of decoder
for (InterfaceHttpData httpData : decoder.getBodyHttpDatas()) {
httpData.release();
factory.removeHttpDataFromClean(request, httpData);
}
factory.cleanAllHttpData();
decoder.destroy();
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project netty by netty.
the class HttpToHttp2ConnectionHandlerTest method testChunkedRequestWithBodyAndTrailingHeaders.
@Test
public void testChunkedRequestWithBodyAndTrailingHeaders() throws Exception {
final String text = "foooooo";
final String text2 = "goooo";
final List<String> receivedBuffers = Collections.synchronizedList(new ArrayList<String>());
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock in) throws Throwable {
receivedBuffers.add(((ByteBuf) in.getArguments()[2]).toString(UTF_8));
return null;
}
}).when(serverListener).onDataRead(any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), eq(false));
bootstrapEnv(4, 1, 1);
final HttpRequest request = new DefaultHttpRequest(HTTP_1_1, POST, "http://your_user-name123@www.example.org:5555/example");
final HttpHeaders httpHeaders = request.headers();
httpHeaders.set(HttpHeaderNames.HOST, "www.example.org:5555");
httpHeaders.add(HttpHeaderNames.TRANSFER_ENCODING, "chunked");
httpHeaders.add(of("foo"), of("goo"));
httpHeaders.add(of("foo"), of("goo2"));
httpHeaders.add(of("foo2"), of("goo2"));
final Http2Headers http2Headers = new DefaultHttp2Headers().method(new AsciiString("POST")).path(new AsciiString("/example")).authority(new AsciiString("www.example.org:5555")).scheme(new AsciiString("http")).add(new AsciiString("foo"), new AsciiString("goo")).add(new AsciiString("foo"), new AsciiString("goo2")).add(new AsciiString("foo2"), new AsciiString("goo2"));
final DefaultHttpContent httpContent = new DefaultHttpContent(Unpooled.copiedBuffer(text, UTF_8));
final LastHttpContent lastHttpContent = new DefaultLastHttpContent(Unpooled.copiedBuffer(text2, UTF_8));
lastHttpContent.trailingHeaders().add(of("trailing"), of("bar"));
final Http2Headers http2TrailingHeaders = new DefaultHttp2Headers().add(new AsciiString("trailing"), new AsciiString("bar"));
ChannelPromise writePromise = newPromise();
ChannelFuture writeFuture = clientChannel.write(request, writePromise);
ChannelPromise contentPromise = newPromise();
ChannelFuture contentFuture = clientChannel.write(httpContent, contentPromise);
ChannelPromise lastContentPromise = newPromise();
ChannelFuture lastContentFuture = clientChannel.write(lastHttpContent, lastContentPromise);
clientChannel.flush();
assertTrue(writePromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS));
assertTrue(writePromise.isSuccess());
assertTrue(writeFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS));
assertTrue(writeFuture.isSuccess());
assertTrue(contentPromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS));
assertTrue(contentPromise.isSuccess());
assertTrue(contentFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS));
assertTrue(contentFuture.isSuccess());
assertTrue(lastContentPromise.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS));
assertTrue(lastContentPromise.isSuccess());
assertTrue(lastContentFuture.awaitUninterruptibly(WAIT_TIME_SECONDS, SECONDS));
assertTrue(lastContentFuture.isSuccess());
awaitRequests();
verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(3), eq(http2Headers), eq(0), anyShort(), anyBoolean(), eq(0), eq(false));
verify(serverListener).onDataRead(any(ChannelHandlerContext.class), eq(3), any(ByteBuf.class), eq(0), eq(false));
verify(serverListener).onHeadersRead(any(ChannelHandlerContext.class), eq(3), eq(http2TrailingHeaders), eq(0), anyShort(), anyBoolean(), eq(0), eq(true));
assertEquals(1, receivedBuffers.size());
assertEquals(text + text2, receivedBuffers.get(0));
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project zuul by Netflix.
the class ClientRequestReceiver method buildZuulHttpRequest.
// Build a ZuulMessage from the netty request.
private HttpRequestMessage buildZuulHttpRequest(final HttpRequest nativeRequest, final ChannelHandlerContext clientCtx) {
PerfMark.attachTag("path", nativeRequest, HttpRequest::uri);
// Setup the context for this request.
final SessionContext context;
if (decorator != null) {
// Optionally decorate the context.
SessionContext tempContext = new SessionContext();
// Store the netty channel in SessionContext.
tempContext.set(CommonContextKeys.NETTY_SERVER_CHANNEL_HANDLER_CONTEXT, clientCtx);
context = decorator.decorate(tempContext);
// We expect the UUID is present after decoration
PerfMark.attachTag("uuid", context, SessionContext::getUUID);
} else {
context = new SessionContext();
}
// Get the client IP (ignore XFF headers at this point, as that can be app specific).
final Channel channel = clientCtx.channel();
final String clientIp = channel.attr(SourceAddressChannelHandler.ATTR_SOURCE_ADDRESS).get();
// This is the only way I found to get the port of the request with netty...
final int port = channel.attr(SourceAddressChannelHandler.ATTR_SERVER_LOCAL_PORT).get();
final String serverName = channel.attr(SourceAddressChannelHandler.ATTR_SERVER_LOCAL_ADDRESS).get();
final SocketAddress clientDestinationAddress = channel.attr(SourceAddressChannelHandler.ATTR_LOCAL_ADDR).get();
final InetSocketAddress proxyProtocolDestinationAddress = channel.attr(SourceAddressChannelHandler.ATTR_PROXY_PROTOCOL_DESTINATION_ADDRESS).get();
if (proxyProtocolDestinationAddress != null) {
context.set(CommonContextKeys.PROXY_PROTOCOL_DESTINATION_ADDRESS, proxyProtocolDestinationAddress);
}
// Store info about the SSL handshake if applicable, and choose the http scheme.
String scheme = SCHEME_HTTP;
final SslHandshakeInfo sslHandshakeInfo = channel.attr(SslHandshakeInfoHandler.ATTR_SSL_INFO).get();
if (sslHandshakeInfo != null) {
context.set(CommonContextKeys.SSL_HANDSHAKE_INFO, sslHandshakeInfo);
scheme = SCHEME_HTTPS;
}
// Decide if this is HTTP/1 or HTTP/2.
String protocol = channel.attr(PROTOCOL_NAME).get();
if (protocol == null) {
protocol = nativeRequest.protocolVersion().text();
}
// Strip off the query from the path.
String path = parsePath(nativeRequest.uri());
// Setup the req/resp message objects.
final HttpRequestMessage request = new HttpRequestMessageImpl(context, protocol, nativeRequest.method().asciiName().toString().toLowerCase(), path, copyQueryParams(nativeRequest), copyHeaders(nativeRequest), clientIp, scheme, port, serverName, clientDestinationAddress, false);
// a LastHttpContent without any prior HttpContent's.
if (HttpUtils.hasChunkedTransferEncodingHeader(request) || HttpUtils.hasNonZeroContentLengthHeader(request)) {
request.setHasBody(true);
}
// Store this original request info for future reference (ie. for metrics and access logging purposes).
request.storeInboundRequest();
// Store the netty request for use later.
context.set(CommonContextKeys.NETTY_HTTP_REQUEST, nativeRequest);
// Store zuul request on netty channel for later use.
channel.attr(ATTR_ZUUL_REQ).set(request);
if (nativeRequest instanceof DefaultFullHttpRequest) {
final ByteBuf chunk = ((DefaultFullHttpRequest) nativeRequest).content();
request.bufferBodyContents(new DefaultLastHttpContent(chunk));
}
return request;
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project zuul by Netflix.
the class GZipResponseFilterTest method prepareResponseBody_NeedsGZipping_gzipDeflate.
@Test
public void prepareResponseBody_NeedsGZipping_gzipDeflate() throws Exception {
originalRequestHeaders.set("Accept-Encoding", "gzip,deflate");
byte[] originBody = "blah".getBytes();
response.getHeaders().set("Content-Length", Integer.toString(originBody.length));
// Force GZip for small response
Mockito.when(filter.isRightSizeForGzip(response)).thenReturn(true);
response.setHasBody(true);
assertTrue(filter.shouldFilter(response));
final HttpResponseMessage result = filter.apply(response);
final HttpContent hc1 = filter.processContentChunk(response, new DefaultHttpContent(Unpooled.wrappedBuffer(originBody)).retain());
final HttpContent hc2 = filter.processContentChunk(response, new DefaultLastHttpContent());
final byte[] body = new byte[hc1.content().readableBytes() + hc2.content().readableBytes()];
final int hc1Len = hc1.content().readableBytes();
final int hc2Len = hc2.content().readableBytes();
hc1.content().readBytes(body, 0, hc1Len);
hc2.content().readBytes(body, hc1Len, hc2Len);
String bodyStr;
// Check body is a gzipped version of the origin body.
try (ByteArrayInputStream bais = new ByteArrayInputStream(body);
GZIPInputStream gzis = new GZIPInputStream(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
int b;
while ((b = gzis.read()) != -1) {
baos.write(b);
}
bodyStr = baos.toString("UTF-8");
}
assertEquals("blah", bodyStr);
assertEquals("gzip", result.getHeaders().getFirst("Content-Encoding"));
// Check Content-Length header has been removed
assertEquals(0, result.getHeaders().getAll("Content-Length").size());
}
Aggregations