Skip to content

Commit f64ae5f

Browse files
committed
Fixes a bug
1 parent 96fbbbd commit f64ae5f

File tree

4 files changed

+43
-6
lines changed

4 files changed

+43
-6
lines changed

‎Sources/AsyncHTTPClient/ConnectionPool/HTTPRequestStateMachine+Demand.swift‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,18 @@ extension HTTPRequestStateMachine{
6161
}
6262
}
6363

64-
mutatingfunc channelReadComplete()->CircularBuffer<ByteBuffer>{
64+
mutatingfunc channelReadComplete()->CircularBuffer<ByteBuffer>?{
6565
switchself.state {
6666
case.waitingForBytes(let buffer):
67-
varnewBuffer= buffer
68-
newBuffer.removeAll(keepingCapacity:true)
69-
self.state =.waitingForReadOrDemand(newBuffer)
70-
return buffer
67+
if buffer.isEmpty {
68+
self.state =.waitingForRead(buffer)
69+
returnnil
70+
}else{
71+
varnewBuffer= buffer
72+
newBuffer.removeAll(keepingCapacity:true)
73+
self.state =.waitingForReadOrDemand(newBuffer)
74+
return buffer
75+
}
7176

7277
case.waitingForRead,
7378
.waitingForDemand,

‎Sources/AsyncHTTPClient/ConnectionPool/HTTPRequestStateMachine.swift‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,11 @@ struct HTTPRequestStateMachine{
426426
returnself.avoidingStateMachineCoW{(state)->Actionin
427427
letbuffer= streamState.channelReadComplete()
428428
state =.running(requestState,.receivingBody(head, streamState))
429-
return.forwardResponseBodyParts(buffer)
429+
iflet buffer = buffer {
430+
return.forwardResponseBodyParts(buffer)
431+
}else{
432+
return.wait
433+
}
430434
}
431435

432436
case.modifying:

‎Tests/AsyncHTTPClientTests/HTTPRequestStateMachineTests+XCTest.swift‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ extension HTTPRequestStateMachineTests{
3838
("testRequestIsNotSendUntilChannelIsWritable", testRequestIsNotSendUntilChannelIsWritable),
3939
("testConnectionBecomesInactiveWhileWaitingForWritable", testConnectionBecomesInactiveWhileWaitingForWritable),
4040
("testResponseReadingWithBackpressure", testResponseReadingWithBackpressure),
41+
("testChannelReadCompleteTriggersButNoBodyDataWasReceivedSoFar", testChannelReadCompleteTriggersButNoBodyDataWasReceivedSoFar),
4142
("testResponseReadingWithBackpressureEndOfResponseAllowsReadEventsToTriggerDirectly", testResponseReadingWithBackpressureEndOfResponseAllowsReadEventsToTriggerDirectly),
4243
("testCancellingARequestInStateInitializedKeepsTheConnectionAlive", testCancellingARequestInStateInitializedKeepsTheConnectionAlive),
4344
("testCancellingARequestBeforeBeingSendKeepsTheConnectionAlive", testCancellingARequestBeforeBeingSendKeepsTheConnectionAlive),

‎Tests/AsyncHTTPClientTests/HTTPRequestStateMachineTests.swift‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,33 @@ class HTTPRequestStateMachineTests: XCTestCase{
279279
XCTAssertEqual(state.demandMoreResponseBodyParts(),.wait)
280280
}
281281

282+
func testChannelReadCompleteTriggersButNoBodyDataWasReceivedSoFar(){
283+
varstate=HTTPRequestStateMachine(isChannelWritable:true)
284+
letrequestHead=HTTPRequestHead(version:.http1_1, method:.GET, uri:"/")
285+
letmetadata=RequestFramingMetadata(connectionClose:false, body:.none)
286+
XCTAssertEqual(state.startRequest(head: requestHead, metadata: metadata),.sendRequestHead(requestHead, startBody:false))
287+
288+
letresponseHead=HTTPResponseHead(version:.http1_1, status:.ok, headers:HTTPHeaders([("content-length","12")]))
289+
XCTAssertEqual(state.channelRead(.head(responseHead)),.forwardResponseHead(responseHead, pauseRequestBodyStream:false))
290+
letpart0=ByteBuffer(bytes:0...3)
291+
letpart1=ByteBuffer(bytes:4...7)
292+
letpart2=ByteBuffer(bytes:8...11)
293+
XCTAssertEqual(state.channelReadComplete(),.wait)
294+
XCTAssertEqual(state.read(),.read)
295+
XCTAssertEqual(state.channelRead(.body(part0)),.wait)
296+
XCTAssertEqual(state.channelRead(.body(part1)),.wait)
297+
XCTAssertEqual(state.channelReadComplete(),.forwardResponseBodyParts(.init([part0, part1])))
298+
XCTAssertEqual(state.read(),.wait)
299+
XCTAssertEqual(state.demandMoreResponseBodyParts(),.read)
300+
XCTAssertEqual(state.channelReadComplete(),.wait)
301+
XCTAssertEqual(state.read(),.read)
302+
XCTAssertEqual(state.channelRead(.body(part2)),.wait)
303+
XCTAssertEqual(state.channelRead(.end(nil)),.succeedRequest(.none,.init([part2])))
304+
XCTAssertEqual(state.channelReadComplete(),.wait)
305+
XCTAssertEqual(state.read(),.read)
306+
XCTAssertEqual(state.demandMoreResponseBodyParts(),.wait)
307+
}
308+
282309
func testResponseReadingWithBackpressureEndOfResponseAllowsReadEventsToTriggerDirectly(){
283310
varstate=HTTPRequestStateMachine(isChannelWritable:true)
284311
letrequestHead=HTTPRequestHead(version:.http1_1, method:.GET, uri:"/")

0 commit comments

Comments
(0)