@@ -43,7 +43,7 @@ extension RequestBag {
4343
4444 case initialized
4545 case buffering( CircularBuffer < ByteBuffer > , next: Next )
46- case waitingForRemote( CircularBuffer < ByteBuffer > )
46+ case waitingForRemote
4747 }
4848
4949 private var state : State = . initialized
@@ -282,26 +282,31 @@ extension RequestBag.StateMachine {
282282 }
283283 }
284284
285- mutating func receiveResponseBodyPart ( _ byteBuffer : ByteBuffer ) -> ByteBuffer ? {
285+ mutating func receiveResponseBodyParts ( _ buffer : CircularBuffer < ByteBuffer > ) -> ByteBuffer ? {
286286 switch self . state {
287287 case . initialized, . queued:
288288 preconditionFailure ( " How can we receive a response body part, if the request hasn't started yet. " )
289289 case . executing( _, _, . initialized) :
290290 preconditionFailure ( " If we receive a response body, we must have received a head before " )
291291
292- case . executing( let executor, let requestState, . buffering( var buffer , next: let next) ) :
292+ case . executing( let executor, let requestState, . buffering( var currentBuffer , next: let next) ) :
293293 guard case . askExecutorForMore = next else {
294294 preconditionFailure ( " If we have received an error or eof before, why did we get another body part? Next: \( next) " )
295295 }
296296
297297 self . state = . modifying
298- buffer. append ( byteBuffer)
299- self . state = . executing( executor, requestState, . buffering( buffer, next: next) )
298+ if currentBuffer. isEmpty {
299+ currentBuffer = buffer
300+ } else {
301+ currentBuffer. append ( contentsOf: buffer)
302+ }
303+ self . state = . executing( executor, requestState, . buffering( currentBuffer, next: next) )
300304 return nil
301- case . executing( let executor, let requestState, . waitingForRemote( let buffer) ) :
302- assert ( buffer. isEmpty, " If we wait for remote, the buffer must be empty " )
305+ case . executing( let executor, let requestState, . waitingForRemote) :
306+ var buffer = buffer
307+ let first = buffer. removeFirst ( )
303308 self . state = . executing( executor, requestState, . buffering( buffer, next: . askExecutorForMore) )
304- return byteBuffer
309+ return first
305310 case . redirected:
306311 // ignore body
307312 return nil
@@ -315,30 +320,42 @@ extension RequestBag.StateMachine {
315320 }
316321
317322 enum ReceiveResponseEndAction {
323+ case consume( ByteBuffer )
318324 case redirect( RedirectHandler < Delegate . Response > , HTTPResponseHead , URL )
319325 case succeedRequest
320326 case none
321327 }
322328
323- mutating func receiveResponseEnd ( ) -> ReceiveResponseEndAction {
329+ mutating func succeedRequest ( _ newChunks : CircularBuffer < ByteBuffer > ? ) -> ReceiveResponseEndAction {
324330 switch self . state {
325331 case . initialized, . queued:
326332 preconditionFailure ( " How can we receive a response body part, if the request hasn't started yet. " )
327333 case . executing( _, _, . initialized) :
328334 preconditionFailure ( " If we receive a response body, we must have received a head before " )
329335
330- case . executing( let executor, let requestState, . buffering( let buffer, next: let next) ) :
336+ case . executing( let executor, let requestState, . buffering( var buffer, next: let next) ) :
331337 guard case . askExecutorForMore = next else {
332338 preconditionFailure ( " If we have received an error or eof before, why did we get another body part? Next: \( next) " )
333339 }
334340
341+ if buffer. isEmpty, let newChunks = newChunks {
342+ buffer = newChunks
343+ } else if let newChunks = newChunks {
344+ buffer. append ( contentsOf: newChunks)
345+ }
346+
335347 self . state = . executing( executor, requestState, . buffering( buffer, next: . eof) )
336348 return . none
337349
338- case . executing( _, _, . waitingForRemote( let buffer) ) :
339- assert ( buffer. isEmpty, " If we wait for remote, the buffer must be empty " )
340- self . state = . finished( error: nil )
341- return . succeedRequest
350+ case . executing( let executor, let requestState, . waitingForRemote) :
351+ guard var newChunks = newChunks, !newChunks. isEmpty else {
352+ self . state = . finished( error: nil )
353+ return . succeedRequest
354+ }
355+
356+ let first = newChunks. removeFirst ( )
357+ self . state = . executing( executor, requestState, . buffering( newChunks, next: . eof) )
358+ return . consume( first)
342359
343360 case . redirected( let head, let redirectURL) :
344361 self . state = . finished( error: nil )
@@ -421,7 +438,7 @@ extension RequestBag.StateMachine {
421438 }
422439
423440 // buffer is empty, wait for more
424- self . state = . executing( executor, requestState, . waitingForRemote( buffer ) )
441+ self . state = . executing( executor, requestState, . waitingForRemote)
425442 return . requestMoreFromExecutor( executor)
426443
427444 case . executing( let executor, let requestState, . buffering( var buffer, next: . eof) ) :
@@ -482,7 +499,7 @@ extension RequestBag.StateMachine {
482499 case . executing( let executor, _, . initialized) :
483500 self . state = . finished( error: error)
484501 return . failTask( nil , executor)
485- case . executing( let executor, _, . waitingForRemote( _ ) ) :
502+ case . executing( let executor, _, . waitingForRemote) :
486503 self . state = . finished( error: error)
487504 return . failTask( nil , executor)
488505 case . redirected:
0 commit comments