@@ -490,11 +490,43 @@ extension Channel {
490490 mode: NIOHTTP2Handler . ParserMode ,
491491 configuration: NIOHTTP2Handler . Configuration = . init( ) ,
492492 streamInitializer: @escaping NIOChannelInitializerWithOutput < Output >
493+ ) -> EventLoopFuture < NIOHTTP2Handler . AsyncStreamMultiplexer < Output > > {
494+ self . configureAsyncHTTP2Pipeline (
495+ mode: mode,
496+ streamDelegate: nil ,
497+ configuration: configuration,
498+ streamInitializer: streamInitializer
499+ )
500+ }
501+
502+ /// Configures a `ChannelPipeline` to speak HTTP/2 and sets up mapping functions so that it may be interacted with from concurrent code.
503+ ///
504+ /// In general this is not entirely useful by itself, as HTTP/2 is a negotiated protocol. This helper does not handle negotiation.
505+ /// Instead, this simply adds the handler required to speak HTTP/2 after negotiation has completed, or when agreed by prior knowledge.
506+ /// Use this function to setup a HTTP/2 pipeline if you wish to use async sequence abstractions over inbound and outbound streams.
507+ /// Using this rather than implementing a similar function yourself allows that pipeline to evolve without breaking your code.
508+ ///
509+ /// - Parameters:
510+ /// - mode: The mode this pipeline will operate in, server or client.
511+ /// - streamDelegate: A delegate which is called when streams are created and closed.
512+ /// - configuration: The settings that will be used when establishing the connection and new streams.
513+ /// - streamInitializer: A closure that will be called whenever the remote peer initiates a new stream.
514+ /// The output of this closure is the element type of the returned multiplexer
515+ /// - Returns: An `EventLoopFuture` containing the `AsyncStreamMultiplexer` inserted into this pipeline, which can
516+ /// be used to initiate new streams and iterate over inbound HTTP/2 stream channels.
517+ @inlinable
518+ @available ( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * )
519+ public func configureAsyncHTTP2Pipeline< Output: Sendable > (
520+ mode: NIOHTTP2Handler . ParserMode ,
521+ streamDelegate: NIOHTTP2StreamDelegate ? ,
522+ configuration: NIOHTTP2Handler . Configuration = NIOHTTP2Handler . Configuration ( ) ,
523+ streamInitializer: @escaping NIOChannelInitializerWithOutput < Output >
493524 ) -> EventLoopFuture < NIOHTTP2Handler . AsyncStreamMultiplexer < Output > > {
494525 if self . eventLoop. inEventLoop {
495526 return self . eventLoop. makeCompletedFuture {
496527 return try self . pipeline. syncOperations. configureAsyncHTTP2Pipeline (
497528 mode: mode,
529+ streamDelegate: streamDelegate,
498530 configuration: configuration,
499531 streamInitializer: streamInitializer
500532 )
@@ -503,13 +535,15 @@ extension Channel {
503535 return self . eventLoop. submit {
504536 return try self . pipeline. syncOperations. configureAsyncHTTP2Pipeline (
505537 mode: mode,
538+ streamDelegate: streamDelegate,
506539 configuration: configuration,
507540 streamInitializer: streamInitializer
508541 )
509542 }
510543 }
511544 }
512545
546+
513547 /// Configures a channel to perform an HTTP/2 secure upgrade with typed negotiation results.
514548 ///
515549 /// HTTP/2 secure upgrade uses the Application Layer Protocol Negotiation TLS extension to
@@ -642,12 +676,46 @@ extension ChannelPipeline.SynchronousOperations {
642676 mode: NIOHTTP2Handler . ParserMode ,
643677 configuration: NIOHTTP2Handler . Configuration = . init( ) ,
644678 streamInitializer: @escaping NIOChannelInitializerWithOutput < Output >
679+ ) throws -> NIOHTTP2Handler . AsyncStreamMultiplexer < Output > {
680+ try self . configureAsyncHTTP2Pipeline (
681+ mode: mode,
682+ streamDelegate: nil ,
683+ configuration: configuration,
684+ streamInitializer: streamInitializer
685+ )
686+ }
687+
688+ /// Configures a `ChannelPipeline` to speak HTTP/2 and sets up mapping functions so that it may be interacted with from concurrent code.
689+ ///
690+ /// This operation **must** be called on the event loop.
691+ ///
692+ /// In general this is not entirely useful by itself, as HTTP/2 is a negotiated protocol. This helper does not handle negotiation.
693+ /// Instead, this simply adds the handler required to speak HTTP/2 after negotiation has completed, or when agreed by prior knowledge.
694+ /// Use this function to setup a HTTP/2 pipeline if you wish to use async sequence abstractions over inbound and outbound streams,
695+ /// as it allows that pipeline to evolve without breaking your code.
696+ ///
697+ /// - Parameters:
698+ /// - mode: The mode this pipeline will operate in, server or client.
699+ /// - streamDelegate: A delegate which is called when streams are created and closed.
700+ /// - configuration: The settings that will be used when establishing the connection and new streams.
701+ /// - streamInitializer: A closure that will be called whenever the remote peer initiates a new stream.
702+ /// The output of this closure is the element type of the returned multiplexer
703+ /// - Returns: An `EventLoopFuture` containing the `AsyncStreamMultiplexer` inserted into this pipeline, which can
704+ /// be used to initiate new streams and iterate over inbound HTTP/2 stream channels.
705+ @inlinable
706+ @available ( macOS 10 . 15 , iOS 13 . 0 , watchOS 6 . 0 , tvOS 13 . 0 , * )
707+ public func configureAsyncHTTP2Pipeline< Output: Sendable > (
708+ mode: NIOHTTP2Handler . ParserMode ,
709+ streamDelegate: NIOHTTP2StreamDelegate ? ,
710+ configuration: NIOHTTP2Handler . Configuration = NIOHTTP2Handler . Configuration ( ) ,
711+ streamInitializer: @escaping NIOChannelInitializerWithOutput < Output >
645712 ) throws -> NIOHTTP2Handler . AsyncStreamMultiplexer < Output > {
646713 let handler = NIOHTTP2Handler (
647714 mode: mode,
648715 eventLoop: self . eventLoop,
649716 connectionConfiguration: configuration. connection,
650717 streamConfiguration: configuration. stream,
718+ streamDelegate: streamDelegate,
651719 inboundStreamInitializerWithAnyOutput: { channel in
652720 streamInitializer ( channel) . map { return $0 }
653721 }
0 commit comments