@@ -113,9 +113,19 @@ public final class HTTPServer: Server, Sendable {
113113
114114 /// An optional callback that will be called instead of using swift-nio-ssl's regular certificate verification logic.
115115 /// This is the same as `NIOSSLCustomVerificationCallback` but just marked as `Sendable`
116+ /// - Warning: Mutually exclusive with `customCertificateVerifyCallbackWithMetadata`.
116117 @preconcurrency
117118 public var customCertificateVerifyCallback : ( @Sendable ( [ NIOSSLCertificate ] , EventLoopPromise < NIOSSLVerificationResult > ) -> Void ) ?
118-
119+
120+ /// An optional callback that will be called instead of using swift-nio-ssl's regular certificate verification logic.
121+ /// This is the same as `NIOSSLCustomVerificationCallbackWithMetadata` but just marked as `Sendable`.
122+ ///
123+ /// In contrast to `customCertificateVerifyCallback`, this callback allows returning the validate certificate
124+ /// chain, which can then be accessed on the request via `Request.peerCertificateChain`.
125+ /// - Warning: Mutually exclusive with `customCertificateVerifyCallback`.
126+ @preconcurrency
127+ public var customCertificateVerifyCallbackWithMetadata : ( @Sendable ( [ NIOSSLCertificate ] , EventLoopPromise < NIOSSLVerificationResultWithMetadata > ) -> Void ) ?
128+
119129 /// The number of incoming TCP connections to accept per "tick" (i.e. each time through the server's event loop).
120130 ///
121131 /// Most users will never need to change this value; its primary use case is to work around benchmarking
@@ -161,6 +171,43 @@ public final class HTTPServer: Server, Sendable {
161171 )
162172 }
163173
174+ public init (
175+ hostname: String = Self . defaultHostname,
176+ port: Int = Self . defaultPort,
177+ backlog: Int = 256 ,
178+ reuseAddress: Bool = true ,
179+ tcpNoDelay: Bool = true ,
180+ responseCompression: ResponseCompressionConfiguration = . disabled,
181+ requestDecompression: RequestDecompressionConfiguration = . enabled,
182+ supportPipelining: Bool = true ,
183+ supportVersions: Set < HTTPVersionMajor > ? = nil ,
184+ tlsConfiguration: TLSConfiguration ? = nil ,
185+ serverName: String ? = nil ,
186+ reportMetrics: Bool = true ,
187+ logger: Logger ? = nil ,
188+ shutdownTimeout: TimeAmount = . seconds( 10 ) ,
189+ customCertificateVerifyCallbackWithMetadata: ( @Sendable ( [ NIOSSLCertificate ] , EventLoopPromise < NIOSSLVerificationResultWithMetadata > ) -> Void ) ? ,
190+ connectionsPerServerTick: UInt = 256
191+ ) {
192+ self . init (
193+ address: . hostname( hostname, port: port) ,
194+ backlog: backlog,
195+ reuseAddress: reuseAddress,
196+ tcpNoDelay: tcpNoDelay,
197+ responseCompression: responseCompression,
198+ requestDecompression: requestDecompression,
199+ supportPipelining: supportPipelining,
200+ supportVersions: supportVersions,
201+ tlsConfiguration: tlsConfiguration,
202+ serverName: serverName,
203+ reportMetrics: reportMetrics,
204+ logger: logger,
205+ shutdownTimeout: shutdownTimeout,
206+ customCertificateVerifyCallbackWithMetadata: customCertificateVerifyCallbackWithMetadata,
207+ connectionsPerServerTick: connectionsPerServerTick
208+ )
209+ }
210+
164211 public init (
165212 address: BindAddress ,
166213 backlog: Int = 256 ,
@@ -196,10 +243,50 @@ public final class HTTPServer: Server, Sendable {
196243 self . logger = logger ?? Logger ( label: " codes.vapor.http-server " )
197244 self . shutdownTimeout = shutdownTimeout
198245 self . customCertificateVerifyCallback = customCertificateVerifyCallback
246+ self . customCertificateVerifyCallbackWithMetadata = nil
247+ self . connectionsPerServerTick = connectionsPerServerTick
248+ }
249+
250+ public init (
251+ address: BindAddress ,
252+ backlog: Int = 256 ,
253+ reuseAddress: Bool = true ,
254+ tcpNoDelay: Bool = true ,
255+ responseCompression: ResponseCompressionConfiguration = . disabled,
256+ requestDecompression: RequestDecompressionConfiguration = . enabled,
257+ supportPipelining: Bool = true ,
258+ supportVersions: Set < HTTPVersionMajor > ? = nil ,
259+ tlsConfiguration: TLSConfiguration ? = nil ,
260+ serverName: String ? = nil ,
261+ reportMetrics: Bool = true ,
262+ logger: Logger ? = nil ,
263+ shutdownTimeout: TimeAmount = . seconds( 10 ) ,
264+ customCertificateVerifyCallbackWithMetadata: ( @Sendable ( [ NIOSSLCertificate ] , EventLoopPromise < NIOSSLVerificationResultWithMetadata > ) -> Void ) ? ,
265+ connectionsPerServerTick: UInt = 256
266+ ) {
267+ self . address = address
268+ self . backlog = backlog
269+ self . reuseAddress = reuseAddress
270+ self . tcpNoDelay = tcpNoDelay
271+ self . responseCompression = responseCompression
272+ self . requestDecompression = requestDecompression
273+ self . supportPipelining = supportPipelining
274+ if let supportVersions = supportVersions {
275+ self . supportVersions = supportVersions
276+ } else {
277+ self . supportVersions = tlsConfiguration == nil ? [ . one] : [ . one, . two]
278+ }
279+ self . tlsConfiguration = tlsConfiguration
280+ self . serverName = serverName
281+ self . reportMetrics = reportMetrics
282+ self . logger = logger ?? Logger ( label: " codes.vapor.http-server " )
283+ self . shutdownTimeout = shutdownTimeout
284+ self . customCertificateVerifyCallback = nil
285+ self . customCertificateVerifyCallbackWithMetadata = customCertificateVerifyCallbackWithMetadata
199286 self . connectionsPerServerTick = connectionsPerServerTick
200287 }
201288 }
202-
289+
203290 public var onShutdown : EventLoopFuture < Void > {
204291 guard let connection = self . connection. withLockedValue ( { $0 } ) else {
205292 fatalError ( " Server has not started yet " )
@@ -447,7 +534,11 @@ private final class HTTPServerConnection: Sendable {
447534 let tlsHandler : NIOSSLServerHandler
448535 do {
449536 sslContext = try NIOSSLContext ( configuration: tlsConfiguration)
450- tlsHandler = NIOSSLServerHandler ( context: sslContext, customVerifyCallback: configuration. customCertificateVerifyCallback)
537+ tlsHandler = NIOSSLServerHandler (
538+ context: sslContext,
539+ customVerifyCallback: configuration. customCertificateVerifyCallback,
540+ customVerifyCallbackWithMetadata: configuration. customCertificateVerifyCallbackWithMetadata
541+ )
451542 } catch {
452543 configuration. logger. error ( " Could not configure TLS: \( error) " )
453544 return channel. close ( mode: . all)
@@ -662,9 +753,13 @@ extension ChannelPipeline {
662753
663754// MARK: Helper function for constructing NIOSSLServerHandler.
664755extension NIOSSLServerHandler {
665- convenience init ( context: NIOSSLContext , customVerifyCallback: NIOSSLCustomVerificationCallback ? ) {
756+ convenience init ( context: NIOSSLContext , customVerifyCallback: NIOSSLCustomVerificationCallback ? ,
757+ customVerifyCallbackWithMetadata: NIOSSLCustomVerificationCallbackWithMetadata ? ) {
758+ precondition ( customVerifyCallback == nil || customVerifyCallbackWithMetadata == nil , " Only one of customVerifyCallback and customVerifyCallbackWithMetadata can be used at a time. " )
666759 if let callback = customVerifyCallback {
667760 self . init ( context: context, customVerificationCallback: callback)
761+ } else if let callbackWithMetadata = customVerifyCallbackWithMetadata {
762+ self . init ( context: context, customVerificationCallbackWithMetadata: callbackWithMetadata)
668763 } else {
669764 self . init ( context: context)
670765 }
0 commit comments