@@ -20,6 +20,7 @@ import Network
2020import Logging
2121import NIOConcurrencyHelpers
2222import NIOCore
23+ import NIOEmbedded
2324import NIOFoundationCompat
2425import NIOHTTP1
2526import NIOHTTPCompression
@@ -607,6 +608,35 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
607608 }
608609 }
609610
611+ func testWriteTimeout( ) throws {
612+ let localClient = HTTPClient ( eventLoopGroupProvider: . shared( self . clientGroup) ,
613+ configuration: HTTPClient . Configuration ( timeout: HTTPClient . Configuration. Timeout ( write: . nanoseconds( 10 ) ) ) )
614+
615+ defer {
616+ XCTAssertNoThrow ( try localClient. syncShutdown ( ) )
617+ }
618+
619+ // Create a request that writes a chunk, then waits longer than the configured write timeout,
620+ // and then writes again. This should trigger a write timeout error.
621+ let request = try HTTPClient . Request ( url: self . defaultHTTPBinURLPrefix + " post " ,
622+ method: . POST,
623+ headers: [ " transfer-encoding " : " chunked " ] ,
624+ body: . stream { streamWriter in
625+ _ = streamWriter. write ( . byteBuffer( . init( ) ) )
626+
627+ let promise = self . clientGroup. next ( ) . makePromise ( of: Void . self)
628+ self . clientGroup. next ( ) . scheduleTask ( in: . milliseconds( 3 ) ) {
629+ streamWriter. write ( . byteBuffer( . init( ) ) ) . cascade ( to: promise)
630+ }
631+
632+ return promise. futureResult
633+ } )
634+
635+ XCTAssertThrowsError ( try localClient. execute ( request: request) . wait ( ) ) {
636+ XCTAssertEqual ( $0 as? HTTPClientError , . writeTimeout)
637+ }
638+ }
639+
610640 func testConnectTimeout( ) throws {
611641 #if os(Linux)
612642 // 198.51.100.254 is reserved for documentation only and therefore should not accept any TCP connection
@@ -1230,8 +1260,8 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
12301260 /// openssl req -x509 -newkey rsa:4096 -keyout self_signed_key.pem -out self_signed_cert.pem -sha256 -days 99999 -nodes -subj '/CN=localhost'
12311261 let certPath = Bundle . module. path ( forResource: " self_signed_cert " , ofType: " pem " ) !
12321262 let keyPath = Bundle . module. path ( forResource: " self_signed_key " , ofType: " pem " ) !
1233- let configuration = TLSConfiguration . makeServerConfiguration (
1234- certificateChain: try NIOSSLCertificate . fromPEMFile ( certPath) . map { . certificate( $0) } ,
1263+ let configuration = try TLSConfiguration . makeServerConfiguration (
1264+ certificateChain: NIOSSLCertificate . fromPEMFile ( certPath) . map { . certificate( $0) } ,
12351265 privateKey: . file( keyPath)
12361266 )
12371267 let sslContext = try NIOSSLContext ( configuration: configuration)
@@ -1270,8 +1300,8 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
12701300 /// openssl req -x509 -newkey rsa:4096 -keyout self_signed_key.pem -out self_signed_cert.pem -sha256 -days 99999 -nodes -subj '/CN=localhost'
12711301 let certPath = Bundle . module. path ( forResource: " self_signed_cert " , ofType: " pem " ) !
12721302 let keyPath = Bundle . module. path ( forResource: " self_signed_key " , ofType: " pem " ) !
1273- let configuration = TLSConfiguration . makeServerConfiguration (
1274- certificateChain: try NIOSSLCertificate . fromPEMFile ( certPath) . map { . certificate( $0) } ,
1303+ let configuration = try TLSConfiguration . makeServerConfiguration (
1304+ certificateChain: NIOSSLCertificate . fromPEMFile ( certPath) . map { . certificate( $0) } ,
12751305 privateKey: . file( keyPath)
12761306 )
12771307 let sslContext = try NIOSSLContext ( configuration: configuration)
@@ -2728,7 +2758,7 @@ final class HTTPClientTests: XCTestCaseHTTPClientTestsBaseClass {
27282758
27292759 func uploader( _ streamWriter: HTTPClient . Body . StreamWriter ) -> EventLoopFuture < Void > {
27302760 let done = streamWriter. write ( . byteBuffer( ByteBuffer ( string: " X " ) ) )
2731- done. recover { error -> Void in
2761+ done. recover { error in
27322762 XCTFail ( " unexpected error \( error) " )
27332763 } . whenSuccess {
27342764 // This is executed when we have already sent the end of the request.
0 commit comments