@@ -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 been 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,11 @@ extension NIOHTTP2Handler {
10671098 return
10681099 }
10691100
1101+ // Tell the delegate, if there is one.
1102+ if let delegate = self . frameDelegate {
1103+ delegate. wroteFrame ( frame)
1104+ }
1105+
10701106 // Ok, if we got here we're good to send data. We want to attach the promise to the latest write, not
10711107 // always the frame header.
10721108 self . wroteFrame = true
@@ -1391,7 +1427,8 @@ extension NIOHTTP2Handler {
13911427 maximumResetFrameCount: streamConfiguration. streamResetFrameRateLimit. maximumCount,
13921428 resetFrameCounterWindow: streamConfiguration. streamResetFrameRateLimit. windowLength,
13931429 maximumStreamErrorCount: streamConfiguration. streamErrorRateLimit. maximumCount,
1394- streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength
1430+ streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength,
1431+ frameDelegate: nil
13951432 )
13961433
13971434 self . inboundStreamMultiplexerState = . uninitializedInline(
@@ -1408,6 +1445,7 @@ extension NIOHTTP2Handler {
14081445 connectionConfiguration: ConnectionConfiguration = . init( ) ,
14091446 streamConfiguration: StreamConfiguration = . init( ) ,
14101447 streamDelegate: NIOHTTP2StreamDelegate ? = nil ,
1448+ frameDelegate: NIOHTTP2FrameDelegate ? ,
14111449 inboundStreamInitializerWithAnyOutput: @escaping StreamInitializerWithAnyOutput
14121450 ) {
14131451 self . init (
@@ -1424,7 +1462,8 @@ extension NIOHTTP2Handler {
14241462 maximumResetFrameCount: streamConfiguration. streamResetFrameRateLimit. maximumCount,
14251463 resetFrameCounterWindow: streamConfiguration. streamResetFrameRateLimit. windowLength,
14261464 maximumStreamErrorCount: streamConfiguration. streamErrorRateLimit. maximumCount,
1427- streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength
1465+ streamErrorCounterWindow: streamConfiguration. streamErrorRateLimit. windowLength,
1466+ frameDelegate: frameDelegate
14281467 )
14291468 self . inboundStreamMultiplexerState = . uninitializedAsync(
14301469 streamConfiguration,
0 commit comments