use of io.netty.handler.codec.http.DefaultLastHttpContent in project ambry by linkedin.
the class CopyForcingByteBuf method zeroSizeContentTest.
/**
* Tests for POST request that has no content.
* @throws Exception
*/
@Test
public void zeroSizeContentTest() throws Exception {
Channel channel = new MockChannel();
NettyRequest nettyRequest = createNettyRequest(HttpMethod.POST, "/", null, channel);
HttpContent httpContent = new DefaultLastHttpContent();
nettyRequest.addContent(httpContent);
assertEquals("Reference count is not as expected", 2, httpContent.refCnt());
ByteBufferAsyncWritableChannel writeChannel = new ByteBufferAsyncWritableChannel();
ReadIntoCallback callback = new ReadIntoCallback();
Future<Long> future = nettyRequest.readInto(writeChannel, callback);
assertEquals("There should be no content", 0, writeChannel.getNextChunk().remaining());
writeChannel.resolveOldestChunk(null);
closeRequestAndValidate(nettyRequest, channel);
writeChannel.close();
assertEquals("Reference count of http content has changed", 1, httpContent.refCnt());
callback.awaitCallback();
if (callback.exception != null) {
throw callback.exception;
}
long futureBytesRead = future.get();
assertEquals("Total bytes read does not match (callback)", 0, callback.bytesRead);
assertEquals("Total bytes read does not match (future)", 0, futureBytesRead);
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project ambry by linkedin.
the class CopyForcingByteBuf method generateCompositeContent.
/**
* Generates random content and fills it up in {@code httpContents} with a backing {@link CompositeByteBuf}.
* @param httpContents the {@link List<HttpContent>} that will contain all the content.
* @return the whole content as a {@link ByteBuffer} - serves as a source of truth.
*/
private ByteBuffer generateCompositeContent(List<HttpContent> httpContents) {
int individualPartSize = GENERATED_CONTENT_SIZE / GENERATED_CONTENT_PART_COUNT;
byte[] contentBytes = TestUtils.getRandomBytes(GENERATED_CONTENT_SIZE);
ArrayList<ByteBuf> byteBufs = new ArrayList<>(GENERATED_CONTENT_PART_COUNT);
for (int addedContentCount = 0; addedContentCount < GENERATED_CONTENT_PART_COUNT; addedContentCount++) {
byteBufs.add(Unpooled.wrappedBuffer(contentBytes, addedContentCount * individualPartSize, individualPartSize));
}
httpContents.add(new DefaultLastHttpContent(new CompositeByteBuf(ByteBufAllocator.DEFAULT, false, 20, byteBufs)));
return ByteBuffer.wrap(contentBytes);
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project ambry by linkedin.
the class PublicAccessLogHandlerTest method sendRequestCheckResponse.
/**
* Sends the provided {@code httpRequest} and verifies that the response is as expected.
* @param channel the {@link EmbeddedChannel} to send the request over.
* @param httpRequest the {@link HttpRequest} that has to be sent
* @param uri, Uri to be used for the request
* @param headers {@link HttpHeaders} that is set in the request to be used for verification purposes
* @param testErrorCase true if error case has to be tested, false otherwise
* @param sslUsed true if SSL was used for this request.
*/
private void sendRequestCheckResponse(EmbeddedChannel channel, HttpRequest httpRequest, String uri, HttpHeaders headers, boolean testErrorCase, boolean chunkedResponse, boolean sslUsed) throws Exception {
channel.writeInbound(httpRequest);
if (uri.equals(EchoMethodHandler.DISCONNECT_URI)) {
channel.disconnect();
} else {
channel.writeInbound(new DefaultLastHttpContent());
}
String lastLogEntry = publicAccessLogger.getLastPublicAccessLogEntry();
// verify remote host, http method and uri
String subString = testErrorCase ? "Error" : "Info" + ":embedded" + " " + httpRequest.method() + " " + uri;
Assert.assertTrue("Public Access log entry doesn't have expected remote host/method/uri ", lastLogEntry.startsWith(subString));
// verify SSL-related info
subString = "SSL ([used=" + sslUsed + "]";
if (sslUsed) {
subString += ", [principal=" + PEER_CERT.getSubjectX500Principal() + "]";
subString += ", [san=" + PEER_CERT.getSubjectAlternativeNames() + "]";
}
subString += ")";
Assert.assertTrue("Public Access log entry doesn't have SSL info set correctly", lastLogEntry.contains(subString));
// verify request headers
verifyPublicAccessLogEntryForRequestHeaders(lastLogEntry, headers, httpRequest.method(), true);
// verify response
subString = "Response (";
for (String responseHeader : RESPONSE_HEADERS.split(",")) {
if (headers.contains(responseHeader)) {
subString += "[" + responseHeader + "=" + headers.get(responseHeader) + "] ";
}
}
subString += "[isChunked=" + chunkedResponse + "]), status=" + HttpResponseStatus.OK.code();
if (!testErrorCase) {
Assert.assertTrue("Public Access log entry doesn't have response set correctly", lastLogEntry.contains(subString));
} else {
Assert.assertTrue("Public Access log entry doesn't have error set correctly ", lastLogEntry.contains(": Channel closed while request in progress."));
}
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project proxyee-down by monkeyWie.
the class HttpDownUtil method getResponse.
/**
* 取请求响应
*/
public static HttpResponse getResponse(HttpRequest httpRequest, ProxyConfig proxyConfig, SslContext clientSslCtx, NioEventLoopGroup loopGroup) throws Exception {
final HttpResponse[] httpResponses = new HttpResponse[1];
CountDownLatch cdl = new CountDownLatch(1);
HttpRequestInfo requestInfo = (HttpRequestInfo) httpRequest;
RequestProto requestProto = requestInfo.requestProto();
Bootstrap bootstrap = new Bootstrap();
// 注册线程池
bootstrap.group(loopGroup).channel(// 使用NioSocketChannel来作为连接用的channel类
NioSocketChannel.class).handler(new ChannelInitializer() {
@Override
protected void initChannel(Channel ch) throws Exception {
if (proxyConfig != null) {
ch.pipeline().addLast(ProxyHandleFactory.build(proxyConfig));
}
if (requestProto.getSsl()) {
ch.pipeline().addLast(clientSslCtx.newHandler(ch.alloc()));
}
ch.pipeline().addLast("httpCodec", new HttpClientCodec());
ch.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void channelRead(ChannelHandlerContext ctx0, Object msg0) throws Exception {
if (msg0 instanceof HttpResponse) {
HttpResponse httpResponse = (HttpResponse) msg0;
httpResponses[0] = httpResponse;
ctx0.channel().close();
cdl.countDown();
}
}
});
}
});
if (proxyConfig != null) {
// 代理服务器解析DNS和连接
bootstrap.resolver(NoopAddressResolverGroup.INSTANCE);
}
ChannelFuture cf = bootstrap.connect(requestProto.getHost(), requestProto.getPort());
cf.addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
httpRequest.headers().set(HttpHeaderNames.RANGE, "bytes=0-0");
cf.channel().writeAndFlush(httpRequest);
if (requestInfo.content() != null) {
HttpContent content = new DefaultLastHttpContent();
content.content().writeBytes(requestInfo.content());
cf.channel().writeAndFlush(content);
}
} else {
cdl.countDown();
}
});
cdl.await(30, TimeUnit.SECONDS);
if (httpResponses[0] == null) {
throw new TimeoutException("getResponse timeout");
}
return httpResponses[0];
}
use of io.netty.handler.codec.http.DefaultLastHttpContent in project proxyee-down by monkeyWie.
the class ResponseTextIntercept method afterResponse.
@Override
public void afterResponse(Channel clientChannel, Channel proxyChannel, HttpContent httpContent, HttpProxyInterceptPipeline pipeline) throws Exception {
if (isMatch) {
try {
contentBuf.writeBytes(httpContent.content());
if (httpContent instanceof LastHttpContent) {
ByteUtil.insertText(contentBuf, ByteUtil.findText(contentBuf, "<head>"), hookResponse(), Charset.forName("UTF-8"));
HttpContent hookHttpContent = new DefaultLastHttpContent();
if (isGzip) {
// 转化成gzip编码
byte[] temp = new byte[contentBuf.readableBytes()];
contentBuf.readBytes(temp);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream outputStream = new GZIPOutputStream(baos);
outputStream.write(temp);
outputStream.finish();
hookHttpContent.content().writeBytes(baos.toByteArray());
} else {
hookHttpContent.content().writeBytes(contentBuf);
}
ReferenceCountUtil.release(contentBuf);
pipeline.getDefault().afterResponse(clientChannel, proxyChannel, hookHttpContent, pipeline);
}
} finally {
ReferenceCountUtil.release(httpContent);
}
} else {
pipeline.afterResponse(clientChannel, proxyChannel, httpContent);
}
}
Aggregations