@@ -29,15 +29,15 @@ extension HTTPClient {
29
29
extension RequestBag {
30
30
struct StateMachine {
31
31
fileprivate enum State {
32
- case initialized
33
- case queued( HTTPRequestScheduler )
32
+ case initialized( RedirectHandler < Delegate . Response > ? )
33
+ case queued( HTTPRequestScheduler , RedirectHandler < Delegate . Response > ? )
34
34
/// if the deadline was exceeded while in the `.queued(_:)` state,
35
35
/// we wait until the request pool fails the request with a potential more descriptive error message,
36
36
/// if a connection failure has occured while the request was queued.
37
37
case deadlineExceededWhileQueued
38
38
case executing( HTTPRequestExecutor , RequestStreamState , ResponseStreamState )
39
39
case finished( error: Error ? )
40
- case redirected( HTTPRequestExecutor , Int , HTTPResponseHead , URL )
40
+ case redirected( HTTPRequestExecutor , RedirectHandler < Delegate . Response > , Int , HTTPResponseHead , URL )
41
41
case modifying
42
42
}
43
43
@@ -55,23 +55,22 @@ extension RequestBag {
55
55
case eof
56
56
}
57
57
58
- case initialized
58
+ case initialized( RedirectHandler < Delegate . Response > ? )
59
59
case buffering( CircularBuffer < ByteBuffer > , next: Next )
60
60
case waitingForRemote
61
61
}
62
62
63
- private var state : State = . initialized
64
- private let redirectHandler : RedirectHandler < Delegate . Response > ?
63
+ private var state : State
65
64
66
65
init ( redirectHandler: RedirectHandler < Delegate . Response > ? ) {
67
- self . redirectHandler = redirectHandler
66
+ self . state = . initialized ( redirectHandler)
68
67
}
69
68
}
70
69
}
71
70
72
71
extension RequestBag . StateMachine {
73
72
mutating func requestWasQueued( _ scheduler: HTTPRequestScheduler ) {
74
- guard case . initialized = self . state else {
73
+ guard case . initialized( let redirectHandler ) = self . state else {
75
74
// There might be a race between `requestWasQueued` and `willExecuteRequest`:
76
75
//
77
76
// If the request is created and passed to the HTTPClient on thread A, it will move into
@@ -91,7 +90,7 @@ extension RequestBag.StateMachine {
91
90
return
92
91
}
93
92
94
- self . state = . queued( scheduler)
93
+ self . state = . queued( scheduler, redirectHandler )
95
94
}
96
95
97
96
enum WillExecuteRequestAction {
@@ -102,8 +101,8 @@ extension RequestBag.StateMachine {
102
101
103
102
mutating func willExecuteRequest( _ executor: HTTPRequestExecutor ) -> WillExecuteRequestAction {
104
103
switch self . state {
105
- case . initialized, . queued:
106
- self . state = . executing( executor, . initialized, . initialized)
104
+ case . initialized( let redirectHandler ) , . queued( _ , let redirectHandler ) :
105
+ self . state = . executing( executor, . initialized, . initialized( redirectHandler ) )
107
106
return . none
108
107
case . deadlineExceededWhileQueued:
109
108
let error : Error = HTTPClientError . deadlineExceeded
@@ -127,8 +126,8 @@ extension RequestBag.StateMachine {
127
126
case . initialized, . queued, . deadlineExceededWhileQueued:
128
127
preconditionFailure ( " A request stream can only be resumed, if the request was started " )
129
128
130
- case . executing( let executor, . initialized, . initialized) :
131
- self . state = . executing( executor, . producing, . initialized)
129
+ case . executing( let executor, . initialized, . initialized( let redirectHandler ) ) :
130
+ self . state = . executing( executor, . producing, . initialized( redirectHandler ) )
132
131
return . startWriter
133
132
134
133
case . executing( _, . producing, _) :
@@ -299,11 +298,11 @@ extension RequestBag.StateMachine {
299
298
case . initialized, . queued, . deadlineExceededWhileQueued:
300
299
preconditionFailure ( " How can we receive a response, if the request hasn't started yet. " )
301
300
case . executing( let executor, let requestState, let responseState) :
302
- guard case . initialized = responseState else {
301
+ guard case . initialized( let redirectHandler ) = responseState else {
303
302
preconditionFailure ( " If we receive a response, we must not have received something else before " )
304
303
}
305
304
306
- if let redirectURL = self . redirectHandler? . redirectTarget (
305
+ if let redirectHandler = redirectHandler , let redirectURL = redirectHandler. redirectTarget (
307
306
status: head. status,
308
307
responseHeaders: head. headers
309
308
) {
@@ -312,11 +311,11 @@ extension RequestBag.StateMachine {
312
311
// smaller than 3kb.
313
312
switch head. contentLength {
314
313
case . some( 0 ... ( HTTPClient . maxBodySizeRedirectResponse) ) , . none:
315
- self . state = . redirected( executor, 0 , head, redirectURL)
314
+ self . state = . redirected( executor, redirectHandler , 0 , head, redirectURL)
316
315
return . signalBodyDemand( executor)
317
316
case . some:
318
317
self . state = . finished( error: HTTPClientError . cancelled)
319
- return . redirect( executor, self . redirectHandler! , head, redirectURL)
318
+ return . redirect( executor, redirectHandler, head, redirectURL)
320
319
}
321
320
} else {
322
321
self . state = . executing( executor, requestState, . buffering( . init( ) , next: . askExecutorForMore) )
@@ -369,15 +368,15 @@ extension RequestBag.StateMachine {
369
368
} else {
370
369
return . none
371
370
}
372
- case . redirected( let executor, var receivedBytes, let head, let redirectURL) :
371
+ case . redirected( let executor, let redirectHandler , var receivedBytes, let head, let redirectURL) :
373
372
let partsLength = buffer. reduce ( into: 0 ) { $0 += $1. readableBytes }
374
373
receivedBytes += partsLength
375
374
376
375
if receivedBytes > HTTPClient . maxBodySizeRedirectResponse {
377
376
self . state = . finished( error: HTTPClientError . cancelled)
378
- return . redirect( executor, self . redirectHandler! , head, redirectURL)
377
+ return . redirect( executor, redirectHandler, head, redirectURL)
379
378
} else {
380
- self . state = . redirected( executor, receivedBytes, head, redirectURL)
379
+ self . state = . redirected( executor, redirectHandler , receivedBytes, head, redirectURL)
381
380
return . signalBodyDemand( executor)
382
381
}
383
382
@@ -428,9 +427,9 @@ extension RequestBag.StateMachine {
428
427
self . state = . executing( executor, requestState, . buffering( newChunks, next: . eof) )
429
428
return . consume( first)
430
429
431
- case . redirected( _, _, let head, let redirectURL) :
430
+ case . redirected( _, let redirectHandler , _, let head, let redirectURL) :
432
431
self . state = . finished( error: nil )
433
- return . redirect( self . redirectHandler! , head, redirectURL)
432
+ return . redirect( redirectHandler, head, redirectURL)
434
433
435
434
case . finished( error: . some) :
436
435
return . none
@@ -553,7 +552,7 @@ extension RequestBag.StateMachine {
553
552
554
553
mutating func deadlineExceeded( ) -> DeadlineExceededAction {
555
554
switch self . state {
556
- case . queued( let queuer) :
555
+ case . queued( let queuer, _ ) :
557
556
/// We do not fail the request immediately because we want to give the scheduler a chance of throwing a better error message
558
557
/// We therefore depend on the scheduler failing the request after we cancel the request.
559
558
self . state = . deadlineExceededWhileQueued
@@ -582,7 +581,7 @@ extension RequestBag.StateMachine {
582
581
case . initialized:
583
582
self . state = . finished( error: error)
584
583
return . failTask( error, nil , nil )
585
- case . queued( let queuer) :
584
+ case . queued( let queuer, _ ) :
586
585
self . state = . finished( error: error)
587
586
return . failTask( error, queuer, nil )
588
587
case . executing( let executor, let requestState, . buffering( _, next: . eof) ) :
0 commit comments