Adding a propagateSettings flag to InboundHttp2ToHttpAdapter.
Motivation: When DefaultHttp2FrameReader has read a settings frame, the settings will be passed along the pipeline. This allows a client to hold off sending data until it has received a settings frame. But for a server it will always have received a settings frame and the usefulness of this forwarding of settings is less useful. This also causes a debug message to be logged on the server side if there is no channel handler to handle the settings: [nioEventLoopGroup-1-1] DEBUG io.netty.channel.DefaultChannelPipeline - Discarded inbound message {INITIAL_WINDOW_SIZE=131072, MAX_FRAME_SIZE=16384} that reached at the tail of the pipeline. Please check your pipeline configuration. Modifications: Added a builder for the InboundHttp2ToHttpAdapter and InboundHttp2PriortyAdapter and a new parameter named 'propagateSettings' to their constructors. Result: It is now possible to control whether settings should be passed along the pipeline or not.
This commit is contained in:
parent
22c8ee7d16
commit
6a30c9534b
@ -482,8 +482,6 @@ public class DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSize
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
listener.onSettingsRead(ctx, settings);
|
listener.onSettingsRead(ctx, settings);
|
||||||
// Provide an interface for non-listeners to capture settings
|
|
||||||
ctx.fireChannelRead(settings);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,80 +61,83 @@ public class InboundHttp2ToHttpAdapter extends Http2EventAdapter {
|
|||||||
protected final boolean validateHttpHeaders;
|
protected final boolean validateHttpHeaders;
|
||||||
private final ImmediateSendDetector sendDetector;
|
private final ImmediateSendDetector sendDetector;
|
||||||
protected final IntObjectMap<FullHttpMessage> messageMap;
|
protected final IntObjectMap<FullHttpMessage> messageMap;
|
||||||
|
private final boolean propagateSettings;
|
||||||
|
|
||||||
/**
|
public static class Builder {
|
||||||
* Creates a new instance
|
|
||||||
*
|
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
|
||||||
* @throws NullPointerException If {@code connection} is null
|
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
public static InboundHttp2ToHttpAdapter newInstance(Http2Connection connection, int maxContentLength) {
|
|
||||||
InboundHttp2ToHttpAdapter instance = new InboundHttp2ToHttpAdapter(connection, maxContentLength);
|
|
||||||
connection.addListener(instance);
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
private final Http2Connection connection;
|
||||||
* Creates a new instance
|
private int maxContentLength;
|
||||||
*
|
private boolean validateHttpHeaders;
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
private boolean propagateSettings;
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
|
||||||
* @param validateHttpHeaders
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} to validate HTTP headers in the http-codec</li>
|
|
||||||
* <li>{@code false} not to validate HTTP headers in the http-codec</li>
|
|
||||||
* </ul>
|
|
||||||
* @throws NullPointerException If {@code connection} is null
|
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
public static InboundHttp2ToHttpAdapter newInstance(Http2Connection connection, int maxContentLength,
|
|
||||||
boolean validateHttpHeaders) {
|
|
||||||
InboundHttp2ToHttpAdapter instance = new InboundHttp2ToHttpAdapter(connection,
|
|
||||||
maxContentLength, validateHttpHeaders);
|
|
||||||
connection.addListener(instance);
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new {@link InboundHttp2ToHttpAdapter} builder for the specified {@link Http2Connection}.
|
||||||
*
|
*
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
* @param connection The object which will provide connection notification events for the current connection
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
*/
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
public Builder(Http2Connection connection) {
|
||||||
* @throws NullPointerException If {@code connection} is null
|
this.connection = connection;
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
protected InboundHttp2ToHttpAdapter(Http2Connection connection, int maxContentLength) {
|
|
||||||
this(connection, maxContentLength, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance
|
|
||||||
*
|
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
|
||||||
* @param validateHttpHeaders
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} to validate HTTP headers in the http-codec</li>
|
|
||||||
* <li>{@code false} not to validate HTTP headers in the http-codec</li>
|
|
||||||
* </ul>
|
|
||||||
* @throws NullPointerException If {@code connection} is null
|
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
protected InboundHttp2ToHttpAdapter(Http2Connection connection, int maxContentLength,
|
|
||||||
boolean validateHttpHeaders) {
|
|
||||||
checkNotNull(connection, "connection");
|
|
||||||
if (maxContentLength <= 0) {
|
|
||||||
throw new IllegalArgumentException("maxContentLength must be a positive integer: " + maxContentLength);
|
|
||||||
}
|
}
|
||||||
this.maxContentLength = maxContentLength;
|
|
||||||
this.validateHttpHeaders = validateHttpHeaders;
|
/**
|
||||||
this.connection = connection;
|
* Specifies the maximum length of the message content.
|
||||||
|
*
|
||||||
|
* @param maxContentLength the maximum length of the message content. If the length of the message content
|
||||||
|
* exceeds this value, a {@link TooLongFrameException} will be raised
|
||||||
|
* @return {@link Builder} the builder for the {@link InboundHttp2ToHttpAdapter}
|
||||||
|
*/
|
||||||
|
public Builder maxContentLength(int maxContentLength) {
|
||||||
|
this.maxContentLength = maxContentLength;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether validation of HTTP headers should be performed.
|
||||||
|
*
|
||||||
|
* @param validate
|
||||||
|
* <ul>
|
||||||
|
* <li>{@code true} to validate HTTP headers in the http-codec</li>
|
||||||
|
* <li>{@code false} not to validate HTTP headers in the http-codec</li>
|
||||||
|
* </ul>
|
||||||
|
* @return {@link Builder} the builder for the {@link InboundHttp2ToHttpAdapter}
|
||||||
|
*/
|
||||||
|
public Builder validateHttpHeaders(boolean validate) {
|
||||||
|
validateHttpHeaders = validate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether a read settings frame should be propagated alone the channel pipeline.
|
||||||
|
*
|
||||||
|
* @param propagate if {@code true} read settings will be passed along the pipeline. This can be useful
|
||||||
|
* to clients that need hold off sending data until they have received the settings.
|
||||||
|
* @return {@link Builder} the builder for the {@link InboundHttp2ToHttpAdapter}
|
||||||
|
*/
|
||||||
|
public Builder propagateSettings(boolean propagate) {
|
||||||
|
propagateSettings = propagate;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds/creates a new {@link InboundHttp2ToHttpAdapter} instance using this builders current settings.
|
||||||
|
*/
|
||||||
|
public InboundHttp2ToHttpAdapter build() {
|
||||||
|
InboundHttp2ToHttpAdapter instance = new InboundHttp2ToHttpAdapter(this);
|
||||||
|
connection.addListener(instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected InboundHttp2ToHttpAdapter(Builder builder) {
|
||||||
|
checkNotNull(builder.connection, "connection");
|
||||||
|
if (builder.maxContentLength <= 0) {
|
||||||
|
throw new IllegalArgumentException("maxContentLength must be a positive integer: "
|
||||||
|
+ builder.maxContentLength);
|
||||||
|
}
|
||||||
|
connection = builder.connection;
|
||||||
|
maxContentLength = builder.maxContentLength;
|
||||||
|
validateHttpHeaders = builder.validateHttpHeaders;
|
||||||
|
propagateSettings = builder.propagateSettings;
|
||||||
sendDetector = DEFAULT_SEND_DETECTOR;
|
sendDetector = DEFAULT_SEND_DETECTOR;
|
||||||
messageMap = new IntObjectHashMap<FullHttpMessage>();
|
messageMap = new IntObjectHashMap<FullHttpMessage>();
|
||||||
}
|
}
|
||||||
@ -318,6 +321,14 @@ public class InboundHttp2ToHttpAdapter extends Http2EventAdapter {
|
|||||||
processHeadersEnd(ctx, promisedStreamId, msg, false);
|
processHeadersEnd(ctx, promisedStreamId, msg, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSettingsRead(ChannelHandlerContext ctx, Http2Settings settings) throws Http2Exception {
|
||||||
|
if (propagateSettings) {
|
||||||
|
// Provide an interface for non-listeners to capture settings
|
||||||
|
ctx.fireChannelRead(settings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows messages to be sent up the pipeline before the next phase in the
|
* Allows messages to be sent up the pipeline before the next phase in the
|
||||||
* HTTP message flow is detected.
|
* HTTP message flow is detected.
|
||||||
|
@ -19,7 +19,6 @@ import java.util.Map.Entry;
|
|||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.handler.codec.AsciiString;
|
import io.netty.handler.codec.AsciiString;
|
||||||
import io.netty.handler.codec.TextHeaders.EntryVisitor;
|
import io.netty.handler.codec.TextHeaders.EntryVisitor;
|
||||||
import io.netty.handler.codec.TooLongFrameException;
|
|
||||||
import io.netty.handler.codec.http.DefaultHttpHeaders;
|
import io.netty.handler.codec.http.DefaultHttpHeaders;
|
||||||
import io.netty.handler.codec.http.FullHttpMessage;
|
import io.netty.handler.codec.http.FullHttpMessage;
|
||||||
import io.netty.handler.codec.http.HttpHeaders;
|
import io.netty.handler.codec.http.HttpHeaders;
|
||||||
@ -42,75 +41,27 @@ public final class InboundHttp2ToHttpPriorityAdapter extends InboundHttp2ToHttpA
|
|||||||
HttpUtil.OUT_OF_MESSAGE_SEQUENCE_RETURN_CODE.toString());
|
HttpUtil.OUT_OF_MESSAGE_SEQUENCE_RETURN_CODE.toString());
|
||||||
private final IntObjectMap<HttpHeaders> outOfMessageFlowHeaders;
|
private final IntObjectMap<HttpHeaders> outOfMessageFlowHeaders;
|
||||||
|
|
||||||
/**
|
public static final class Builder extends InboundHttp2ToHttpAdapter.Builder {
|
||||||
* Creates a new instance
|
|
||||||
*
|
/**
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
* Creates a new {@link InboundHttp2ToHttpPriorityAdapter} builder for the specified {@link Http2Connection}.
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
*
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
* @param connection The object which will provide connection notification events for the current connection
|
||||||
* @throws NullPointerException If {@code connection} is null
|
*/
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
public Builder(Http2Connection connection) {
|
||||||
*/
|
super(connection);
|
||||||
public static InboundHttp2ToHttpPriorityAdapter newInstance(Http2Connection connection, int maxContentLength) {
|
}
|
||||||
InboundHttp2ToHttpPriorityAdapter instance = new InboundHttp2ToHttpPriorityAdapter(connection,
|
|
||||||
maxContentLength);
|
@Override
|
||||||
connection.addListener(instance);
|
public InboundHttp2ToHttpPriorityAdapter build() {
|
||||||
return instance;
|
final InboundHttp2ToHttpPriorityAdapter instance = new InboundHttp2ToHttpPriorityAdapter(this);
|
||||||
|
instance.connection.addListener(instance);
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private InboundHttp2ToHttpPriorityAdapter(Builder builder) {
|
||||||
* Creates a new instance
|
super(builder);
|
||||||
*
|
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
|
||||||
* @param validateHttpHeaders
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} to validate HTTP headers in the http-codec</li>
|
|
||||||
* <li>{@code false} not to validate HTTP headers in the http-codec</li>
|
|
||||||
* </ul>
|
|
||||||
* @throws NullPointerException If {@code connection} is null
|
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
public static InboundHttp2ToHttpPriorityAdapter newInstance(Http2Connection connection, int maxContentLength,
|
|
||||||
boolean validateHttpHeaders) {
|
|
||||||
InboundHttp2ToHttpPriorityAdapter instance = new InboundHttp2ToHttpPriorityAdapter(connection,
|
|
||||||
maxContentLength, validateHttpHeaders);
|
|
||||||
connection.addListener(instance);
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance
|
|
||||||
*
|
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
|
||||||
* @throws NullPointerException If {@code connection} is null
|
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
private InboundHttp2ToHttpPriorityAdapter(Http2Connection connection, int maxContentLength) {
|
|
||||||
super(connection, maxContentLength);
|
|
||||||
outOfMessageFlowHeaders = new IntObjectHashMap<HttpHeaders>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new instance
|
|
||||||
*
|
|
||||||
* @param connection The object which will provide connection notification events for the current connection
|
|
||||||
* @param maxContentLength the maximum length of the message content. If the length of the message content exceeds
|
|
||||||
* this value, a {@link TooLongFrameException} will be raised.
|
|
||||||
* @param validateHttpHeaders
|
|
||||||
* <ul>
|
|
||||||
* <li>{@code true} to validate HTTP headers in the http-codec</li>
|
|
||||||
* <li>{@code false} not to validate HTTP headers in the http-codec</li>
|
|
||||||
* </ul>
|
|
||||||
* @throws NullPointerException If {@code connection} is null
|
|
||||||
* @throws IllegalArgumentException If {@code maxContentLength} is less than or equal to {@code 0}
|
|
||||||
*/
|
|
||||||
private InboundHttp2ToHttpPriorityAdapter(Http2Connection connection, int maxContentLength,
|
|
||||||
boolean validateHttpHeaders) {
|
|
||||||
super(connection, maxContentLength, validateHttpHeaders);
|
|
||||||
outOfMessageFlowHeaders = new IntObjectHashMap<HttpHeaders>();
|
outOfMessageFlowHeaders = new IntObjectHashMap<HttpHeaders>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +82,9 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private HttpResponseListener clientListener;
|
private HttpResponseListener clientListener;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HttpSettingsListener settingsListener;
|
||||||
|
|
||||||
private Http2FrameWriter frameWriter;
|
private Http2FrameWriter frameWriter;
|
||||||
private ServerBootstrap sb;
|
private ServerBootstrap sb;
|
||||||
private Bootstrap cb;
|
private Bootstrap cb;
|
||||||
@ -90,9 +93,11 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
private Channel clientChannel;
|
private Channel clientChannel;
|
||||||
private volatile CountDownLatch serverLatch;
|
private volatile CountDownLatch serverLatch;
|
||||||
private volatile CountDownLatch clientLatch;
|
private volatile CountDownLatch clientLatch;
|
||||||
|
private volatile CountDownLatch settingsLatch;
|
||||||
private int maxContentLength;
|
private int maxContentLength;
|
||||||
private HttpResponseDelegator serverDelegator;
|
private HttpResponseDelegator serverDelegator;
|
||||||
private HttpResponseDelegator clientDelegator;
|
private HttpResponseDelegator clientDelegator;
|
||||||
|
private HttpSettingsDelegator settingsDelegator;
|
||||||
private Http2Exception serverException;
|
private Http2Exception serverException;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@ -105,6 +110,7 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
maxContentLength = 1024;
|
maxContentLength = 1024;
|
||||||
setServerLatch(1);
|
setServerLatch(1);
|
||||||
setClientLatch(1);
|
setClientLatch(1);
|
||||||
|
setSettingsLatch(1);
|
||||||
frameWriter = new DefaultHttp2FrameWriter();
|
frameWriter = new DefaultHttp2FrameWriter();
|
||||||
|
|
||||||
sb = new ServerBootstrap();
|
sb = new ServerBootstrap();
|
||||||
@ -119,11 +125,18 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
Http2Connection connection = new DefaultHttp2Connection(true);
|
Http2Connection connection = new DefaultHttp2Connection(true);
|
||||||
p.addLast(
|
p.addLast(
|
||||||
"reader",
|
"reader",
|
||||||
new HttpAdapterFrameAdapter(connection, InboundHttp2ToHttpPriorityAdapter.newInstance(
|
new HttpAdapterFrameAdapter(connection,
|
||||||
connection, maxContentLength), new CountDownLatch(10)));
|
new InboundHttp2ToHttpPriorityAdapter.Builder(connection)
|
||||||
|
.maxContentLength(maxContentLength)
|
||||||
|
.validateHttpHeaders(true)
|
||||||
|
.propagateSettings(true)
|
||||||
|
.build(),
|
||||||
|
new CountDownLatch(10)));
|
||||||
serverDelegator = new HttpResponseDelegator(serverListener, serverLatch);
|
serverDelegator = new HttpResponseDelegator(serverListener, serverLatch);
|
||||||
p.addLast(serverDelegator);
|
p.addLast(serverDelegator);
|
||||||
serverConnectedChannel = ch;
|
serverConnectedChannel = ch;
|
||||||
|
settingsDelegator = new HttpSettingsDelegator(settingsListener, settingsLatch);
|
||||||
|
p.addLast(settingsDelegator);
|
||||||
p.addLast(new ChannelHandlerAdapter() {
|
p.addLast(new ChannelHandlerAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
||||||
@ -148,8 +161,11 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
Http2Connection connection = new DefaultHttp2Connection(false);
|
Http2Connection connection = new DefaultHttp2Connection(false);
|
||||||
p.addLast(
|
p.addLast(
|
||||||
"reader",
|
"reader",
|
||||||
new HttpAdapterFrameAdapter(connection, InboundHttp2ToHttpPriorityAdapter.newInstance(
|
new HttpAdapterFrameAdapter(connection,
|
||||||
connection, maxContentLength), new CountDownLatch(10)));
|
new InboundHttp2ToHttpPriorityAdapter.Builder(connection)
|
||||||
|
.maxContentLength(maxContentLength)
|
||||||
|
.build(),
|
||||||
|
new CountDownLatch(10)));
|
||||||
clientDelegator = new HttpResponseDelegator(clientListener, clientLatch);
|
clientDelegator = new HttpResponseDelegator(clientListener, clientLatch);
|
||||||
p.addLast(clientDelegator);
|
p.addLast(clientDelegator);
|
||||||
}
|
}
|
||||||
@ -663,6 +679,22 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void propagateSettings() throws Exception {
|
||||||
|
final Http2Settings settings = new Http2Settings().pushEnabled(true);
|
||||||
|
runInChannel(clientChannel, new Http2Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
frameWriter.writeSettings(ctxClient(), settings, newPromiseClient());
|
||||||
|
ctxClient().flush();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertTrue(settingsLatch.await(3, SECONDS));
|
||||||
|
ArgumentCaptor<Http2Settings> settingsCaptor = ArgumentCaptor.forClass(Http2Settings.class);
|
||||||
|
verify(settingsListener).messageReceived(settingsCaptor.capture());
|
||||||
|
assertEquals(settings, settingsCaptor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
private void cleanupCapturedRequests() {
|
private void cleanupCapturedRequests() {
|
||||||
if (capturedRequests != null) {
|
if (capturedRequests != null) {
|
||||||
for (int i = 0; i < capturedRequests.size(); ++i) {
|
for (int i = 0; i < capturedRequests.size(); ++i) {
|
||||||
@ -695,6 +727,13 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setSettingsLatch(int count) {
|
||||||
|
settingsLatch = new CountDownLatch(count);
|
||||||
|
if (settingsDelegator != null) {
|
||||||
|
settingsDelegator.latch(settingsLatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void awaitRequests() throws Exception {
|
private void awaitRequests() throws Exception {
|
||||||
assertTrue(serverLatch.await(2, SECONDS));
|
assertTrue(serverLatch.await(2, SECONDS));
|
||||||
}
|
}
|
||||||
@ -723,6 +762,10 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
void messageReceived(HttpObject obj);
|
void messageReceived(HttpObject obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private interface HttpSettingsListener {
|
||||||
|
void messageReceived(Http2Settings settings);
|
||||||
|
}
|
||||||
|
|
||||||
private static final class HttpResponseDelegator extends SimpleChannelInboundHandler<HttpObject> {
|
private static final class HttpResponseDelegator extends SimpleChannelInboundHandler<HttpObject> {
|
||||||
private final HttpResponseListener listener;
|
private final HttpResponseListener listener;
|
||||||
private volatile CountDownLatch latch;
|
private volatile CountDownLatch latch;
|
||||||
@ -744,6 +787,27 @@ public class InboundHttp2ToHttpAdapterTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class HttpSettingsDelegator extends SimpleChannelInboundHandler<Http2Settings> {
|
||||||
|
private final HttpSettingsListener listener;
|
||||||
|
private volatile CountDownLatch latch;
|
||||||
|
|
||||||
|
HttpSettingsDelegator(HttpSettingsListener listener, CountDownLatch latch) {
|
||||||
|
super(false);
|
||||||
|
this.listener = listener;
|
||||||
|
this.latch = latch;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void messageReceived(ChannelHandlerContext ctx, Http2Settings settings) throws Exception {
|
||||||
|
listener.messageReceived(settings);
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void latch(CountDownLatch latch) {
|
||||||
|
this.latch = latch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final class HttpAdapterFrameAdapter extends FrameAdapter {
|
private static final class HttpAdapterFrameAdapter extends FrameAdapter {
|
||||||
HttpAdapterFrameAdapter(Http2Connection connection, Http2FrameListener listener, CountDownLatch latch) {
|
HttpAdapterFrameAdapter(Http2Connection connection, Http2FrameListener listener, CountDownLatch latch) {
|
||||||
super(connection, listener, latch);
|
super(connection, listener, latch);
|
||||||
|
@ -71,7 +71,10 @@ public class Http2ClientInitializer extends ChannelInitializer<SocketChannel> {
|
|||||||
new DefaultHttp2InboundFlowController(connection, frameWriter),
|
new DefaultHttp2InboundFlowController(connection, frameWriter),
|
||||||
new DefaultHttp2OutboundFlowController(connection, frameWriter),
|
new DefaultHttp2OutboundFlowController(connection, frameWriter),
|
||||||
new DelegatingDecompressorFrameListener(connection,
|
new DelegatingDecompressorFrameListener(connection,
|
||||||
InboundHttp2ToHttpAdapter.newInstance(connection, maxContentLength)));
|
new InboundHttp2ToHttpAdapter.Builder(connection)
|
||||||
|
.maxContentLength(maxContentLength)
|
||||||
|
.propagateSettings(true)
|
||||||
|
.build()));
|
||||||
responseHandler = new HttpResponseHandler();
|
responseHandler = new HttpResponseHandler();
|
||||||
settingsHandler = new Http2SettingsHandler(ch.newPromise());
|
settingsHandler = new Http2SettingsHandler(ch.newPromise());
|
||||||
if (sslCtx != null) {
|
if (sslCtx != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user