@@ -186,26 +186,23 @@ class HTTPClientTests: XCTestCase {
186
186
XCTAssertEqual ( response. status, . ok)
187
187
}
188
188
189
- func testHttpHostRedirect( ) throws {
189
+ func testHttpHostRedirect( ) {
190
190
let localClient = HTTPClient ( eventLoopGroupProvider: . shared( self . clientGroup) ,
191
191
configuration: HTTPClient . Configuration ( certificateVerification: . none, redirectConfiguration: . follow( max: 10 , allowCycles: true ) ) )
192
192
193
193
defer {
194
194
XCTAssertNoThrow ( try localClient. syncShutdown ( ) )
195
195
}
196
196
197
- let response = try localClient. get ( url: self . defaultHTTPBinURLPrefix + " redirect/loopback?port= \( self . defaultHTTPBin. port) " ) . wait ( )
198
- guard var body = response. body else {
199
- XCTFail ( " The target page should have a body containing the value of the Host header " )
197
+ let url = self . defaultHTTPBinURLPrefix + " redirect/loopback?port= \( self . defaultHTTPBin. port) "
198
+ var maybeResponse : HTTPClient . Response ?
199
+ XCTAssertNoThrow ( maybeResponse = try localClient. get ( url: url) . wait ( ) )
200
+ guard let response = maybeResponse, let body = response. body else {
201
+ XCTFail ( " request failed " )
200
202
return
201
203
}
202
- guard let responseData = body. readData ( length: body. readableBytes) else {
203
- XCTFail ( " Read data shouldn't be nil since we passed body.readableBytes to body.readData " )
204
- return
205
- }
206
- let decoder = JSONDecoder ( )
207
- let hostName = try decoder. decode ( [ String : String ] . self, from: responseData) [ " data " ]
208
- XCTAssert ( hostName == " 127.0.0.1 " )
204
+ let hostName = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: body) . data
205
+ XCTAssertEqual ( " 127.0.0.1 " , hostName)
209
206
}
210
207
211
208
func testPercentEncoded( ) throws {
@@ -1637,4 +1634,126 @@ class HTTPClientTests: XCTestCase {
1637
1634
} )
1638
1635
XCTAssertNoThrow ( try self . defaultClient. execute ( request: request) . wait ( ) )
1639
1636
}
1637
+
1638
+ func testWeHandleUsSendingACloseHeaderCorrectly( ) {
1639
+ guard let req1 = try ? Request ( url: self . defaultHTTPBinURLPrefix + " stats " ,
1640
+ method: . GET,
1641
+ headers: [ " connection " : " close " ] ) ,
1642
+ let statsBytes1 = try ? self . defaultClient. execute ( request: req1) . wait ( ) . body,
1643
+ let stats1 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes1) else {
1644
+ XCTFail ( " request 1 didn't work " )
1645
+ return
1646
+ }
1647
+ guard let statsBytes2 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1648
+ let stats2 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes2) else {
1649
+ XCTFail ( " request 2 didn't work " )
1650
+ return
1651
+ }
1652
+ guard let statsBytes3 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1653
+ let stats3 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes3) else {
1654
+ XCTFail ( " request 3 didn't work " )
1655
+ return
1656
+ }
1657
+
1658
+ // req 1 and 2 cannot share the same connection (close header)
1659
+ XCTAssertEqual ( stats1. connectionNumber + 1 , stats2. connectionNumber)
1660
+ XCTAssertEqual ( stats1. requestNumber + 1 , stats2. requestNumber)
1661
+
1662
+ // req 2 and 3 should share the same connection (keep-alive is default)
1663
+ XCTAssertEqual ( stats2. requestNumber + 1 , stats3. requestNumber)
1664
+ XCTAssertEqual ( stats2. connectionNumber, stats3. connectionNumber)
1665
+ }
1666
+
1667
+ func testWeHandleUsReceivingACloseHeaderCorrectly( ) {
1668
+ guard let req1 = try ? Request ( url: self . defaultHTTPBinURLPrefix + " stats " ,
1669
+ method: . GET,
1670
+ headers: [ " X-Send-Back-Header-Connection " : " close " ] ) ,
1671
+ let statsBytes1 = try ? self . defaultClient. execute ( request: req1) . wait ( ) . body,
1672
+ let stats1 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes1) else {
1673
+ XCTFail ( " request 1 didn't work " )
1674
+ return
1675
+ }
1676
+ guard let statsBytes2 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1677
+ let stats2 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes2) else {
1678
+ XCTFail ( " request 2 didn't work " )
1679
+ return
1680
+ }
1681
+ guard let statsBytes3 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1682
+ let stats3 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes3) else {
1683
+ XCTFail ( " request 3 didn't work " )
1684
+ return
1685
+ }
1686
+
1687
+ // req 1 and 2 cannot share the same connection (close header)
1688
+ XCTAssertEqual ( stats1. connectionNumber + 1 , stats2. connectionNumber)
1689
+ XCTAssertEqual ( stats1. requestNumber + 1 , stats2. requestNumber)
1690
+
1691
+ // req 2 and 3 should share the same connection (keep-alive is default)
1692
+ XCTAssertEqual ( stats2. requestNumber + 1 , stats3. requestNumber)
1693
+ XCTAssertEqual ( stats2. connectionNumber, stats3. connectionNumber)
1694
+ }
1695
+
1696
+ func testWeHandleUsSendingACloseHeaderAmongstOtherConnectionHeadersCorrectly( ) {
1697
+ for closeHeader in [ ( " connection " , " close " ) , ( " CoNneCTION " , " ClOSe " ) ] {
1698
+ guard let req1 = try ? Request ( url: self . defaultHTTPBinURLPrefix + " stats " ,
1699
+ method: . GET,
1700
+ headers: [ " X-Send-Back-Header- \( closeHeader. 0 ) " :
1701
+ " foo, \( closeHeader. 1 ) ,bar " ] ) ,
1702
+ let statsBytes1 = try ? self . defaultClient. execute ( request: req1) . wait ( ) . body,
1703
+ let stats1 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes1) else {
1704
+ XCTFail ( " request 1 didn't work " )
1705
+ return
1706
+ }
1707
+ guard let statsBytes2 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1708
+ let stats2 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes2) else {
1709
+ XCTFail ( " request 2 didn't work " )
1710
+ return
1711
+ }
1712
+ guard let statsBytes3 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1713
+ let stats3 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes3) else {
1714
+ XCTFail ( " request 3 didn't work " )
1715
+ return
1716
+ }
1717
+
1718
+ // req 1 and 2 cannot share the same connection (close header)
1719
+ XCTAssertEqual ( stats1. connectionNumber + 1 , stats2. connectionNumber)
1720
+ XCTAssertEqual ( stats1. requestNumber + 1 , stats2. requestNumber)
1721
+
1722
+ // req 2 and 3 should share the same connection (keep-alive is default)
1723
+ XCTAssertEqual ( stats2. requestNumber + 1 , stats3. requestNumber)
1724
+ XCTAssertEqual ( stats2. connectionNumber, stats3. connectionNumber)
1725
+ }
1726
+ }
1727
+
1728
+ func testWeHandleUsReceivingACloseHeaderAmongstOtherConnectionHeadersCorrectly( ) {
1729
+ for closeHeader in [ ( " connection " , " close " ) , ( " CoNneCTION " , " ClOSe " ) ] {
1730
+ guard let req1 = try ? Request ( url: self . defaultHTTPBinURLPrefix + " stats " ,
1731
+ method: . GET,
1732
+ headers: [ " X-Send-Back-Header- \( closeHeader. 0 ) " :
1733
+ " foo, \( closeHeader. 1 ) ,bar " ] ) ,
1734
+ let statsBytes1 = try ? self . defaultClient. execute ( request: req1) . wait ( ) . body,
1735
+ let stats1 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes1) else {
1736
+ XCTFail ( " request 1 didn't work " )
1737
+ return
1738
+ }
1739
+ guard let statsBytes2 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1740
+ let stats2 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes2) else {
1741
+ XCTFail ( " request 2 didn't work " )
1742
+ return
1743
+ }
1744
+ guard let statsBytes3 = try ? self . defaultClient. get ( url: self . defaultHTTPBinURLPrefix + " stats " ) . wait ( ) . body,
1745
+ let stats3 = try ? JSONDecoder ( ) . decode ( RequestInfo . self, from: statsBytes3) else {
1746
+ XCTFail ( " request 3 didn't work " )
1747
+ return
1748
+ }
1749
+
1750
+ // req 1 and 2 cannot share the same connection (close header)
1751
+ XCTAssertEqual ( stats1. connectionNumber + 1 , stats2. connectionNumber)
1752
+ XCTAssertEqual ( stats1. requestNumber + 1 , stats2. requestNumber)
1753
+
1754
+ // req 2 and 3 should share the same connection (keep-alive is default)
1755
+ XCTAssertEqual ( stats2. requestNumber + 1 , stats3. requestNumber)
1756
+ XCTAssertEqual ( stats2. connectionNumber, stats3. connectionNumber)
1757
+ }
1758
+ }
1640
1759
}
0 commit comments