@@ -54,8 +54,8 @@ struct HTTPRequestStateMachine {
54
54
}
55
55
56
56
/// The request is streaming its request body. `expectedBodyLength` has a value, if the request header contained
57
- /// a `"content-length"` header field. It is the request header contained a `"transfer-encoding" = "chunked"`
58
- /// header field.
57
+ /// a `"content-length"` header field. If the request header contained a `"transfer-encoding" = "chunked"`
58
+ /// header field, the `expectedBodyLength` is `nil` .
59
59
case streaming( expectedBodyLength: Int ? , sentBodyBytes: Int , producer: ProducerControlState )
60
60
/// The request has sent its request body and end.
61
61
case endSent
@@ -73,35 +73,36 @@ struct HTTPRequestStateMachine {
73
73
case waitingForHead
74
74
/// A response head has been received and we are ready to consume more data off the wire
75
75
case receivingBody( HTTPResponseHead , ConsumerControlState )
76
- /// A response end has been received and we are ready to consume more data of the wire
76
+ /// A response end has been received. We don't expect more bytes from the wire.
77
77
case endReceived
78
78
}
79
79
80
80
enum Action {
81
81
/// A action to execute, when we consider a request "done".
82
82
enum FinalStreamAction {
83
- /// close the connection
83
+ /// Close the connection
84
84
case close
85
- /// trigger a read event
85
+ /// Trigger a read event
86
86
case read
87
- /// do nothing
87
+ /// Do nothing. This is action is used, if the request failed, before we the request head was written onto the wire.
88
+ /// This might happen if the request is cancelled, or the request failed the soundness check.
88
89
case none
89
90
}
90
91
91
92
case verifyRequest
92
93
93
- case sendRequestHead( HTTPRequestHead , startBody: Bool , startReadTimeoutTimer : TimeAmount ? )
94
+ case sendRequestHead( HTTPRequestHead , startBody: Bool )
94
95
case sendBodyPart( IOData )
95
- case sendRequestEnd( startReadTimeoutTimer : TimeAmount ? )
96
+ case sendRequestEnd
96
97
97
98
case pauseRequestBodyStream
98
99
case resumeRequestBodyStream
99
100
100
101
case forwardResponseHead( HTTPResponseHead , pauseRequestBodyStream: Bool )
101
- case forwardResponseBodyPart( ByteBuffer , resetReadTimeoutTimer : TimeAmount ? )
102
+ case forwardResponseBodyPart( ByteBuffer )
102
103
103
- case failRequest( Error , FinalStreamAction , clearReadTimeoutTimer : Bool )
104
- case succeedRequest( FinalStreamAction , clearReadTimeoutTimer : Bool )
104
+ case failRequest( Error , FinalStreamAction )
105
+ case succeedRequest( FinalStreamAction )
105
106
106
107
case read
107
108
case wait
@@ -207,8 +208,10 @@ struct HTTPRequestStateMachine {
207
208
case . running( let requestState, . receivingBody( let responseHead, . downstreamIsConsuming( readPending: false ) ) ) :
208
209
self . state = . running( requestState, . receivingBody( responseHead, . downstreamIsConsuming( readPending: true ) ) )
209
210
return . wait
210
- case . running( let requestState, . receivingBody( let responseHead, . downstreamHasDemand) ) :
211
- self . state = . running( requestState, . receivingBody( responseHead, . downstreamHasDemand) )
211
+ case . running( _, . receivingBody( _, . downstreamHasDemand) ) :
212
+ // The consumer has signaled a demand for more response body bytes. If a `read` is
213
+ // caught, we pass it on right away. The state machines does not transition into another
214
+ // state.
212
215
return . read
213
216
}
214
217
}
@@ -220,10 +223,10 @@ struct HTTPRequestStateMachine {
220
223
case . verifyingRequest, . waitForChannelToBecomeWritable:
221
224
// the request failed, before it was sent onto the wire.
222
225
self . state = . failed( error)
223
- return . failRequest( error, . none, clearReadTimeoutTimer : false )
226
+ return . failRequest( error, . none)
224
227
case . running:
225
228
self . state = . failed( error)
226
- return . failRequest( error, . close, clearReadTimeoutTimer : false )
229
+ return . failRequest( error, . close)
227
230
case . finished, . failed:
228
231
preconditionFailure ( " If the request is finished or failed, we expect the connection state machine to remove the request immediately from its state. Thus this state is unreachable. " )
229
232
}
@@ -269,17 +272,10 @@ struct HTTPRequestStateMachine {
269
272
// pause. The reason for this is as follows: There might be thread synchronization
270
273
// situations in which the producer might not have received the plea to pause yet.
271
274
272
- if let expected = expectedBodyLength {
273
- if sentBodyBytes + part. readableBytes > expected {
274
- let error = HTTPClientError . bodyLengthMismatch
275
-
276
- var clearReadTimeoutTimer = false
277
- if case . receivingBody = responseState, self . idleReadTimeout != nil {
278
- clearReadTimeoutTimer = true
279
- }
275
+ if let expected = expectedBodyLength, sentBodyBytes + part. readableBytes > expected {
276
+ let error = HTTPClientError . bodyLengthMismatch
280
277
281
- return . failRequest( error, . close, clearReadTimeoutTimer: clearReadTimeoutTimer)
282
- }
278
+ return . failRequest( error, . close)
283
279
}
284
280
285
281
sentBodyBytes += part. readableBytes
@@ -324,33 +320,33 @@ struct HTTPRequestStateMachine {
324
320
if let expected = expectedBodyLength, expected != sentBodyBytes {
325
321
let error = HTTPClientError . bodyLengthMismatch
326
322
self . state = . failed( error)
327
- return . failRequest( error, . close, clearReadTimeoutTimer : false )
323
+ return . failRequest( error, . close)
328
324
}
329
325
330
326
self . state = . running( . endSent, . waitingForHead)
331
- return . sendRequestEnd( startReadTimeoutTimer : self . idleReadTimeout )
327
+ return . sendRequestEnd
332
328
333
329
case . running( . streaming( let expectedBodyLength, let sentBodyBytes, _) , . receivingBody( let head, let streamState) ) :
334
330
assert ( head. status. code < 300 )
335
331
336
332
if let expected = expectedBodyLength, expected != sentBodyBytes {
337
333
let error = HTTPClientError . bodyLengthMismatch
338
334
self . state = . failed( error)
339
- return . failRequest( error, . close, clearReadTimeoutTimer : self . idleReadTimeout != nil )
335
+ return . failRequest( error, . close)
340
336
}
341
337
342
338
self . state = . running( . endSent, . receivingBody( head, streamState) )
343
- return . sendRequestEnd( startReadTimeoutTimer : self . idleReadTimeout )
339
+ return . sendRequestEnd
344
340
345
341
case . running( . streaming( let expectedBodyLength, let sentBodyBytes, _) , . endReceived) :
346
342
if let expected = expectedBodyLength, expected != sentBodyBytes {
347
343
let error = HTTPClientError . bodyLengthMismatch
348
344
self . state = . failed( error)
349
- return . failRequest( error, . close, clearReadTimeoutTimer : false )
345
+ return . failRequest( error, . close)
350
346
}
351
347
352
348
self . state = . finished
353
- return . succeedRequest( . none, clearReadTimeoutTimer : false )
349
+ return . succeedRequest( . none)
354
350
355
351
case . failed:
356
352
return . wait
@@ -362,16 +358,11 @@ struct HTTPRequestStateMachine {
362
358
case . initialized, . verifyingRequest, . waitForChannelToBecomeWritable:
363
359
let error = HTTPClientError . cancelled
364
360
self . state = . failed( error)
365
- return . failRequest( error, . none, clearReadTimeoutTimer : false )
366
- case . running( _ , let responseState ) :
361
+ return . failRequest( error, . none)
362
+ case . running:
367
363
let error = HTTPClientError . cancelled
368
364
self . state = . failed( error)
369
-
370
- var clearReadTimeoutTimer = false
371
- if case . receivingBody = responseState, self . idleReadTimeout != nil {
372
- clearReadTimeoutTimer = true
373
- }
374
- return . failRequest( error, . close, clearReadTimeoutTimer: clearReadTimeoutTimer)
365
+ return . failRequest( error, . close)
375
366
case . finished:
376
367
return . wait
377
368
case . failed:
@@ -381,19 +372,10 @@ struct HTTPRequestStateMachine {
381
372
382
373
mutating func channelInactive( ) -> Action {
383
374
switch self . state {
384
- case . initialized, . verifyingRequest, . waitForChannelToBecomeWritable:
385
- let error = HTTPClientError . remoteConnectionClosed
386
- self . state = . failed( error)
387
- return . failRequest( error, . none, clearReadTimeoutTimer: false )
388
- case . running( _, let responseState) :
375
+ case . initialized, . verifyingRequest, . waitForChannelToBecomeWritable, . running:
389
376
let error = HTTPClientError . remoteConnectionClosed
390
377
self . state = . failed( error)
391
-
392
- var clearReadTimeoutTimer = false
393
- if case . receivingBody = responseState, self . idleReadTimeout != nil {
394
- clearReadTimeoutTimer = true
395
- }
396
- return . failRequest( error, . none, clearReadTimeoutTimer: clearReadTimeoutTimer)
378
+ return . failRequest( error, . none)
397
379
case . finished:
398
380
return . wait
399
381
case . failed:
@@ -457,12 +439,12 @@ struct HTTPRequestStateMachine {
457
439
458
440
case . running( let requestState, . receivingBody( let head, . downstreamHasDemand) ) :
459
441
self . state = . running( requestState, . receivingBody( head, . downstreamIsConsuming( readPending: false ) ) )
460
- return . forwardResponseBodyPart( body, resetReadTimeoutTimer : self . idleReadTimeout )
442
+ return . forwardResponseBodyPart( body)
461
443
462
444
case . running( _, . receivingBody( _, . downstreamIsConsuming) ) :
463
445
// the state doesn't need to be changed. we are already in the correct state.
464
446
// just forward the data.
465
- return . forwardResponseBodyPart( body, resetReadTimeoutTimer : self . idleReadTimeout )
447
+ return . forwardResponseBodyPart( body)
466
448
467
449
case . running( _, . endReceived) , . finished:
468
450
preconditionFailure ( " How can we successfully finish the request, before having received a head. Invalid state: \( self . state) " )
@@ -490,7 +472,7 @@ struct HTTPRequestStateMachine {
490
472
assert ( head. status. code >= 300 )
491
473
assert ( producerState == . paused, " Expected to have paused the request body stream, when the head was received. Invalid state: \( self . state) " )
492
474
self . state = . finished
493
- return . succeedRequest( . close, clearReadTimeoutTimer : self . idleReadTimeout != nil )
475
+ return . succeedRequest( . close)
494
476
495
477
case . running( . endSent, . receivingBody( _, let streamState) ) :
496
478
let finalAction : Action . FinalStreamAction
@@ -502,7 +484,7 @@ struct HTTPRequestStateMachine {
502
484
}
503
485
504
486
self . state = . finished
505
- return . succeedRequest( finalAction, clearReadTimeoutTimer : self . idleReadTimeout != nil )
487
+ return . succeedRequest( finalAction)
506
488
507
489
case . running( _, . endReceived) , . finished:
508
490
preconditionFailure ( " How can we receive a response end, if another one was already received. Invalid state: \( self . state) " )
@@ -546,7 +528,7 @@ struct HTTPRequestStateMachine {
546
528
case . running( . endSent, . waitingForHead) , . running( . endSent, . receivingBody) :
547
529
let error = HTTPClientError . readTimeout
548
530
self . state = . failed( error)
549
- return . failRequest( error, . close, clearReadTimeoutTimer : false )
531
+ return . failRequest( error, . close)
550
532
551
533
case . running( . endSent, . endReceived) :
552
534
preconditionFailure ( " Invalid state. This state should be: .finished " )
@@ -559,13 +541,13 @@ struct HTTPRequestStateMachine {
559
541
private mutating func startSendingRequestHead( _ head: HTTPRequestHead ) -> Action {
560
542
if let value = head. headers. first ( name: " content-length " ) , let length = Int ( value) , length > 0 {
561
543
self . state = . running( . streaming( expectedBodyLength: length, sentBodyBytes: 0 , producer: . producing) , . waitingForHead)
562
- return . sendRequestHead( head, startBody: true , startReadTimeoutTimer : nil )
544
+ return . sendRequestHead( head, startBody: true )
563
545
} else if head. headers. contains ( name: " transfer-encoding " ) {
564
546
self . state = . running( . streaming( expectedBodyLength: nil , sentBodyBytes: 0 , producer: . producing) , . waitingForHead)
565
- return . sendRequestHead( head, startBody: true , startReadTimeoutTimer : nil )
547
+ return . sendRequestHead( head, startBody: true )
566
548
} else {
567
549
self . state = . running( . endSent, . waitingForHead)
568
- return . sendRequestHead( head, startBody: false , startReadTimeoutTimer : self . idleReadTimeout )
550
+ return . sendRequestHead( head, startBody: false )
569
551
}
570
552
}
571
553
}
0 commit comments