Skip to content

Commit b72844d

Browse files
committed
Add an explicit test to verify we don't loose data if we receive an end.
1 parent 96e4f95 commit b72844d

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

Diff for: Sources/AsyncHTTPClient/ConnectionPool/HTTPRequestStateMachine+Demand.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ extension HTTPRequestStateMachine {
9999
// If the connection to a server is closed, NIO will forward all outstanding
100100
// `channelRead`s without waiting for a next `context.read` call. After all
101101
// `channelRead`s are delivered, we will also see a `channelReadComplete` call. After
102-
// this has happened, we know that we will get a channelInactive, which will fail the
103-
// request. Since the request is doomed anyway, we can just drop the already buffered
104-
// bytes here.
102+
// this has happened, we know that we will get a channelInactive or further
103+
// `channelReads`. If the request ever gets to an `.end` all buffered data will be
104+
// forwarded to the user.
105105

106106
case .waitingForRead,
107107
.waitingForDemand,

Diff for: Tests/AsyncHTTPClientTests/HTTPRequestStateMachineTests+XCTest.swift

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ extension HTTPRequestStateMachineTests {
5959
("testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForDemand", testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForDemand),
6060
("testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForRead", testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForRead),
6161
("testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemand", testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemand),
62+
("testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemandMultipleTimes", testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemandMultipleTimes),
6263
]
6364
}
6465
}

Diff for: Tests/AsyncHTTPClientTests/HTTPRequestStateMachineTests.swift

+33
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,39 @@ class HTTPRequestStateMachineTests: XCTestCase {
619619
XCTAssertEqual(state.channelReadComplete(), .wait)
620620
XCTAssertEqual(state.channelInactive(), .failRequest(HTTPClientError.remoteConnectionClosed, .none))
621621
}
622+
623+
func testFailHTTPRequestWithContentLengthBecauseOfChannelInactiveWaitingForReadAndDemandMultipleTimes() {
624+
var state = HTTPRequestStateMachine(isChannelWritable: true, ignoreUncleanSSLShutdown: false)
625+
let requestHead = HTTPRequestHead(version: .http1_1, method: .GET, uri: "/")
626+
let metadata = RequestFramingMetadata(connectionClose: false, body: .none)
627+
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata), .sendRequestHead(requestHead, startBody: false))
628+
629+
let responseHead = HTTPResponseHead(version: .http1_1, status: .ok, headers: ["Content-Length": "50"])
630+
let body = ByteBuffer(string: "foo bar")
631+
XCTAssertEqual(state.channelRead(.head(responseHead)), .forwardResponseHead(responseHead, pauseRequestBodyStream: false))
632+
XCTAssertEqual(state.demandMoreResponseBodyParts(), .wait)
633+
XCTAssertEqual(state.channelReadComplete(), .wait)
634+
XCTAssertEqual(state.read(), .read)
635+
XCTAssertEqual(state.channelRead(.body(body)), .wait)
636+
XCTAssertEqual(state.channelReadComplete(), .forwardResponseBodyParts([body]))
637+
638+
let part1 = ByteBuffer(string: "baz lightyear")
639+
XCTAssertEqual(state.channelRead(.body(part1)), .wait)
640+
XCTAssertEqual(state.channelReadComplete(), .wait)
641+
642+
let part2 = ByteBuffer(string: "nearly last")
643+
XCTAssertEqual(state.channelRead(.body(part2)), .wait)
644+
XCTAssertEqual(state.channelReadComplete(), .wait)
645+
646+
let part3 = ByteBuffer(string: "final message")
647+
XCTAssertEqual(state.channelRead(.body(part3)), .wait)
648+
XCTAssertEqual(state.channelReadComplete(), .wait)
649+
650+
XCTAssertEqual(state.channelRead(.end(nil)), .succeedRequest(.close, [part1, part2, part3]))
651+
XCTAssertEqual(state.channelReadComplete(), .wait)
652+
653+
XCTAssertEqual(state.channelInactive(), .wait)
654+
}
622655
}
623656

624657
extension HTTPRequestStateMachine.Action: Equatable {

0 commit comments

Comments
 (0)