下面列出了怎么用 io.netty.handler.codec.http.DefaultLastHttpContent 的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testFormEncodeIncorrect() throws Exception {
LastHttpContent content = new DefaultLastHttpContent(
Unpooled.copiedBuffer("project=netty&&project=netty", CharsetUtil.US_ASCII));
DefaultHttpRequest req = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/");
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(req);
try {
decoder.offer(content);
fail();
} catch (HttpPostRequestDecoder.ErrorDataDecoderException e) {
assertTrue(e.getCause() instanceof IllegalArgumentException);
} finally {
decoder.destroy();
content.release();
}
}
@Test
public void testUpgradeDataEnd() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
ByteBuf hello = Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8);
LastHttpContent end = new DefaultLastHttpContent(hello, true);
assertTrue(ch.writeOutbound(end));
Http2DataFrame dataFrame = ch.readOutbound();
try {
assertThat(dataFrame.content().toString(CharsetUtil.UTF_8), is("hello world"));
assertTrue(dataFrame.isEndStream());
} finally {
dataFrame.release();
}
assertThat(ch.readOutbound(), is(nullValue()));
assertFalse(ch.finish());
}
@Test
public void testUpgradeDataEndWithTrailers() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
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());
}
@Test
public void testEncodeDataEndAsClient() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(false));
ByteBuf hello = Unpooled.copiedBuffer("hello world", CharsetUtil.UTF_8);
LastHttpContent end = new DefaultLastHttpContent(hello, true);
assertTrue(ch.writeOutbound(end));
Http2DataFrame dataFrame = ch.readOutbound();
try {
assertThat(dataFrame.content().toString(CharsetUtil.UTF_8), is("hello world"));
assertTrue(dataFrame.isEndStream());
} finally {
dataFrame.release();
}
assertThat(ch.readOutbound(), is(nullValue()));
assertFalse(ch.finish());
}
@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());
}
@Override
public void beforeRequest(Channel clientChannel, HttpRequest httpRequest, HttpProxyInterceptPipeline pipeline) throws Exception {
String acceptValue = httpRequest.headers().get(HttpHeaderNames.ACCEPT);
if (acceptValue != null && acceptValue.contains("application/x-sniff-cookie")) {
HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, new DefaultHttpHeaders());
httpResponse.headers().set(HttpHeaderNames.CONTENT_LENGTH, 0);
//https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
AsciiString customHeadKey = AsciiString.cached("X-Sniff-Cookie");
String cookie = pipeline.getHttpRequest().headers().get(HttpHeaderNames.COOKIE);
httpResponse.headers().set(customHeadKey, cookie == null ? "" : cookie);
httpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS, customHeadKey);
String origin = httpRequest.headers().get(HttpHeaderNames.ORIGIN);
if (StringUtil.isNullOrEmpty(origin)) {
String referer = httpRequest.headers().get(HttpHeaderNames.REFERER);
URL url = new URL(referer);
origin = url.getHost();
}
httpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, origin);
httpResponse.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_CREDENTIALS, true);
clientChannel.writeAndFlush(httpResponse);
clientChannel.writeAndFlush(new DefaultLastHttpContent());
clientChannel.close();
} else {
super.beforeRequest(clientChannel, httpRequest, pipeline);
}
}
@Test
public void addContentChunk_adds_last_chunk_trailing_headers() {
// given
RequestInfoImpl<?> requestInfo = RequestInfoImpl.dummyInstanceForUnknownRequests();
requestInfo.isCompleteRequestWithAllChunks = false;
LastHttpContent lastChunk = new DefaultLastHttpContent(Unpooled.copiedBuffer(UUID.randomUUID().toString(), CharsetUtil.UTF_8));
String headerKey = UUID.randomUUID().toString();
List<String> headerVal = Arrays.asList(UUID.randomUUID().toString(), UUID.randomUUID().toString());
lastChunk.trailingHeaders().add(headerKey, headerVal);
// when
requestInfo.addContentChunk(lastChunk);
// then
assertThat(requestInfo.trailingHeaders.names().size(), is(1));
assertThat(requestInfo.trailingHeaders.getAll(headerKey), is(headerVal));
}
@Test
public void addContentChunk_adds_chunk_content_length_to_rawContentLengthInBytes() throws IOException {
// given
RequestInfoImpl<?> requestInfo = RequestInfoImpl.dummyInstanceForUnknownRequests();
requestInfo.isCompleteRequestWithAllChunks = false;
String chunk1String = UUID.randomUUID().toString();
String lastChunkString = UUID.randomUUID().toString();
byte[] chunk1Bytes = chunk1String.getBytes();
byte[] lastChunkBytes = lastChunkString.getBytes();
HttpContent chunk1 = new DefaultHttpContent(Unpooled.copiedBuffer(chunk1Bytes));
HttpContent lastChunk = new DefaultLastHttpContent(Unpooled.copiedBuffer(lastChunkBytes));
// when
requestInfo.addContentChunk(chunk1);
requestInfo.addContentChunk(lastChunk);
// then
assertThat(requestInfo.contentChunks.size(), is(2));
assertThat(requestInfo.isCompleteRequestWithAllChunks(), is(true));
assertThat(requestInfo.getRawContentLengthInBytes(), is(chunk1Bytes.length + lastChunkBytes.length));
}
@Test
public void addDecoderReplaysLastHttp() {
ByteBuf buf = Unpooled.copiedBuffer("{\"foo\":1}", CharsetUtil.UTF_8);
EmbeddedChannel channel = new EmbeddedChannel();
new HttpClientOperations(() -> channel, ConnectionObserver.emptyListener(),
ClientCookieEncoder.STRICT, ClientCookieDecoder.STRICT)
.addHandler(new JsonObjectDecoder());
channel.writeInbound(new DefaultLastHttpContent(buf));
MatcherAssert.assertThat(channel.pipeline().names().iterator().next(), is("JsonObjectDecoder$extractor"));
Object content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(ByteBuf.class));
((ByteBuf) content).release();
content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(LastHttpContent.class));
((LastHttpContent) content).release();
MatcherAssert.assertThat(channel.readInbound(), nullValue());
}
@Test
public void addNamedDecoderReplaysLastHttp() {
ByteBuf buf = Unpooled.copiedBuffer("{\"foo\":1}", CharsetUtil.UTF_8);
EmbeddedChannel channel = new EmbeddedChannel();
new HttpClientOperations(() -> channel, ConnectionObserver.emptyListener(),
ClientCookieEncoder.STRICT, ClientCookieDecoder.STRICT)
.addHandler("json", new JsonObjectDecoder());
channel.writeInbound(new DefaultLastHttpContent(buf));
MatcherAssert.assertThat(channel.pipeline().names().iterator().next(), is("json$extractor"));
Object content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(ByteBuf.class));
((ByteBuf) content).release();
content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(LastHttpContent.class));
((LastHttpContent) content).release();
MatcherAssert.assertThat(channel.readInbound(), nullValue());
}
@Test
public void addEncoderReplaysLastHttp() {
ByteBuf buf = Unpooled.copiedBuffer("{\"foo\":1}", CharsetUtil.UTF_8);
EmbeddedChannel channel = new EmbeddedChannel();
new HttpClientOperations(() -> channel, ConnectionObserver.emptyListener(),
ClientCookieEncoder.STRICT, ClientCookieDecoder.STRICT)
.addHandler(new JsonObjectDecoder());
channel.writeInbound(new DefaultLastHttpContent(buf));
MatcherAssert.assertThat(channel.pipeline().names().iterator().next(), is("JsonObjectDecoder$extractor"));
Object content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(ByteBuf.class));
((ByteBuf) content).release();
content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(LastHttpContent.class));
((LastHttpContent) content).release();
MatcherAssert.assertThat(channel.readInbound(), nullValue());
}
@Test
public void addNamedEncoderReplaysLastHttp() {
ByteBuf buf = Unpooled.copiedBuffer("{\"foo\":1}", CharsetUtil.UTF_8);
EmbeddedChannel channel = new EmbeddedChannel();
new HttpClientOperations(() -> channel, ConnectionObserver.emptyListener(),
ClientCookieEncoder.STRICT, ClientCookieDecoder.STRICT)
.addHandler("json", new JsonObjectDecoder());
channel.writeInbound(new DefaultLastHttpContent(buf));
MatcherAssert.assertThat(channel.pipeline().names().iterator().next(), is("json$extractor"));
Object content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(ByteBuf.class));
((ByteBuf) content).release();
content = channel.readInbound();
MatcherAssert.assertThat(content, instanceOf(LastHttpContent.class));
((LastHttpContent) content).release();
MatcherAssert.assertThat(channel.readInbound(), nullValue());
}
@Test
public void testBuildContent()
throws Exception {
HttpRequest nettyRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_0, HttpMethod.GET, "www.google.com");
RecordedHttpRequestBuilder recordedHttpRequestBuilder = new RecordedHttpRequestBuilder(nettyRequest);
String charset = "UTF-8";
String str1 = "first content";
HttpContent httpContent1 = new DefaultHttpContent(Unpooled.copiedBuffer(str1.getBytes(charset)));
recordedHttpRequestBuilder.appendHttpContent(httpContent1);
String str2 = "second content";
HttpContent httpContent2 = new DefaultHttpContent(Unpooled.copiedBuffer(str2.getBytes(charset)));
recordedHttpRequestBuilder.appendHttpContent(httpContent2);
String lastStr = "Last chunk";
HttpContent lastContent = new DefaultLastHttpContent(Unpooled.copiedBuffer(lastStr.getBytes(charset)));
recordedHttpRequestBuilder.appendHttpContent(lastContent);
RecordedHttpRequest recordedHttpRequest = recordedHttpRequestBuilder.build();
Assert
.assertEquals((str1 + str2 + lastStr).getBytes(charset), recordedHttpRequest.getHttpBody().getContent(charset));
}
@Test
public void testBuild()
throws IOException {
HttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_0, HttpResponseStatus.GATEWAY_TIMEOUT);
RecordedHttpResponseBuilder recordedHttpResponseBuilder = new RecordedHttpResponseBuilder(httpResponse);
String charset = "UTF-8";
String str1 = "Hello world";
HttpContent httpContent1 = new DefaultHttpContent(Unpooled.copiedBuffer(str1.getBytes(charset)));
recordedHttpResponseBuilder.appendHttpContent(httpContent1);
String str2 = "second content";
HttpContent httpContent2 = new DefaultHttpContent(Unpooled.copiedBuffer(str2.getBytes(charset)));
recordedHttpResponseBuilder.appendHttpContent(httpContent2);
String lastStr = "Last chunk";
HttpContent lastContent = new DefaultLastHttpContent(Unpooled.copiedBuffer(lastStr.getBytes(charset)));
recordedHttpResponseBuilder.appendHttpContent(lastContent);
RecordedHttpResponse recordedHttpResponse = recordedHttpResponseBuilder.build();
Assert.assertEquals(recordedHttpResponse.getStatus(), HttpResponseStatus.GATEWAY_TIMEOUT.code());
Assert.assertEquals((str1 + str2 + lastStr).getBytes(charset),
recordedHttpResponse.getHttpBody().getContent(charset));
}
private void handleThrowable(MicroservicesRegistryImpl currentMicroservicesRegistry, Throwable throwable,
Request request) {
Optional<ExceptionMapper> exceptionMapper = currentMicroservicesRegistry.getExceptionMapper(throwable);
if (exceptionMapper.isPresent()) {
org.wso2.msf4j.Response msf4jResponse = new org.wso2.msf4j.Response(request);
msf4jResponse.setEntity(exceptionMapper.get().toResponse(throwable));
msf4jResponse.send();
} else {
log.warn("Unmapped exception", throwable);
try {
HttpCarbonMessage response = HttpUtil.createTextResponse(
javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(),
"Exception occurred :" + throwable.getMessage());
response.setHeader("Content-type", "text/plain");
response.addHttpContent(new DefaultLastHttpContent());
request.respond(response);
} catch (ServerConnectorException e) {
log.error("Error while sending the response.", e);
}
}
}
/**
* Write the entity to the carbon message.
*/
@Override
public void writeData(HttpCarbonMessage carbonMessage, Object entity, String mediaType, int chunkSize,
HttpCarbonMessage responder) {
mediaType = (mediaType != null) ? mediaType : MediaType.WILDCARD;
ByteBuffer byteBuffer = BeanConverter.getConverter(mediaType).convertToMedia(entity);
carbonMessage.addHttpContent(new DefaultLastHttpContent(Unpooled.wrappedBuffer(byteBuffer)));
if (chunkSize == Response.NO_CHUNK) {
carbonMessage.setHeader(HttpHeaderNames.CONTENT_LENGTH.toString(), String.valueOf(byteBuffer.remaining()));
} else {
carbonMessage.setHeader(HttpHeaderNames.TRANSFER_ENCODING.toString(), CHUNKED);
}
carbonMessage.setHeader(HttpHeaderNames.CONTENT_TYPE.toString(), mediaType);
try {
responder.respond(carbonMessage);
} catch (ServerConnectorException e) {
throw new RuntimeException("Error while sending the response.", e);
}
}
/**
* Create a CarbonMessage for a specific status code.
*
* @param status HTTP status code
* @param msg message text
* @return CarbonMessage representing the status
*/
public static HttpCarbonMessage createTextResponse(int status, String msg) {
HttpCarbonMessage response = new HttpCarbonMessage(
new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.valueOf(status)));
response.setHttpStatusCode(status);
if (msg != null) {
response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(msg.length()));
byte[] msgArray = null;
try {
msgArray = msg.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Failed to get the byte array from responseValue", e);
}
ByteBuffer byteBuffer = ByteBuffer.allocate(msgArray.length);
byteBuffer.put(msgArray);
byteBuffer.flip();
response.addHttpContent(new DefaultLastHttpContent(Unpooled.wrappedBuffer(byteBuffer)));
} else {
response.setHeader(HttpHeaders.CONTENT_LENGTH, "0");
}
return response;
}
@Test
public void shouldDecodeSuccessfulGetDesignDocumentResponse() throws Exception {
String response = Resources.read("designdoc_success.json", this.getClass());
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(200, "OK"));
HttpContent responseChunk = new DefaultLastHttpContent(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8));
GetDesignDocumentRequest requestMock = mock(GetDesignDocumentRequest.class);
when(requestMock.name()).thenReturn("name");
when(requestMock.development()).thenReturn(true);
queue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk);
latch.await(1, TimeUnit.SECONDS);
assertEquals(1, firedEvents.size());
GetDesignDocumentResponse inbound = (GetDesignDocumentResponse) firedEvents.get(0);
assertTrue(inbound.status().isSuccess());
assertEquals("name", inbound.name());
assertEquals(true, inbound.development());
assertEquals(response, inbound.content().toString(CharsetUtil.UTF_8));
ReferenceCountUtil.releaseLater(inbound);
}
@Test
public void shouldParseErrorWithEmptyRows() throws Exception {
String response = Resources.read("error_empty_rows.json", this.getClass());
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(200, "OK"));
HttpContent responseChunk1 = new DefaultLastHttpContent(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8));
ViewQueryRequest requestMock = mock(ViewQueryRequest.class);
queue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk1);
latch.await(1, TimeUnit.SECONDS);
assertEquals(1, firedEvents.size());
ViewQueryResponse inbound = (ViewQueryResponse) firedEvents.get(0);
assertTrue(inbound.status().isSuccess());
assertEquals(0, countAndRelease(inbound.rows()));
String error = inbound.error().toBlocking().single();
Map<String, Object> parsed = DefaultObjectMapper.readValueAsMap(error);
assertEquals(1, parsed.size());
assertNotNull(parsed.get("errors"));
}
@Test
public void shouldParseErrorAfterRows() throws Exception {
String response = Resources.read("error_rows.json", this.getClass());
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(200, "OK"));
HttpContent responseChunk1 = new DefaultLastHttpContent(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8));
ViewQueryRequest requestMock = mock(ViewQueryRequest.class);
queue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk1);
latch.await(1, TimeUnit.SECONDS);
assertEquals(1, firedEvents.size());
ViewQueryResponse inbound = (ViewQueryResponse) firedEvents.get(0);
assertTrue(inbound.status().isSuccess());
assertEquals(10, countAndRelease(inbound.rows()));
String error = inbound.error().toBlocking().single();
Map<String, Object> parsed = DefaultObjectMapper.readValueAsMap(error);
assertEquals(1, parsed.size());
assertNotNull(parsed.get("errors"));
}
@Test
public void shouldParseErrorWithDesignNotFound() throws Exception {
String response = Resources.read("designdoc_notfound.json", this.getClass());
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(404, "Object Not Found"));
HttpContent responseChunk1 = new DefaultLastHttpContent(Unpooled.copiedBuffer(response, CharsetUtil.UTF_8));
ViewQueryRequest requestMock = mock(ViewQueryRequest.class);
queue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk1);
latch.await(1, TimeUnit.SECONDS);
assertEquals(1, firedEvents.size());
ViewQueryResponse inbound = (ViewQueryResponse) firedEvents.get(0);
assertFalse(inbound.status().isSuccess());
assertEquals(ResponseStatus.NOT_EXISTS, inbound.status());
assertEquals(0, countAndRelease(inbound.rows()));
String error = inbound.error().toBlocking().single();
assertEquals("{\"errors\":[{\"error\":\"not_found\",\"reason\":\"Design document _design/designdoc not found\"}]}", error);
}
@Test
public void shouldDecodeSuccessBucketConfigResponse() throws Exception {
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(200, "OK"));
HttpContent responseChunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("foo", CHARSET));
HttpContent responseChunk2 = new DefaultLastHttpContent(Unpooled.copiedBuffer("bar", CHARSET));
BucketConfigRequest requestMock = mock(BucketConfigRequest.class);
requestQueue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk1, responseChunk2);
channel.readInbound();
assertEquals(1, eventSink.responseEvents().size());
BucketConfigResponse event = (BucketConfigResponse) eventSink.responseEvents().get(0).getMessage();
assertEquals(ResponseStatus.SUCCESS, event.status());
assertEquals("foobar", event.config());
assertTrue(requestQueue.isEmpty());
}
@Test
public void shouldDecodeNotFoundBucketConfigResponse() throws Exception {
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
new HttpResponseStatus(404, "Object Not Found"));
HttpContent responseChunk = new DefaultLastHttpContent(Unpooled.copiedBuffer("Not found.", CharsetUtil.UTF_8));
BucketConfigRequest requestMock = mock(BucketConfigRequest.class);
requestQueue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk);
assertEquals(1, eventSink.responseEvents().size());
BucketConfigResponse event = (BucketConfigResponse) eventSink.responseEvents().get(0).getMessage();
assertEquals(ResponseStatus.NOT_EXISTS, event.status());
assertEquals("Not found.", event.config());
assertTrue(requestQueue.isEmpty());
}
@Test
public void shouldDecodeFlushNotEnabledResponse() throws Exception {
String content = "{\"_\":\"Flush is disabled for the bucket\"}";
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1,
new HttpResponseStatus(400, "Bad Request"));
HttpContent responseChunk = new DefaultLastHttpContent(Unpooled.copiedBuffer(content, CharsetUtil.UTF_8));
FlushRequest requestMock = mock(FlushRequest.class);
requestQueue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk);
assertEquals(1, eventSink.responseEvents().size());
FlushResponse event = (FlushResponse) eventSink.responseEvents().get(0).getMessage();
assertEquals(ResponseStatus.INVALID_ARGUMENTS, event.status());
assertEquals("{\"_\":\"Flush is disabled for the bucket\"}", event.content());
assertTrue(requestQueue.isEmpty());
}
@Test
public void shouldDecodeListDesignDocumentsResponse() throws Exception {
HttpResponse responseHeader = new DefaultHttpResponse(HttpVersion.HTTP_1_1, new HttpResponseStatus(200, "OK"));
HttpContent responseChunk1 = new DefaultHttpContent(Unpooled.copiedBuffer("foo", CharsetUtil.UTF_8));
HttpContent responseChunk2 = new DefaultLastHttpContent(Unpooled.copiedBuffer("bar", CharsetUtil.UTF_8));
GetDesignDocumentsRequest requestMock = mock(GetDesignDocumentsRequest.class);
requestQueue.add(requestMock);
channel.writeInbound(responseHeader, responseChunk1, responseChunk2);
assertEquals(1, eventSink.responseEvents().size());
GetDesignDocumentsResponse event = (GetDesignDocumentsResponse) eventSink.responseEvents().get(0).getMessage();
assertEquals(ResponseStatus.SUCCESS, event.status());
assertEquals("foobar", event.content());
assertTrue(requestQueue.isEmpty());
}
/**
* 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);
}
/**
* Splits the given {@code contentBytes} into {@code numChunks} chunks and stores them in {@code httpContents}.
* @param contentBytes the content that needs to be split.
* @param numChunks the number of chunks to split {@code contentBytes} into.
* @param httpContents the {@link List<HttpContent>} that will contain all the content in parts.
* @param useCopyForcingByteBuf if {@code true}, uses {@link CopyForcingByteBuf} instead of the default
* {@link ByteBuf}.
*/
private void splitContent(byte[] contentBytes, int numChunks, List<HttpContent> httpContents,
boolean useCopyForcingByteBuf) {
int individualPartSize = contentBytes.length / numChunks;
ByteBuf content;
for (int addedContentCount = 0; addedContentCount < numChunks - 1; addedContentCount++) {
if (useCopyForcingByteBuf) {
content =
CopyForcingByteBuf.wrappedBuffer(contentBytes, addedContentCount * individualPartSize, individualPartSize);
} else {
content = Unpooled.wrappedBuffer(contentBytes, addedContentCount * individualPartSize, individualPartSize);
}
httpContents.add(new DefaultHttpContent(content));
}
if (useCopyForcingByteBuf) {
content =
CopyForcingByteBuf.wrappedBuffer(contentBytes, (numChunks - 1) * individualPartSize, individualPartSize);
} else {
content = Unpooled.wrappedBuffer(contentBytes, (numChunks - 1) * individualPartSize, individualPartSize);
}
httpContents.add(new DefaultLastHttpContent(content));
}
/**
* Sends the provided {@code httpRequest} and verifies that the response is an echo of the {@code restMethod}.
* @param channel the {@link EmbeddedChannel} to send the request over.
* @param httpMethod the {@link HttpMethod} for the request.
* @param restMethod the equivalent {@link RestMethod} for {@code httpMethod}. Used to check for correctness of
* response.
* @param isKeepAlive if the request needs to be keep-alive.
* @throws IOException
*/
private void sendRequestCheckResponse(EmbeddedChannel channel, HttpMethod httpMethod, RestMethod restMethod,
boolean isKeepAlive) throws IOException {
long requestId = REQUEST_ID_GENERATOR.getAndIncrement();
String uri = MockRestRequestService.ECHO_REST_METHOD + requestId;
HttpRequest httpRequest = RestTestUtils.createRequest(httpMethod, uri, null);
HttpUtil.setKeepAlive(httpRequest, isKeepAlive);
channel.writeInbound(httpRequest);
channel.writeInbound(new DefaultLastHttpContent());
HttpResponse response = (HttpResponse) channel.readOutbound();
assertEquals("Unexpected response status", HttpResponseStatus.OK, response.status());
// MockRestRequestService echoes the RestMethod + request id.
String expectedResponse = restMethod.toString() + requestId;
assertEquals("Unexpected content", expectedResponse,
RestTestUtils.getContentString((HttpContent) channel.readOutbound()));
assertTrue("End marker was expected", channel.readOutbound() instanceof LastHttpContent);
}
@Setup(Level.Trial)
public void setup() {
byte[] bytes = new byte[256];
content = Unpooled.buffer(bytes.length);
content.writeBytes(bytes);
ByteBuf testContent = Unpooled.unreleasableBuffer(content.asReadOnly());
HttpHeaders headersWithChunked = new DefaultHttpHeaders(false);
headersWithChunked.add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
HttpHeaders headersWithContentLength = new DefaultHttpHeaders(false);
headersWithContentLength.add(HttpHeaderNames.CONTENT_LENGTH, testContent.readableBytes());
fullRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/index", testContent,
headersWithContentLength, EmptyHttpHeaders.INSTANCE);
contentLengthRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/index",
headersWithContentLength);
chunkedRequest = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/index", headersWithChunked);
lastContent = new DefaultLastHttpContent(testContent, false);
encoder = new HttpRequestEncoder();
context = new EmbeddedChannelWriteReleaseHandlerContext(pooledAllocator ? PooledByteBufAllocator.DEFAULT :
UnpooledByteBufAllocator.DEFAULT, encoder) {
@Override
protected void handleException(Throwable t) {
handleUnexpectedException(t);
}
};
}
@Test
public void testUpgradeTrailers() throws Exception {
EmbeddedChannel ch = new EmbeddedChannel(new Http2StreamFrameToHttpObjectCodec(true));
LastHttpContent trailers = new DefaultLastHttpContent(Unpooled.EMPTY_BUFFER, true);
HttpHeaders headers = trailers.trailingHeaders();
headers.set("key", "value");
assertTrue(ch.writeOutbound(trailers));
Http2HeadersFrame headerFrame = ch.readOutbound();
assertThat(headerFrame.headers().get("key").toString(), is("value"));
assertTrue(headerFrame.isEndStream());
assertThat(ch.readOutbound(), is(nullValue()));
assertFalse(ch.finish());
}