我正在使用 Swift-NIO 为 iOS/tvOS 创建一个带有 TLS 的 Http/2 代理。我的代理启动:
var tlsConfiguration = ...
tlsConfiguration.applicationProtocols = NIOHTTP2SupportedALPNProtocols
let bootstrap = NIOTSListenerBootstrap(group: loopGroup)
.serverChannelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.serverChannelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEPORT), value: 1)
.childChannelInitializer { channel in
let sslContext: NIOSSLContext
let tlsHandler: NIOSSLServerHandler
do {
sslContext = try NIOSSLContext(configuration: tlsConfiguration)
tlsHandler = NIOSSLServerHandler(context: sslContext)
} catch {
print("[HTTP2PROXY] Could not configure TLS")
return channel.close(mode: .all)
}
return channel.pipeline.addHandler(tlsHandler, name: "TLS_Handler").flatMap {
print("[HTTP2PROXY] TLSHandler added to pipeline")
print("[HTTP2PROXY] Configuring pipeline for Http/1.1 and Http/2")
return channel.configureCommonHTTPServerPipeline(h2ConnectionChannelConfigurator: nil) { streamChannel in
return streamChannel.pipeline.addHandlers([DebugInboundEventsHandler(), DebugOutboundEventsHandler()]).flatMap {
print("[HTTP2PROXY] Event debugger handlers added")
return streamChannel.pipeline.addHandler(HTTPResponseCompressor(), name: "ResponseCompressor")
}.flatMap {
print("[HTTP2PROXY] HTTPResponseCompressor added to pipeline")
return streamChannel.pipeline.addHandler(CustomHttp1Handler(hlsRequestHandler: self.hlsRequestHandler), name: "Custom_Http1")
}.flatMap {
print("[HTTP2PROXY] Custom Http1Handler added to pipeline")
return streamChannel.pipeline.addHandler(ErrorHandler())
}
}
}
}
.childChannelOption(ChannelOptions.socket(IPPROTO_TCP, TCP_NODELAY), value: 1)
.childChannelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEADDR), value: 1)
.childChannelOption(ChannelOptions.socket(SocketOptionLevel(SOL_SOCKET), SO_REUSEPORT), value: 1)
do {
let serverChannel = try bootstrap.bind(host: Http2Proxy.host, port: Http2Proxy.port).wait()
print("[HTTP2PROXY] Server Channel bound to: \(serverChannel.localAddress!)")
}
catch {
try! loopGroup.syncShutdownGracefully()
print("[HTTP2PROXY] Failed to start channel: \(error)")
}
服务器使用 Https over Http/2 正确工作和处理请求,甚至在被询问时 gzip 响应。那太好了。但是在日志中,我看到对于每个传入的请求,都在重新配置管道(即一遍又一遍地调用附加处理程序的转义)。这是它应该工作的方式吗?据我所知,我不会在任何地方关闭上下文/频道。这个代理是否为每个请求设置了一个新的管道,因此我是否错过了通过同一通道(和管道)发送大量请求的 Http/2 方法?或者这实际上是它应该工作的方式?感觉不是最理想的结果...
日志:
10:21:15.760 [HTTP2PROXY] Server Channel bound to: [IPv4]127.0.0.1/127.0.0.1:50001
10:22:47.813 [HTTP2PROXY] TLSHandler added to pipeline
10:22:47.813 [HTTP2PROXY] Configuring pipeline for Http/1.1 and Http/2
10:22:47.837 [HTTP2PROXY] Event debugger handlers added
10:22:47.838 [HTTP2PROXY] HTTPResponseCompressor added to pipeline
10:22:47.838 [HTTP2PROXY] Custom Http1Handler added to pipeline
10:22:47.853 [HTTP2PROXY] Event debugger handlers added
10:22:47.853 [HTTP2PROXY] HTTPResponseCompressor added to pipeline
10:22:47.853 [HTTP2PROXY] Custom Http1Handler added to pipeline
10:22:47.854 [HTTP2PROXY] Event debugger handlers added
10:22:47.854 [HTTP2PROXY] HTTPResponseCompressor added to pipeline
10:22:47.854 [HTTP2PROXY] Custom Http1Handler added to pipeline
10:22:47.860 [HTTP2PROXY] Event debugger handlers added
10:22:47.860 [HTTP2PROXY] HTTPResponseCompressor added to pipeline
10:22:47.860 [HTTP2PROXY] Custom Http1Handler added to pipeline
10:22:47.861 [HTTP2PROXY] Event debugger handlers added
10:22:47.861 [HTTP2PROXY] HTTPResponseCompressor added to pipeline
10:22:47.861 [HTTP2PROXY] Custom Http1Handler added to pipeline
10:22:47.927 [HTTP2PROXY] Event debugger handlers added
10:22:47.927 [HTTP2PROXY] HTTPResponseCompressor added to pipeline
10:22:47.927 [HTTP2PROXY] Custom Http1Handler added to pipeline
记录 context.channel.pipeline.debugDescription 给出:
10:30:41.083 [HTTP2PROXY] Pipeline config:
ChannelPipeline[ObjectIdentifier(0x00000002804d6fd0)]:
[I] ↓↑ [O]
HTTP2FramePayloadToHTTP1ServerCodec ↓↑ HTTP2FramePayloadToHTTP1ServerCodec [handler0]
HTTPResponseCompressor ↓↑ HTTPResponseCompressor [ResponseCompressor]
CustomHttp1Handler ↓↑ [Custom_Http1]
ErrorHandler ↓↑ [handler1]
10:30:41.087 [HTTP2PROXY] Pipeline config:
ChannelPipeline[ObjectIdentifier(0x00000002804d7160)]:
[I] ↓↑ [O]
HTTP2FramePayloadToHTTP1ServerCodec ↓↑ HTTP2FramePayloadToHTTP1ServerCodec [handler0]
HTTPResponseCompressor ↓↑ HTTPResponseCompressor [ResponseCompressor]
CustomHttp1Handler ↓↑ [Custom_Http1]
ErrorHandler ↓↑ [handler1]
10:30:41.090 [HTTP2PROXY] Pipeline config:
ChannelPipeline[ObjectIdentifier(0x00000002804d7610)]:
[I] ↓↑ [O]
HTTP2FramePayloadToHTTP1ServerCodec ↓↑ HTTP2FramePayloadToHTTP1ServerCodec [handler0]
HTTPResponseCompressor ↓↑ HTTPResponseCompressor [ResponseCompressor]
CustomHttp1Handler ↓↑ [Custom_Http1]
ErrorHandler ↓↑ [handler1]
10:30:41.100 [HTTP2PROXY] Pipeline config:
ChannelPipeline[ObjectIdentifier(0x00000002804d71b0)]:
[I] ↓↑ [O]
HTTP2FramePayloadToHTTP1ServerCodec ↓↑ HTTP2FramePayloadToHTTP1ServerCodec [handler0]
HTTPResponseCompressor ↓↑ HTTPResponseCompressor [ResponseCompressor]
CustomHttp1Handler ↓↑ [Custom_Http1]
ErrorHandler ↓↑ [handler1]
所以管道的objectIdentifier每次都不一样...