@@ -968,11 +968,8 @@ class HTTPClientTests: XCTestCase {
968968 request. body = . byteBuffer( ByteBuffer ( bytes: [ 120 , 156 , 75 , 76 , 28 , 5 , 200 , 0 , 0 , 248 , 66 , 103 , 17 ] ) )
969969 request. headers. add ( name: " Accept-Encoding " , value: " deflate " )
970970
971- XCTAssertThrowsError ( try localClient. execute ( request: request) . wait ( ) ) { error in
972- guard case . some( . limit) = error as? NIOHTTPDecompression . DecompressionError else {
973- XCTFail ( " wrong error: \( error) " )
974- return
975- }
971+ XCTAssertThrowsError ( try localClient. execute ( request: request) . wait ( ) ) {
972+ XCTAssertEqual ( $0 as? NIOHTTPDecompression . DecompressionError , . limit)
976973 }
977974 }
978975
@@ -2644,19 +2641,45 @@ class HTTPClientTests: XCTestCase {
26442641 }
26452642
26462643 let tooLong = " XBAD BAD BAD NOT HTTP/1.1 \r \n \r \n "
2647- let future = self . defaultClient. execute (
2648- request: try Request ( url: " http://localhost: \( server. serverPort) " ,
2649- body: . stream( length: 1 ) { streamWriter in
2650- streamWriter. write ( . byteBuffer( ByteBuffer ( string: tooLong) ) )
2651- } ) )
2652-
2653- XCTAssertNoThrow ( try server. readInbound ( ) ) // .head
2654- // this should fail if client detects that we are about to send more bytes than body limit and closes the connection
2655- // We can test that this test actually fails if we remove limit check in `writeBodyPart` - it will send bytes, meaning that the next
2656- // call will not throw, but the future will still throw body mismatch error
2657- XCTAssertThrowsError ( try server. readInbound ( ) ) { error in XCTAssertEqual ( error as? HTTPParserError , HTTPParserError . invalidEOFState) }
2658-
2659- XCTAssertThrowsError ( try future. wait ( ) )
2644+
2645+ let request = try Request (
2646+ url: " http://localhost: \( server. serverPort) " ,
2647+ body: . stream( length: 1 ) { streamWriter in
2648+ streamWriter. write ( . byteBuffer( ByteBuffer ( string: tooLong) ) )
2649+ }
2650+ )
2651+
2652+ let future = self . defaultClient. execute ( request: request)
2653+
2654+ // Okay, what happens here needs an explanation:
2655+ //
2656+ // In the request state machine, we should start the request, which will lead to an
2657+ // invocation of `context.write(HTTPRequestHead)`. Since we will receive a streamed request
2658+ // body a `context.flush()` will be issued. Further the request stream will be started.
2659+ // Since the request stream immediately produces to much data, the request will be failed
2660+ // and the connection will be closed.
2661+ //
2662+ // Even though a flush was issued after the request head, there is no guarantee that the
2663+ // request head was written to the network. For this reason we must accept not receiving a
2664+ // request and receiving a request head.
2665+
2666+ do {
2667+ _ = try server. receiveHead ( )
2668+
2669+ // A request head was sent. We expect the request now to fail with a parsing error,
2670+ // since the client ended the connection to early (from the server's point of view.)
2671+ XCTAssertThrowsError ( try server. readInbound ( ) ) {
2672+ XCTAssertEqual ( $0 as? HTTPParserError , HTTPParserError . invalidEOFState)
2673+ }
2674+ } catch {
2675+ // TBD: We sadly can't verify the error type, since it is private in `NIOTestUtils`:
2676+ // NIOTestUtils.BlockingQueue<Element>.TimeoutError
2677+ }
2678+
2679+ // request must always be failed with this error
2680+ XCTAssertThrowsError ( try future. wait ( ) ) {
2681+ XCTAssertEqual ( $0 as? HTTPClientError , . bodyLengthMismatch)
2682+ }
26602683 }
26612684
26622685 func testDoubleError( ) throws {
0 commit comments