Skip to content

Commit 768f1cf

Browse files
committed
store executed redirectTask in RequestBag and propagate cancellation
1 parent 333f511 commit 768f1cf

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

Sources/AsyncHTTPClient/HTTPHandler.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,7 @@ internal struct RedirectHandler<ResponseType> {
956956
status: HTTPResponseStatus,
957957
to redirectURL: URL,
958958
promise: EventLoopPromise<ResponseType>
959-
) {
959+
) -> HTTPClient.Task<ResponseType>? {
960960
do {
961961
var redirectState = self.redirectState
962962
try redirectState.redirect(to: redirectURL.absoluteString)
@@ -976,13 +976,19 @@ internal struct RedirectHandler<ResponseType> {
976976
headers: headers,
977977
body: body
978978
)
979-
self.execute(newRequest, redirectState).futureResult.whenComplete { result in
979+
980+
let newTask = self.execute(newRequest, redirectState)
981+
982+
newTask.futureResult.whenComplete { result in
980983
promise.futureResult.eventLoop.execute {
981984
promise.completeWith(result)
982985
}
983986
}
987+
988+
return newTask
984989
} catch {
985990
promise.fail(error)
991+
return nil
986992
}
987993
}
988994
}

Sources/AsyncHTTPClient/RequestBag+StateMachine.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ extension RequestBag.StateMachine {
594594
enum FailAction {
595595
case failTask(Error, HTTPRequestScheduler?, HTTPRequestExecutor?)
596596
case cancelExecutor(HTTPRequestExecutor)
597+
case propagateCancellation
597598
case none
598599
}
599600

@@ -624,8 +625,11 @@ extension RequestBag.StateMachine {
624625
self.state = .finished(error: error)
625626
return .failTask(error, nil, nil)
626627
case .finished(.none):
627-
// An error occurred after the request has finished. Ignore...
628-
return .none
628+
if (error as? HTTPClientError) == .cancelled {
629+
return .propagateCancellation
630+
} else {
631+
return .none
632+
}
629633
case .deadlineExceededWhileQueued:
630634
let realError: Error = {
631635
if (error as? HTTPClientError) == .cancelled {

Sources/AsyncHTTPClient/RequestBag.swift

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ final class RequestBag<Delegate: HTTPClientResponseDelegate> {
4343
// the consume body part stack depth is synchronized on the task event loop.
4444
private var consumeBodyPartStackDepth: Int
4545

46+
// if a redirect occurs, we store the task for it so we can propagate cancellation
47+
private var redirectTask: HTTPClient.Task<Delegate.Response>? = nil
48+
4649
// MARK: HTTPClientTask properties
4750

4851
var logger: Logger {
@@ -234,7 +237,7 @@ final class RequestBag<Delegate: HTTPClientResponseDelegate> {
234237
executor.demandResponseBodyStream(self)
235238

236239
case .redirect(let executor, let handler, let head, let newURL):
237-
handler.redirect(status: head.status, to: newURL, promise: self.task.promise)
240+
self.redirectTask = handler.redirect(status: head.status, to: newURL, promise: self.task.promise)
238241
executor.cancelRequest(self)
239242

240243
case .forwardResponseHead(let head):
@@ -258,7 +261,7 @@ final class RequestBag<Delegate: HTTPClientResponseDelegate> {
258261
executor.demandResponseBodyStream(self)
259262

260263
case .redirect(let executor, let handler, let head, let newURL):
261-
handler.redirect(status: head.status, to: newURL, promise: self.task.promise)
264+
self.redirectTask = handler.redirect(status: head.status, to: newURL, promise: self.task.promise)
262265
executor.cancelRequest(self)
263266

264267
case .forwardResponsePart(let part):
@@ -294,7 +297,7 @@ final class RequestBag<Delegate: HTTPClientResponseDelegate> {
294297
}
295298

296299
case .redirect(let handler, let head, let newURL):
297-
handler.redirect(status: head.status, to: newURL, promise: self.task.promise)
300+
self.redirectTask = handler.redirect(status: head.status, to: newURL, promise: self.task.promise)
298301
}
299302
}
300303

@@ -368,6 +371,8 @@ final class RequestBag<Delegate: HTTPClientResponseDelegate> {
368371
self.failTask0(error)
369372
case .cancelExecutor(let executor):
370373
executor.cancelRequest(self)
374+
case .propagateCancellation:
375+
self.redirectTask?.cancel()
371376
case .none:
372377
break
373378
}

0 commit comments

Comments
 (0)