@@ -43,7 +43,7 @@ extension RequestBag {
43
43
44
44
case initialized
45
45
case buffering( CircularBuffer < ByteBuffer > , next: Next )
46
- case waitingForRemote( CircularBuffer < ByteBuffer > )
46
+ case waitingForRemote
47
47
}
48
48
49
49
private var state : State = . initialized
@@ -282,26 +282,31 @@ extension RequestBag.StateMachine {
282
282
}
283
283
}
284
284
285
- mutating func receiveResponseBodyPart ( _ byteBuffer : ByteBuffer ) -> ByteBuffer ? {
285
+ mutating func receiveResponseBodyParts ( _ buffer : CircularBuffer < ByteBuffer > ) -> ByteBuffer ? {
286
286
switch self . state {
287
287
case . initialized, . queued:
288
288
preconditionFailure ( " How can we receive a response body part, if the request hasn't started yet. " )
289
289
case . executing( _, _, . initialized) :
290
290
preconditionFailure ( " If we receive a response body, we must have received a head before " )
291
291
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) ) :
293
293
guard case . askExecutorForMore = next else {
294
294
preconditionFailure ( " If we have received an error or eof before, why did we get another body part? Next: \( next) " )
295
295
}
296
296
297
297
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) )
300
304
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 ( )
303
308
self . state = . executing( executor, requestState, . buffering( buffer, next: . askExecutorForMore) )
304
- return byteBuffer
309
+ return first
305
310
case . redirected:
306
311
// ignore body
307
312
return nil
@@ -315,30 +320,42 @@ extension RequestBag.StateMachine {
315
320
}
316
321
317
322
enum ReceiveResponseEndAction {
323
+ case consume( ByteBuffer )
318
324
case redirect( RedirectHandler < Delegate . Response > , HTTPResponseHead , URL )
319
325
case succeedRequest
320
326
case none
321
327
}
322
328
323
- mutating func receiveResponseEnd ( ) -> ReceiveResponseEndAction {
329
+ mutating func succeedRequest ( _ newChunks : CircularBuffer < ByteBuffer > ? ) -> ReceiveResponseEndAction {
324
330
switch self . state {
325
331
case . initialized, . queued:
326
332
preconditionFailure ( " How can we receive a response body part, if the request hasn't started yet. " )
327
333
case . executing( _, _, . initialized) :
328
334
preconditionFailure ( " If we receive a response body, we must have received a head before " )
329
335
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) ) :
331
337
guard case . askExecutorForMore = next else {
332
338
preconditionFailure ( " If we have received an error or eof before, why did we get another body part? Next: \( next) " )
333
339
}
334
340
341
+ if buffer. isEmpty, let newChunks = newChunks {
342
+ buffer = newChunks
343
+ } else if let newChunks = newChunks {
344
+ buffer. append ( contentsOf: newChunks)
345
+ }
346
+
335
347
self . state = . executing( executor, requestState, . buffering( buffer, next: . eof) )
336
348
return . none
337
349
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)
342
359
343
360
case . redirected( let head, let redirectURL) :
344
361
self . state = . finished( error: nil )
@@ -421,7 +438,7 @@ extension RequestBag.StateMachine {
421
438
}
422
439
423
440
// buffer is empty, wait for more
424
- self . state = . executing( executor, requestState, . waitingForRemote( buffer ) )
441
+ self . state = . executing( executor, requestState, . waitingForRemote)
425
442
return . requestMoreFromExecutor( executor)
426
443
427
444
case . executing( let executor, let requestState, . buffering( var buffer, next: . eof) ) :
@@ -482,7 +499,7 @@ extension RequestBag.StateMachine {
482
499
case . executing( let executor, _, . initialized) :
483
500
self . state = . finished( error: error)
484
501
return . failTask( nil , executor)
485
- case . executing( let executor, _, . waitingForRemote( _ ) ) :
502
+ case . executing( let executor, _, . waitingForRemote) :
486
503
self . state = . finished( error: error)
487
504
return . failTask( nil , executor)
488
505
case . redirected:
0 commit comments