use of io.netty.handler.codec.http2.Http2Exception.connectionError in project rest.li by linkedin.
the class Http2FrameListener method onHeadersRead.
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int padding, boolean endOfStream) throws Http2Exception {
LOG.debug("Received HTTP/2 HEADERS frame, stream={}, end={}, headers={}, padding={}bytes", new Object[] { streamId, endOfStream, headers.size(), padding });
// Ignores response for the upgrade request
if (streamId == Http2CodecUtil.HTTP_UPGRADE_STREAM_ID) {
return;
}
final StreamResponseBuilder builder = new StreamResponseBuilder();
// Process HTTP/2 pseudo headers
if (headers.status() != null) {
builder.setStatus(Integer.parseInt(headers.status().toString()));
}
if (headers.authority() != null) {
builder.addHeaderValue(HttpHeaderNames.HOST.toString(), headers.authority().toString());
}
// Process other HTTP headers
for (Map.Entry<CharSequence, CharSequence> header : headers) {
if (Http2Headers.PseudoHeaderName.isPseudoHeader(header.getKey())) {
// Do no set HTTP/2 pseudo headers to response
continue;
}
final String key = header.getKey().toString();
final String value = header.getValue().toString();
if (key.equalsIgnoreCase(HttpConstants.RESPONSE_COOKIE_HEADER_NAME)) {
builder.addCookie(value);
} else {
builder.unsafeAddHeaderValue(key, value);
}
}
// Gets async pool handle from stream properties
Http2Connection.PropertyKey handleKey = ctx.channel().attr(Http2ClientPipelineInitializer.CHANNEL_POOL_HANDLE_ATTR_KEY).get();
TimeoutAsyncPoolHandle<?> handle = _connection.stream(streamId).removeProperty(handleKey);
if (handle == null) {
_lifecycleManager.onError(ctx, Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR, "No channel pool handle is associated with this stream", streamId));
return;
}
final StreamResponse response;
if (endOfStream) {
response = builder.build(EntityStreams.emptyStream());
ctx.fireChannelRead(handle);
} else {
// Associate an entity stream writer to the HTTP/2 stream
final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, streamId, _maxContentLength, handle);
if (_connection.stream(streamId).setProperty(_writerKey, writer) != null) {
_lifecycleManager.onError(ctx, Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR, "Another writer has already been associated with current stream ID", streamId));
return;
}
// Prepares StreamResponse for the channel pipeline
EntityStream entityStream = EntityStreams.newEntityStream(writer);
response = builder.build(entityStream);
}
// Gets callback from stream properties
Http2Connection.PropertyKey callbackKey = ctx.channel().attr(Http2ClientPipelineInitializer.CALLBACK_ATTR_KEY).get();
TransportCallback<?> callback = _connection.stream(streamId).removeProperty(callbackKey);
if (callback != null) {
ctx.fireChannelRead(new ResponseWithCallback<Response, TransportCallback<?>>(response, callback));
}
}
use of io.netty.handler.codec.http2.Http2Exception.connectionError in project netty by netty.
the class Http2ConnectionRoundtripTest method http2ExceptionInPipelineShouldCloseConnection.
@Test
public void http2ExceptionInPipelineShouldCloseConnection() throws Exception {
bootstrapEnv(1, 1, 2, 1);
// Create a latch to track when the close occurs.
final CountDownLatch closeLatch = new CountDownLatch(1);
clientChannel.closeFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) throws Exception {
closeLatch.countDown();
}
});
// Create a single stream by sending a HEADERS frame to the server.
final Http2Headers headers = dummyHeaders();
runInChannel(clientChannel, new Http2Runnable() {
@Override
public void run() throws Http2Exception {
http2Client.encoder().writeHeaders(ctx(), 3, headers, 0, (short) 16, false, 0, false, newPromise());
http2Client.flush(ctx());
}
});
// Wait for the server to create the stream.
assertTrue(serverSettingsAckLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
assertTrue(requestLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
// Add a handler that will immediately throw an exception.
clientChannel.pipeline().addFirst(new ChannelHandlerAdapter() {
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
throw Http2Exception.connectionError(PROTOCOL_ERROR, "Fake Exception");
}
});
// Wait for the close to occur.
assertTrue(closeLatch.await(DEFAULT_AWAIT_TIMEOUT_SECONDS, SECONDS));
assertFalse(clientChannel.isOpen());
}
Aggregations