Adding payload to the Http2Client example.

Modifications:
When trying out the Http2Client example I noticed that adding a request
payload would not cause a data frame to written. This seems to be
because writeHeaders completes the promise, and then the writeData
call ends up in FlowControlWriter.writeFrame, isDone is true and
the data released and the call aborted and returned.
Adding a new promise for the writeData method allows a data frame to be
written.

Result:
A body/payload can now be sent to the server. The example was updated to
simply echo the payload received back to the calling client.
This commit is contained in:
Daniel Bevenius 2014-07-04 09:57:50 +02:00 committed by Norman Maurer
parent 9d08a34c34
commit cbe20faf6c
4 changed files with 14 additions and 12 deletions

View File

@ -15,6 +15,7 @@
package io.netty.example.http2.client;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
@ -27,6 +28,7 @@ import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http2.Http2OrHttpChooser.SelectedProtocol;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.util.CharsetUtil;
import java.util.Arrays;
@ -76,8 +78,9 @@ public final class Http2Client {
Http2ClientConnectionHandler http2ConnectionHandler = initializer.connectionHandler();
http2ConnectionHandler.awaitInitialization();
// Create a simple GET request with just headers.
FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET, "/whatever");
// Create a simple POST request with just headers.
FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, POST, "/whatever",
Unpooled.copiedBuffer("sample data".getBytes(CharsetUtil.UTF_8)));
request.headers().add(HttpHeaders.Names.HOST, HOST + ':' + PORT);
// Send the request to the server.

View File

@ -110,7 +110,7 @@ public class Http2ClientConnectionHandler extends AbstractHttp2ConnectionHandler
int streamId = nextStreamId();
writeHeaders(ctx, promise, streamId, headers.build(), 0, !hasData, false);
if (hasData) {
writeData(ctx, promise, streamId, httpMsg.content(), 0, true, true, false);
writeData(ctx, ctx.newPromise(), streamId, httpMsg.content(), 0, true, true, false);
}
} else {
ctx.write(msg, promise);

View File

@ -42,7 +42,7 @@ public class HelloWorldHttp1Handler extends SimpleChannelInboundHandler<HttpRequ
boolean keepAlive = HttpHeaderUtil.isKeepAlive(req);
ByteBuf content = ctx.alloc().buffer();
content.writeBytes(HelloWorldHttp2Handler.RESPONSE_BYTES);
content.writeBytes(HelloWorldHttp2Handler.RESPONSE_BYTES.duplicate());
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");

View File

@ -15,6 +15,8 @@
package io.netty.example.http2.server;
import static io.netty.buffer.Unpooled.copiedBuffer;
import static io.netty.buffer.Unpooled.unreleasableBuffer;
import static io.netty.example.http2.Http2ExampleUtil.UPGRADE_RESPONSE_HEADER;
import static io.netty.util.internal.logging.InternalLogLevel.INFO;
import io.netty.buffer.ByteBuf;
@ -44,7 +46,7 @@ public class HelloWorldHttp2Handler extends AbstractHttp2ConnectionHandler {
private static final Http2FrameLogger logger = new Http2FrameLogger(INFO,
InternalLoggerFactory.getInstance(Http2ClientConnectionHandler.class));
static final byte[] RESPONSE_BYTES = "Hello World".getBytes(CharsetUtil.UTF_8);
static final ByteBuf RESPONSE_BYTES = unreleasableBuffer(copiedBuffer("Hello World", CharsetUtil.UTF_8));
public HelloWorldHttp2Handler() {
this(new DefaultHttp2Connection(true));
@ -79,7 +81,7 @@ public class HelloWorldHttp2Handler extends AbstractHttp2ConnectionHandler {
public void onDataRead(ChannelHandlerContext ctx, int streamId, ByteBuf data, int padding,
boolean endOfStream, boolean endOfSegment) throws Http2Exception {
if (endOfStream) {
sendResponse(ctx(), streamId);
sendResponse(ctx(), streamId, data.retain());
}
}
@ -92,7 +94,7 @@ public class HelloWorldHttp2Handler extends AbstractHttp2ConnectionHandler {
boolean exclusive, int padding, boolean endStream, boolean endSegment)
throws Http2Exception {
if (endStream) {
sendResponse(ctx(), streamId);
sendResponse(ctx(), streamId, RESPONSE_BYTES.duplicate());
}
}
@ -105,14 +107,11 @@ public class HelloWorldHttp2Handler extends AbstractHttp2ConnectionHandler {
/**
* Sends a "Hello World" DATA frame to the client.
*/
private void sendResponse(ChannelHandlerContext ctx, int streamId) {
private void sendResponse(ChannelHandlerContext ctx, int streamId, ByteBuf payload) {
// Send a frame for the response status
Http2Headers headers = DefaultHttp2Headers.newBuilder().status("200").build();
writeHeaders(ctx(), ctx().newPromise(), streamId, headers, 0, false, false);
// Send a data frame with the response message.
ByteBuf content = ctx.alloc().buffer();
content.writeBytes(RESPONSE_BYTES);
writeData(ctx(), ctx().newPromise(), streamId, content, 0, true, true, false);
writeData(ctx(), ctx().newPromise(), streamId, payload, 0, true, true, false);
}
}