Search in sources :

Example 1 with Http2Exception.connectionError

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));
    }
}
Also used : TransportCallback(com.linkedin.r2.transport.common.bridge.common.TransportCallback) StreamResponseBuilder(com.linkedin.r2.message.stream.StreamResponseBuilder) Http2Connection(io.netty.handler.codec.http2.Http2Connection) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) ByteString(com.linkedin.data.ByteString) EntityStream(com.linkedin.r2.message.stream.entitystream.EntityStream) StreamResponse(com.linkedin.r2.message.stream.StreamResponse) Response(com.linkedin.r2.message.Response) Map(java.util.Map)

Example 2 with Http2Exception.connectionError

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());
}
Also used : ChannelFuture(io.netty.channel.ChannelFuture) ChannelHandlerAdapter(io.netty.channel.ChannelHandlerAdapter) Http2Runnable(io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) CountDownLatch(java.util.concurrent.CountDownLatch) ChannelFutureListener(io.netty.channel.ChannelFutureListener) Test(org.junit.Test)

Aggregations

ByteString (com.linkedin.data.ByteString)1 Response (com.linkedin.r2.message.Response)1 StreamResponse (com.linkedin.r2.message.stream.StreamResponse)1 StreamResponseBuilder (com.linkedin.r2.message.stream.StreamResponseBuilder)1 EntityStream (com.linkedin.r2.message.stream.entitystream.EntityStream)1 TransportCallback (com.linkedin.r2.transport.common.bridge.common.TransportCallback)1 ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelFutureListener (io.netty.channel.ChannelFutureListener)1 ChannelHandlerAdapter (io.netty.channel.ChannelHandlerAdapter)1 ChannelHandlerContext (io.netty.channel.ChannelHandlerContext)1 Http2Connection (io.netty.handler.codec.http2.Http2Connection)1 Http2Runnable (io.netty.handler.codec.http2.Http2TestUtil.Http2Runnable)1 Map (java.util.Map)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 Test (org.junit.Test)1