主要添加一些升级的 Hanlder 到 pipeline 头, 主要由 HttpClientUpgradeHandler 完成
static final class Http2UpgradeAndGrpcHandler extends ChannelInboundHandlerAdapter {
private final String authority;
private final GrpcHttp2ConnectionHandler next;
private ProtocolNegotiationEvent pne;
Http2UpgradeAndGrpcHandler(String authority, GrpcHttp2ConnectionHandler next) {
this.authority = checkNotNull(authority, "authority");
this.next = checkNotNull(next, "next");
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
negotiationLogger(ctx).log(ChannelLogLevel.INFO, "Http2Upgrade started");
HttpClientCodec httpClientCodec = new HttpClientCodec();
ctx.pipeline().addBefore(ctx.name(), null, httpClientCodec);
Http2ClientUpgradeCodec upgradeCodec = new Http2ClientUpgradeCodec(next);
HttpClientUpgradeHandler upgrader =
new HttpClientUpgradeHandler(httpClientCodec, upgradeCodec, /*maxContentLength=*/ 1000);
ctx.pipeline().addBefore(ctx.name(), null, upgrader);
// Trigger the HTTP/1.1 plaintext upgrade protocol by issuing an HTTP request
// which causes the upgrade headers to be added
DefaultHttpRequest upgradeTrigger =
new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");
upgradeTrigger.headers().add(HttpHeaderNames.HOST, authority);
ctx.writeAndFlush(upgradeTrigger).addListener(
ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
super.handlerAdded(ctx);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof ProtocolNegotiationEvent) {
checkState(pne == null, "negotiation already started");
pne = (ProtocolNegotiationEvent) evt;
} else if (evt == HttpClientUpgradeHandler.UpgradeEvent.UPGRADE_SUCCESSFUL) {
checkState(pne != null, "negotiation not yet complete");
negotiationLogger(ctx).log(ChannelLogLevel.INFO, "Http2Upgrade finished");
ctx.pipeline().remove(ctx.name());
next.handleProtocolNegotiationCompleted(pne.getAttributes(), pne.getSecurity());
} else if (evt == HttpClientUpgradeHandler.UpgradeEvent.UPGRADE_REJECTED) {
ctx.fireExceptionCaught(unavailableException("HTTP/2 upgrade rejected"));
} else {
super.userEventTriggered(ctx, evt);
}
}
}