@@ -968,11 +968,8 @@ class HTTPClientTests: XCTestCase {
968
968
request. body = . byteBuffer( ByteBuffer ( bytes: [ 120 , 156 , 75 , 76 , 28 , 5 , 200 , 0 , 0 , 248 , 66 , 103 , 17 ] ) )
969
969
request. headers. add ( name: " Accept-Encoding " , value: " deflate " )
970
970
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)
976
973
}
977
974
}
978
975
@@ -2644,19 +2641,45 @@ class HTTPClientTests: XCTestCase {
2644
2641
}
2645
2642
2646
2643
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
+ }
2660
2683
}
2661
2684
2662
2685
func testDoubleError( ) throws {
0 commit comments