概述
Http2UpgradeHandler按照HTTP/2协议规范处理http/2 stream,处理流程如下:
- 解析HTTP2-Setting头部域
- 处理客户端发送的连接前言(connection preface)
- 发送连接前言给客户端
- 在Endpoint的WorkThread线程池中,处理stream
Http2UpgradeHandler#init()方法
不了解从何处开始调用Http2UpgradeHandler#init()的朋友可参阅tomcat9.0源码分析之NioEndpoint(二)—— Http11Processor
传入的参数是UpgeadeProcessorInternal
@Override
public void init(WebConnection webConnection) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("upgradeHandler.init", connectionId, connectionState.get()));
}
if (!connectionState.compareAndSet(ConnectionState.NEW, ConnectionState.CONNECTED)) {
return;
}
// Init concurrency control if needed
if (protocol.getMaxConcurrentStreamExecution() < localSettings.getMaxConcurrentStreams()) {
streamConcurrency = new AtomicInteger(0);
queuedRunnable = new ConcurrentLinkedQueue<>();
}
parser = getParser(connectionId);
Stream stream = null;
socketWrapper.setReadTimeout(protocol.getReadTimeout());
socketWrapper.setWriteTimeout(protocol.getWriteTimeout());
//如果UpgeadeProcessorInternal不为null
if (webConnection != null) {
// HTTP/2 started via HTTP upgrade.
// The initial HTTP/1.1 request is available as Stream 1.
try {
// Process the initial settings frame
//处理setting frame
stream = getStream(1, true);
//读取请求头的Http2-setting参数
String base64Settings = stream.getCoyoteRequest().getHeader(HTTP2_SETTINGS_HEADER);
byte[] settings = Base64.decodeBase64(base64Settings);
// Settings are only valid on stream 0
FrameType.SETTINGS.check(0, settings.length);
for (int i = 0; i < settings.length % 6; i++) {
int id = ByteUtil.getTwoBytes(settings, i * 6);
long value = ByteUtil.getFourBytes(settings, (i * 6) + 2);
remoteSettings.set(Setting.valueOf(id), value);
}
}