Skip to content

Commit

Permalink
Add HttpScheme Support in HttpToHttp2ConnectionHandler (netty#10641)
Browse files Browse the repository at this point in the history
Motivation:
We should have a method to add `HttpScheme` if `HttpRequest` does not contain `x-http2-scheme` then we should use add it if `HttpToHttp2ConnectionHandler` is build using specified `HttpScheme`.

Modification:
Added `HttpScheme` in `HttpToHttp2ConnectionHandlerBuilder`.

Result:
Automatically add `HttpScheme` if missing in `HttpRequest`.
  • Loading branch information
hyperxpro authored and 夏无影 committed Jul 8, 2022
1 parent 5fd96ef commit ffd360d
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import io.netty.handler.codec.http.HttpContent;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMessage;
import io.netty.handler.codec.http.HttpScheme;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator;
import io.netty.util.ReferenceCountUtil;
Expand All @@ -38,6 +39,7 @@ public class HttpToHttp2ConnectionHandler extends Http2ConnectionHandler {

private final boolean validateHeaders;
private int currentStreamId;
private HttpScheme httpScheme;

protected HttpToHttp2ConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings, boolean validateHeaders) {
Expand All @@ -48,8 +50,15 @@ protected HttpToHttp2ConnectionHandler(Http2ConnectionDecoder decoder, Http2Conn
protected HttpToHttp2ConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings, boolean validateHeaders,
boolean decoupleCloseAndGoAway) {
this(decoder, encoder, initialSettings, validateHeaders, decoupleCloseAndGoAway, null);
}

protected HttpToHttp2ConnectionHandler(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings, boolean validateHeaders,
boolean decoupleCloseAndGoAway, HttpScheme httpScheme) {
super(decoder, encoder, initialSettings, decoupleCloseAndGoAway);
this.validateHeaders = validateHeaders;
this.httpScheme = httpScheme;
}

/**
Expand Down Expand Up @@ -87,6 +96,12 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise)
// Provide the user the opportunity to specify the streamId
currentStreamId = getStreamId(httpMsg.headers());

// Add HttpScheme if it's defined in constructor and header does not contain it.
if (httpScheme != null &&
!httpMsg.headers().contains(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text())) {
httpMsg.headers().set(HttpConversionUtil.ExtensionHeaderNames.SCHEME.text(), httpScheme.name());
}

// Convert and write the headers.
Http2Headers http2Headers = HttpConversionUtil.toHttp2Headers(httpMsg, validateHeaders);
endStream = msg instanceof FullHttpMessage && !((FullHttpMessage) msg).content().isReadable();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package io.netty.handler.codec.http2;

import io.netty.handler.codec.http.HttpScheme;
import io.netty.handler.codec.http2.Http2HeadersEncoder.SensitivityDetector;
import io.netty.util.internal.UnstableApi;

Expand All @@ -26,6 +27,8 @@
public final class HttpToHttp2ConnectionHandlerBuilder extends
AbstractHttp2ConnectionHandlerBuilder<HttpToHttp2ConnectionHandler, HttpToHttp2ConnectionHandlerBuilder> {

private HttpScheme httpScheme;

@Override
public HttpToHttp2ConnectionHandlerBuilder validateHeaders(boolean validateHeaders) {
return super.validateHeaders(validateHeaders);
Expand Down Expand Up @@ -58,7 +61,7 @@ public HttpToHttp2ConnectionHandlerBuilder connection(Http2Connection connection

@Override
public HttpToHttp2ConnectionHandlerBuilder codec(Http2ConnectionDecoder decoder,
Http2ConnectionEncoder encoder) {
Http2ConnectionEncoder encoder) {
return super.codec(decoder, encoder);
}

Expand Down Expand Up @@ -90,6 +93,17 @@ public HttpToHttp2ConnectionHandlerBuilder decoupleCloseAndGoAway(boolean decoup
return super.decoupleCloseAndGoAway(decoupleCloseAndGoAway);
}

/**
* Add {@code scheme} in {@link Http2Headers} if not already present.
*
* @param httpScheme {@link HttpScheme} type
* @return {@code this}.
*/
public HttpToHttp2ConnectionHandlerBuilder httpScheme(HttpScheme httpScheme) {
this.httpScheme = httpScheme;
return self();
}

@Override
public HttpToHttp2ConnectionHandler build() {
return super.build();
Expand All @@ -99,6 +113,6 @@ public HttpToHttp2ConnectionHandler build() {
protected HttpToHttp2ConnectionHandler build(Http2ConnectionDecoder decoder, Http2ConnectionEncoder encoder,
Http2Settings initialSettings) {
return new HttpToHttp2ConnectionHandler(decoder, encoder, initialSettings, isValidateHeaders(),
decoupleCloseAndGoAway());
decoupleCloseAndGoAway(), httpScheme);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpScheme;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http2.Http2TestUtil.FrameCountDown;
import io.netty.util.AsciiString;
Expand Down Expand Up @@ -147,6 +148,29 @@ public void testHeadersOnlyRequest() throws Exception {
verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise));
}

@Test
public void testHttpScheme() throws Exception {
bootstrapEnv(2, 1, 0);
final FullHttpRequest request = new DefaultFullHttpRequest(HTTP_1_1, GET,
"http://my-user_name@www.example.org:5555/example");
final HttpHeaders httpHeaders = request.headers();
httpHeaders.setInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text(), 5);
httpHeaders.set(HttpHeaderNames.HOST, "my-user_name@www.example.org:5555");
httpHeaders.add(of("foo"), of("goo"));
httpHeaders.add(of("foo"), of("goo2"));
httpHeaders.add(of("foo2"), of("goo2"));
final Http2Headers http2Headers =
new DefaultHttp2Headers().method(new AsciiString("GET")).path(new AsciiString("/example"))
.authority(new AsciiString("www.example.org:5555")).scheme(new AsciiString("http"))
.scheme(new AsciiString("http"))
.add(new AsciiString("foo"), new AsciiString("goo"))
.add(new AsciiString("foo"), new AsciiString("goo2"))
.add(new AsciiString("foo2"), new AsciiString("goo2"));

ChannelPromise writePromise = newPromise();
verifyHeadersOnly(http2Headers, writePromise, clientChannel.writeAndFlush(request, writePromise));
}

@Test
public void testMultipleCookieEntriesAreCombined() throws Exception {
bootstrapEnv(2, 1, 0);
Expand Down Expand Up @@ -520,6 +544,7 @@ protected void initChannel(Channel ch) throws Exception {
p.addLast(new HttpToHttp2ConnectionHandlerBuilder()
.server(true)
.frameListener(serverFrameCountDown)
.httpScheme(HttpScheme.HTTP)
.build());
serverChannelLatch.countDown();
}
Expand Down

0 comments on commit ffd360d

Please sign in to comment.