@@ -113,6 +113,9 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
113113 /// The maximum number of sequential CONTINUATION frames.
114114 private let maximumSequentialContinuationFrames : Int
115115
116+ /// A delegate which is told about frames which have eebn written.
117+ private let frameDelegate : NIOHTTP2FrameDelegate ?
118+
116119 @usableFromInline
117120 internal var inboundStreamMultiplexer : InboundStreamMultiplexer ? {
118121 self . inboundStreamMultiplexerState. multiplexer
@@ -242,7 +245,8 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
242245 maximumResetFrameCount: 200 ,
243246 resetFrameCounterWindow: . seconds( 30 ) ,
244247 maximumStreamErrorCount: 200 ,
245- streamErrorCounterWindow: . seconds( 30 )
248+ streamErrorCounterWindow: . seconds( 30 ) ,
249+ frameDelegate: nil
246250 )
247251 }
248252
@@ -280,7 +284,8 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
280284 maximumResetFrameCount: 200 ,
281285 resetFrameCounterWindow: . seconds( 30 ) ,
282286 maximumStreamErrorCount: 200 ,
283- streamErrorCounterWindow: . seconds( 30 )
287+ streamErrorCounterWindow: . seconds( 30 ) ,
288+ frameDelegate: nil
284289 )
285290
286291 }
@@ -295,6 +300,27 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
295300 mode: ParserMode ,
296301 connectionConfiguration: ConnectionConfiguration = . init( ) ,
297302 streamConfiguration: StreamConfiguration = . init( )
303+ ) {
304+ self . init (
305+ mode: mode,
306+ frameDelegate: nil ,
307+ connectionConfiguration: connectionConfiguration,
308+ streamConfiguration: streamConfiguration
309+ )
310+ }
311+
312+ /// Constructs a ``NIOHTTP2Handler``.
313+ ///
314+ /// - Parameters:
315+ /// - mode: The mode for this handler, client or server.
316+ /// - frameDelegate: A delegate which is notified about frames being written.
317+ /// - connectionConfiguration: The settings that will be used when establishing the connection.
318+ /// - streamConfiguration: The settings that will be used when establishing new streams.
319+ public convenience init (
320+ mode: ParserMode ,
321+ frameDelegate: NIOHTTP2FrameDelegate ? ,
322+ connectionConfiguration: ConnectionConfiguration = ConnectionConfiguration ( ) ,
323+ streamConfiguration: StreamConfiguration = StreamConfiguration ( )
298324 ) {
299325 self . init (
300326 mode: mode,
@@ -310,7 +336,8 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
310336 maximumResetFrameCount: streamConfiguration. streamResetFrameRateLimit. maximumCount,
311337 resetFrameCounterWindow: streamConfiguration. streamResetFrameRateLimit. windowLength,
312338 maximumStreamErrorCount: streamConfiguration. streamErrorRateLimit. maximumCount,
313- streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength
339+ streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength,
340+ frameDelegate: frameDelegate
314341 )
315342 }
316343
@@ -328,7 +355,8 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
328355 maximumResetFrameCount: Int ,
329356 resetFrameCounterWindow: TimeAmount ,
330357 maximumStreamErrorCount: Int ,
331- streamErrorCounterWindow: TimeAmount
358+ streamErrorCounterWindow: TimeAmount ,
359+ frameDelegate: NIOHTTP2FrameDelegate ?
332360 ) {
333361 self . _eventLoop = eventLoop
334362 self . stateMachine = HTTP2ConnectionStateMachine (
@@ -355,6 +383,7 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
355383 self . inboundStreamMultiplexerState = . uninitializedLegacy
356384 self . maximumSequentialContinuationFrames = maximumSequentialContinuationFrames
357385 self . glitchesMonitor = GlitchesMonitor ( maximumGlitches: maximumConnectionGlitches)
386+ self . frameDelegate = frameDelegate
358387 }
359388
360389 /// Constructs a ``NIOHTTP2Handler``.
@@ -391,7 +420,8 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
391420 resetFrameCounterWindow: TimeAmount = . seconds( 30 ) ,
392421 maximumStreamErrorCount: Int = 200 ,
393422 streamErrorCounterWindow: TimeAmount = . seconds( 30 ) ,
394- maximumConnectionGlitches: Int = GlitchesMonitor . defaultMaximumGlitches
423+ maximumConnectionGlitches: Int = GlitchesMonitor . defaultMaximumGlitches,
424+ frameDelegate: NIOHTTP2FrameDelegate ? = nil
395425 ) {
396426 self . stateMachine = HTTP2ConnectionStateMachine (
397427 role: . init( mode) ,
@@ -418,6 +448,7 @@ public final class NIOHTTP2Handler: ChannelDuplexHandler {
418448 self . inboundStreamMultiplexerState = . uninitializedLegacy
419449 self . maximumSequentialContinuationFrames = maximumSequentialContinuationFrames
420450 self . glitchesMonitor = GlitchesMonitor ( maximumGlitches: maximumConnectionGlitches)
451+ self . frameDelegate = frameDelegate
421452 }
422453
423454 public func handlerAdded( context: ChannelHandlerContext ) {
@@ -1067,6 +1098,24 @@ extension NIOHTTP2Handler {
10671098 return
10681099 }
10691100
1101+ // Tell the delegate, if there is one.
1102+ if let delegate = self . frameDelegate {
1103+ switch frame. payload {
1104+ case . headers( let headers) :
1105+ delegate. wroteHeaders ( headers. headers, endStream: headers. endStream, streamID: frame. streamID)
1106+
1107+ case . data( let data) :
1108+ switch data. data {
1109+ case . byteBuffer( let buffer) :
1110+ delegate. wroteData ( buffer, endStream: data. endStream, streamID: frame. streamID)
1111+ case . fileRegion:
1112+ ( )
1113+ }
1114+ default :
1115+ ( )
1116+ }
1117+ }
1118+
10701119 // Ok, if we got here we're good to send data. We want to attach the promise to the latest write, not
10711120 // always the frame header.
10721121 self . wroteFrame = true
@@ -1391,7 +1440,8 @@ extension NIOHTTP2Handler {
13911440 maximumResetFrameCount: streamConfiguration. streamResetFrameRateLimit. maximumCount,
13921441 resetFrameCounterWindow: streamConfiguration. streamResetFrameRateLimit. windowLength,
13931442 maximumStreamErrorCount: streamConfiguration. streamErrorRateLimit. maximumCount,
1394- streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength
1443+ streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength,
1444+ frameDelegate: nil
13951445 )
13961446
13971447 self . inboundStreamMultiplexerState = . uninitializedInline(
@@ -1408,6 +1458,7 @@ extension NIOHTTP2Handler {
14081458 connectionConfiguration: ConnectionConfiguration = . init( ) ,
14091459 streamConfiguration: StreamConfiguration = . init( ) ,
14101460 streamDelegate: NIOHTTP2StreamDelegate ? = nil ,
1461+ frameDelegate: NIOHTTP2FrameDelegate ? ,
14111462 inboundStreamInitializerWithAnyOutput: @escaping StreamInitializerWithAnyOutput
14121463 ) {
14131464 self . init (
@@ -1424,7 +1475,8 @@ extension NIOHTTP2Handler {
14241475 maximumResetFrameCount: streamConfiguration. streamResetFrameRateLimit. maximumCount,
14251476 resetFrameCounterWindow: streamConfiguration. streamResetFrameRateLimit. windowLength,
14261477 maximumStreamErrorCount: streamConfiguration. streamErrorRateLimit. maximumCount,
1427- streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength
1478+ streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength,
1479+ frameDelegate: frameDelegate
14281480 )
14291481 self . inboundStreamMultiplexerState = . uninitializedAsync(
14301482 streamConfiguration,
0 commit comments