@@ -120,14 +120,15 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
120
120
private enum InboundStreamMultiplexerState {
121
121
case uninitializedLegacy
122
122
case uninitializedInline( StreamConfiguration , StreamInitializer , NIOHTTP2StreamDelegate ? )
123
+ case uninitializedAsync( StreamConfiguration , StreamInitializerWithAnyOutput , NIOHTTP2StreamDelegate ? )
123
124
case initialized( InboundStreamMultiplexer )
124
125
case deinitialized
125
126
126
127
internal var multiplexer : InboundStreamMultiplexer ? {
127
128
switch self {
128
129
case . initialized( let inboundStreamMultiplexer) :
129
130
return inboundStreamMultiplexer
130
- case . uninitializedLegacy, . uninitializedInline, . deinitialized:
131
+ case . uninitializedLegacy, . uninitializedInline, . uninitializedAsync , . deinitialized:
131
132
return nil
132
133
}
133
134
}
@@ -153,6 +154,20 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
153
154
)
154
155
) )
155
156
157
+ case . uninitializedAsync( let streamConfiguration, let inboundStreamInitializer, let streamDelegate) :
158
+ self = . initialized( . inline(
159
+ InlineStreamMultiplexer (
160
+ context: context,
161
+ outboundView: . init( http2Handler: http2Handler) ,
162
+ mode: mode,
163
+ inboundStreamStateInitializer: . returnsAny( inboundStreamInitializer) ,
164
+ targetWindowSize: max ( 0 , min ( streamConfiguration. targetWindowSize, Int ( Int32 . max) ) ) ,
165
+ streamChannelOutboundBytesHighWatermark: streamConfiguration. outboundBufferSizeHighWatermark,
166
+ streamChannelOutboundBytesLowWatermark: streamConfiguration. outboundBufferSizeLowWatermark,
167
+ streamDelegate: streamDelegate
168
+ )
169
+ ) )
170
+
156
171
case . initialized:
157
172
break //no-op
158
173
}
@@ -989,9 +1004,13 @@ extension NIOHTTP2Handler {
989
1004
#if swift(>=5.7)
990
1005
/// The type of all `inboundStreamInitializer` callbacks which do not need to return data.
991
1006
public typealias StreamInitializer = NIOChannelInitializer
1007
+ /// The type of NIO Channel initializer callbacks which need to return untyped data.
1008
+ internal typealias StreamInitializerWithAnyOutput = @Sendable ( Channel ) -> EventLoopFuture < any Sendable >
992
1009
#else
993
1010
/// The type of all `inboundStreamInitializer` callbacks which need to return data.
994
1011
public typealias StreamInitializer = NIOChannelInitializer
1012
+ /// The type of NIO Channel initializer callbacks which need to return untyped data.
1013
+ internal typealias StreamInitializerWithAnyOutput = ( Channel ) -> EventLoopFuture < any Sendable >
995
1014
#endif
996
1015
997
1016
/// Creates a new ``NIOHTTP2Handler`` with a local multiplexer. (i.e. using
@@ -1014,17 +1033,39 @@ extension NIOHTTP2Handler {
1014
1033
streamDelegate: NIOHTTP2StreamDelegate ? = nil ,
1015
1034
inboundStreamInitializer: @escaping StreamInitializer
1016
1035
) {
1017
- self . init ( mode: mode,
1018
- eventLoop: eventLoop,
1019
- initialSettings: connectionConfiguration. initialSettings,
1020
- headerBlockValidation: connectionConfiguration. headerBlockValidation,
1021
- contentLengthValidation: connectionConfiguration. contentLengthValidation,
1022
- maximumSequentialEmptyDataFrames: connectionConfiguration. maximumSequentialEmptyDataFrames,
1023
- maximumBufferedControlFrames: connectionConfiguration. maximumBufferedControlFrames
1036
+ self . init (
1037
+ mode: mode,
1038
+ eventLoop: eventLoop,
1039
+ initialSettings: connectionConfiguration. initialSettings,
1040
+ headerBlockValidation: connectionConfiguration. headerBlockValidation,
1041
+ contentLengthValidation: connectionConfiguration. contentLengthValidation,
1042
+ maximumSequentialEmptyDataFrames: connectionConfiguration. maximumSequentialEmptyDataFrames,
1043
+ maximumBufferedControlFrames: connectionConfiguration. maximumBufferedControlFrames
1024
1044
)
1045
+
1025
1046
self . inboundStreamMultiplexerState = . uninitializedInline( streamConfiguration, inboundStreamInitializer, streamDelegate)
1026
1047
}
1027
1048
1049
+ internal convenience init (
1050
+ mode: ParserMode ,
1051
+ eventLoop: EventLoop ,
1052
+ connectionConfiguration: ConnectionConfiguration = . init( ) ,
1053
+ streamConfiguration: StreamConfiguration = . init( ) ,
1054
+ streamDelegate: NIOHTTP2StreamDelegate ? = nil ,
1055
+ inboundStreamInitializerWithAnyOutput: @escaping StreamInitializerWithAnyOutput
1056
+ ) {
1057
+ self . init (
1058
+ mode: mode,
1059
+ eventLoop: eventLoop,
1060
+ initialSettings: connectionConfiguration. initialSettings,
1061
+ headerBlockValidation: connectionConfiguration. headerBlockValidation,
1062
+ contentLengthValidation: connectionConfiguration. contentLengthValidation,
1063
+ maximumSequentialEmptyDataFrames: connectionConfiguration. maximumSequentialEmptyDataFrames,
1064
+ maximumBufferedControlFrames: connectionConfiguration. maximumBufferedControlFrames
1065
+ )
1066
+ self . inboundStreamMultiplexerState = . uninitializedAsync( streamConfiguration, inboundStreamInitializerWithAnyOutput, streamDelegate)
1067
+ }
1068
+
1028
1069
/// Connection-level configuration.
1029
1070
///
1030
1071
/// The settings that will be used when establishing the connection. These will be sent to the peer as part of the
@@ -1101,7 +1142,7 @@ extension NIOHTTP2Handler {
1101
1142
}
1102
1143
1103
1144
@available ( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * )
1104
- internal func syncAsyncStreamMultiplexer< Output> ( continuation: any ChannelContinuation , inboundStreamChannels: NIOHTTP2InboundStreamChannels < Output > ) throws -> AsyncStreamMultiplexer < Output > {
1145
+ internal func syncAsyncStreamMultiplexer< Output: Sendable > ( continuation: any AnyContinuation , inboundStreamChannels: NIOHTTP2InboundStreamChannels < Output > ) throws -> AsyncStreamMultiplexer < Output > {
1105
1146
self . eventLoop!. preconditionInEventLoop ( )
1106
1147
1107
1148
switch self . inboundStreamMultiplexer {
0 commit comments