use of io.netty.handler.codec.http2.Http2HeadersFrame in project reactor-netty by reactor.
the class AccessLogHandlerH2 method write.
@Override
@SuppressWarnings("FutureReturnValueIgnored")
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
boolean lastContent = false;
if (msg instanceof Http2HeadersFrame) {
final Http2HeadersFrame responseHeaders = (Http2HeadersFrame) msg;
lastContent = responseHeaders.isEndStream();
accessLogArgProvider.responseHeaders(responseHeaders).chunked(true);
ChannelOperations<?, ?> ops = ChannelOperations.get(ctx.channel());
if (ops instanceof HttpInfos) {
accessLogArgProvider.cookies(((HttpInfos) ops).cookies());
}
}
if (msg instanceof Http2DataFrame) {
final Http2DataFrame data = (Http2DataFrame) msg;
lastContent = data.isEndStream();
accessLogArgProvider.increaseContentLength(data.content().readableBytes());
}
if (lastContent) {
ctx.write(msg, promise.unvoid()).addListener(future -> {
if (future.isSuccess()) {
AccessLog log = accessLog.apply(accessLogArgProvider);
if (log != null) {
log.log();
}
accessLogArgProvider.clear();
}
});
return;
}
// "FutureReturnValueIgnored" this is deliberate
ctx.write(msg, promise);
}
use of io.netty.handler.codec.http2.Http2HeadersFrame in project netty by netty.
the class Http2FrameCodec method writeHeadersFrame.
private void writeHeadersFrame(Http2HeadersFrame headersFrame, ChannelPromise promise) {
int streamId = headersFrame.streamId();
if (!isStreamIdValid(streamId)) {
final Endpoint<Http2LocalFlowController> localEndpoint = http2Handler.connection().local();
streamId = localEndpoint.incrementAndGetNextStreamId();
try {
// Try to create a stream in OPEN state before writing headers, to catch errors on stream creation
// early on i.e. max concurrent streams limit reached, stream id exhaustion, etc.
localEndpoint.createStream(streamId, false);
} catch (Http2Exception e) {
promise.setFailure(e);
return;
}
ctx.fireUserEventTriggered(new Http2StreamActiveEvent(streamId, headersFrame));
}
http2Handler.encoder().writeHeaders(http2HandlerCtx, streamId, headersFrame.headers(), headersFrame.padding(), headersFrame.isEndStream(), promise);
}
use of io.netty.handler.codec.http2.Http2HeadersFrame in project netty by netty.
the class Http2FrameCodecTest method streamErrorShouldFireUserEvent.
@Test
public void streamErrorShouldFireUserEvent() throws Exception {
frameListener.onHeadersRead(http2HandlerCtx, 3, request, 31, false);
Http2Stream stream = framingCodec.connectionHandler().connection().stream(3);
assertNotNull(stream);
Http2StreamActiveEvent activeEvent = inboundHandler.readInboundMessageOrUserEvent();
assertNotNull(activeEvent);
assertEquals(stream.id(), activeEvent.streamId());
StreamException streamEx = new StreamException(3, Http2Error.INTERNAL_ERROR, "foo");
framingCodec.connectionHandler().onError(http2HandlerCtx, streamEx);
Http2HeadersFrame headersFrame = inboundHandler.readInboundMessageOrUserEvent();
assertNotNull(headersFrame);
try {
inboundHandler.checkException();
fail("stream exception expected");
} catch (StreamException e) {
assertEquals(streamEx, e);
}
Http2StreamClosedEvent closedEvent = inboundHandler.readInboundMessageOrUserEvent();
assertNotNull(closedEvent);
assertEquals(stream.id(), closedEvent.streamId());
assertNull(inboundHandler.readInboundMessageOrUserEvent());
}
use of io.netty.handler.codec.http2.Http2HeadersFrame in project ambry by linkedin.
the class Http2ClientStreamStatsHandler method channelRead0.
@Override
protected void channelRead0(ChannelHandlerContext ctx, Http2Frame frame) throws Exception {
ReferenceCountUtil.retain(frame);
RequestInfo requestInfo = ctx.channel().attr(Http2NetworkClient.REQUEST_INFO).get();
requestInfo.responseFramesCount++;
long time = System.currentTimeMillis() - requestInfo.getStreamSendTime();
if (frame instanceof Http2HeadersFrame) {
http2ClientMetrics.http2StreamRoundTripTime.update(time);
requestInfo.setStreamHeaderFrameReceiveTime(System.currentTimeMillis());
logger.debug("Header Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
} else if (frame instanceof Http2DataFrame) {
logger.debug("Data Frame size: {}. Time from send: {}ms. Request: {}", ((Http2DataFrame) frame).content().readableBytes(), time, requestInfo);
}
if (frame instanceof Http2DataFrame && ((Http2DataFrame) frame).isEndStream()) {
http2ClientMetrics.http2StreamFirstToLastFrameTime.update(time);
http2ClientMetrics.http2ResponseFrameCount.update(requestInfo.responseFramesCount);
logger.debug("All Frame received. Time from send: {}ms. Request: {}", time, requestInfo);
}
ctx.fireChannelRead(frame);
}
use of io.netty.handler.codec.http2.Http2HeadersFrame in project netty by netty.
the class Http2FrameClient method main.
public static void main(String[] args) throws Exception {
final EventLoopGroup clientWorkerGroup = new NioEventLoopGroup();
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
final SslProvider provider = SslProvider.isAlpnSupported(SslProvider.OPENSSL) ? SslProvider.OPENSSL : SslProvider.JDK;
sslCtx = SslContextBuilder.forClient().sslProvider(provider).ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE).trustManager(InsecureTrustManagerFactory.INSTANCE).applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN, SelectorFailureBehavior.NO_ADVERTISE, SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)).build();
} else {
sslCtx = null;
}
try {
final Bootstrap b = new Bootstrap();
b.group(clientWorkerGroup);
b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true);
b.remoteAddress(HOST, PORT);
b.handler(new Http2ClientFrameInitializer(sslCtx));
// Start the client.
final Channel channel = b.connect().syncUninterruptibly().channel();
System.out.println("Connected to [" + HOST + ':' + PORT + ']');
final Http2ClientStreamFrameResponseHandler streamFrameResponseHandler = new Http2ClientStreamFrameResponseHandler();
final Http2StreamChannelBootstrap streamChannelBootstrap = new Http2StreamChannelBootstrap(channel);
final Http2StreamChannel streamChannel = streamChannelBootstrap.open().syncUninterruptibly().getNow();
streamChannel.pipeline().addLast(streamFrameResponseHandler);
// Send request (a HTTP/2 HEADERS frame - with ':method = GET' in this case)
final DefaultHttp2Headers headers = new DefaultHttp2Headers();
headers.method("GET");
headers.path(PATH);
headers.scheme(SSL ? "https" : "http");
final Http2HeadersFrame headersFrame = new DefaultHttp2HeadersFrame(headers, true);
streamChannel.writeAndFlush(headersFrame);
System.out.println("Sent HTTP/2 GET request to " + PATH);
// Wait for the responses (or for the latch to expire), then clean up the connections
if (!streamFrameResponseHandler.responseSuccessfullyCompleted()) {
System.err.println("Did not get HTTP/2 response in expected time.");
}
System.out.println("Finished HTTP/2 request, will close the connection.");
// Wait until the connection is closed.
channel.close().syncUninterruptibly();
} finally {
clientWorkerGroup.shutdownGracefully();
}
}
Aggregations