Don't replace all 'connection' headers when sending h2c upgrade request (#7824)

Motivation:

There may be meaningful 'connection' headers that exist on a request
that is used to attempt a HTTP/1.x upgrade request that will be
clobbered.

Modifications:

HttpClientUpgradeHandler uses the `HttpHeaders.add` instead of
`HttpHeaders.set` when adding the 'upgrade' field.

Result:

Fixes #7823, existing 'connection' headers are preserved.
This commit is contained in:
Bryce Anderson 2018-04-01 11:59:30 -06:00 committed by Norman Maurer
parent 602ee5444d
commit 741602050f
2 changed files with 23 additions and 1 deletions

View File

@ -277,6 +277,6 @@ public class HttpClientUpgradeHandler extends HttpObjectAggregator implements Ch
builder.append(',');
}
builder.append(HttpHeaderValues.UPGRADE);
request.headers().set(HttpHeaderNames.CONNECTION, builder.toString());
request.headers().add(HttpHeaderNames.CONNECTION, builder.toString());
}
}

View File

@ -21,6 +21,7 @@ import io.netty.channel.embedded.EmbeddedChannel;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
@ -174,4 +175,25 @@ public class HttpClientUpgradeHandlerTest {
assertEquals(HttpResponseStatus.OK, response.status());
assertFalse(channel.finish());
}
@Test
public void dontStripConnectionHeaders() {
HttpClientUpgradeHandler.SourceCodec sourceCodec = new FakeSourceCodec();
HttpClientUpgradeHandler.UpgradeCodec upgradeCodec = new FakeUpgradeCodec();
HttpClientUpgradeHandler handler = new HttpClientUpgradeHandler(sourceCodec, upgradeCodec, 1024);
UserEventCatcher catcher = new UserEventCatcher();
EmbeddedChannel channel = new EmbeddedChannel(catcher);
channel.pipeline().addFirst("upgrade", handler);
DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "netty.io");
request.headers().add("connection", "extra");
request.headers().add("extra", "value");
assertTrue(channel.writeOutbound(request));
FullHttpRequest readRequest = channel.readOutbound();
List<String> connectionHeaders = readRequest.headers().getAll("connection");
assertTrue(connectionHeaders.contains("extra"));
assertTrue(readRequest.release());
assertFalse(channel.finish());
}
}