use of com.linkedin.r2.transport.http.client.TimeoutAsyncPoolHandle in project rest.li by linkedin.
the class TestHttp2ProtocolUpgradeHandler method testChannelCloseBeforeUpgrade.
@Test(timeOut = 10000)
@SuppressWarnings("unchecked")
public void testChannelCloseBeforeUpgrade() throws Exception {
Http2UpgradeHandler handler = new Http2UpgradeHandler();
EmbeddedChannel channel = new EmbeddedChannel(handler);
// Reads the upgrade request from the outbound buffer to ensure nothing in the buffer
Assert.assertEquals(channel.outboundMessages().size(), 1);
Assert.assertNotNull(channel.readOutbound());
Assert.assertTrue(channel.outboundMessages().isEmpty());
RequestWithCallback request = Mockito.mock(RequestWithCallback.class);
TimeoutAsyncPoolHandle handle = Mockito.mock(TimeoutAsyncPoolHandle.class);
TimeoutTransportCallback callback = Mockito.mock(TimeoutTransportCallback.class);
Mockito.when(request.handle()).thenReturn(handle);
Mockito.when(request.callback()).thenReturn(callback);
// Write should not succeed before upgrade completes
Assert.assertFalse(channel.writeOutbound(request));
Assert.assertFalse(channel.finish());
// Synchronously waiting for channel to close
channel.close().sync();
Mockito.verify(request).handle();
Mockito.verify(request).callback();
Mockito.verify(handle).dispose();
Mockito.verify(callback).onResponse(Mockito.any(TransportResponse.class));
}
use of com.linkedin.r2.transport.http.client.TimeoutAsyncPoolHandle 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;
}
// Refactored duplicate code to new code pipeline.
final StreamResponseBuilder builder = Http2MessageDecoders.ResponseDecoder.buildStreamResponse(headers);
// Gets async pool handle from stream properties
TimeoutAsyncPoolHandle<?> timeoutHandle = Http2PipelinePropertyUtil.remove(ctx, _connection, streamId, Http2ClientPipelineInitializer.CHANNEL_POOL_HANDLE_ATTR_KEY);
if (timeoutHandle == null) {
_lifecycleManager.onError(ctx, false, 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());
// Release the handle to put the channel back to the pool
timeoutHandle.release();
} else {
// Associate an entity stream writer to the HTTP/2 stream
final TimeoutBufferedWriter writer = new TimeoutBufferedWriter(ctx, streamId, _maxContentLength, timeoutHandle);
if (_connection.stream(streamId).setProperty(_writerKey, writer) != null) {
_lifecycleManager.onError(ctx, false, 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
TransportCallback<?> callback = Http2PipelinePropertyUtil.remove(ctx, _connection, streamId, Http2ClientPipelineInitializer.CALLBACK_ATTR_KEY);
if (callback != null) {
ctx.fireChannelRead(new ResponseWithCallback<Response, TransportCallback<?>>(response, callback));
}
}
Aggregations