@@ -605,6 +605,10 @@ final class HTTP2StreamChannel: Channel, ChannelCore, @unchecked Sendable {
605
605
}
606
606
607
607
public func close0( error: Error , mode: CloseMode , promise: EventLoopPromise < Void > ? ) {
608
+ self . closeWithCode ( code: . cancel, promise: promise)
609
+ }
610
+
611
+ func closeWithCode( code: HTTP2ErrorCode , promise: EventLoopPromise < Void > ? ) {
608
612
// If the stream is already closed, we can fail this early and abort processing. If it's not, we need to emit a
609
613
// RST_STREAM frame.
610
614
guard self . state != . closed else {
@@ -627,12 +631,17 @@ final class HTTP2StreamChannel: Channel, ChannelCore, @unchecked Sendable {
627
631
self . closedCleanly ( )
628
632
case . remoteActive, . active, . closing, . closingNeverActivated:
629
633
// In all of these states the stream is still on the network and we need to wait.
630
- self . closedWhileOpen ( )
634
+ self . closedWhileOpen ( code : code )
631
635
}
632
636
}
633
637
634
638
public func triggerUserOutboundEvent0( _ event: Any , promise: EventLoopPromise < Void > ? ) {
635
- // do nothing
639
+ switch event {
640
+ case . reset( let code) as HTTP2StreamChannelEvent :
641
+ self . closeWithCode ( code: code, promise: promise)
642
+ default :
643
+ break
644
+ }
636
645
}
637
646
638
647
public func channelRead0( _ data: NIOAny ) {
@@ -647,7 +656,7 @@ final class HTTP2StreamChannel: Channel, ChannelCore, @unchecked Sendable {
647
656
///
648
657
/// Will emit a RST_STREAM frame in order to close the stream. Note that this function does not
649
658
/// directly close the stream: it waits until the stream closed notification is fired.
650
- private func closedWhileOpen( ) {
659
+ private func closedWhileOpen( code : HTTP2ErrorCode = . cancel ) {
651
660
precondition ( self . state != . closed)
652
661
guard self . state != . closing else {
653
662
// If we're already closing, nothing to do here.
@@ -656,7 +665,7 @@ final class HTTP2StreamChannel: Channel, ChannelCore, @unchecked Sendable {
656
665
657
666
self . modifyingState { $0. beginClosing ( ) }
658
667
// We should have a stream ID here, force-unwrap is safe.
659
- let resetFrame = HTTP2Frame ( streamID: self . streamID!, payload: . rstStream( . cancel ) )
668
+ let resetFrame = HTTP2Frame ( streamID: self . streamID!, payload: . rstStream( code ) )
660
669
self . receiveOutboundFrame ( resetFrame, promise: nil )
661
670
self . multiplexer. flushStream ( self . streamID!)
662
671
}
@@ -998,3 +1007,9 @@ extension HTTP2StreamChannel {
998
1007
SynchronousOptions ( channel: self )
999
1008
}
1000
1009
}
1010
+
1011
+ /// Events that can be sent by the application to be handled by the `HTTP2StreamChannel`
1012
+ public enum HTTP2StreamChannelEvent {
1013
+ /// Send a `RST_STREAM` with the specified code
1014
+ case reset( HTTP2ErrorCode )
1015
+ }
0 commit comments