Skip to content

Commit 9568ecb

Browse files
committed
Fix review comments
1 parent 39833be commit 9568ecb

File tree

2 files changed

+63
-53
lines changed

2 files changed

+63
-53
lines changed

Sources/AsyncHTTPClient/AsyncAwait/HTTPClient+execute.swift

Lines changed: 44 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import struct Foundation.URL
1717
import Logging
1818
import NIOCore
19+
import NIOHTTP1
1920

2021
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
2122
extension HTTPClient {
@@ -61,7 +62,7 @@ extension HTTPClient {
6162
return try await self.followRedirect(
6263
redirectURL: redirectURL,
6364
redirectState: redirectState,
64-
request: preparedRequest,
65+
previousRequest: preparedRequest,
6566
response: response,
6667
deadline: deadline,
6768
logger: logger
@@ -73,27 +74,16 @@ extension HTTPClient {
7374
private func followRedirect(
7475
redirectURL: URL,
7576
redirectState: RedirectState,
76-
request: HTTPClientRequest.Prepared,
77+
previousRequest: HTTPClientRequest.Prepared,
7778
response: HTTPClientResponse,
7879
deadline: NIODeadline,
7980
logger: Logger
8081
) async throws -> HTTPClientResponse {
8182
var redirectState = redirectState
8283
try redirectState.redirect(to: redirectURL.absoluteString)
83-
let (method, headers, body) = transformRequestForRedirect(
84-
from: request.url,
85-
method: request.head.method,
86-
headers: request.head.headers,
87-
body: request.body,
88-
to: redirectURL,
89-
status: response.status
90-
)
91-
var newRequest = HTTPClientRequest(url: redirectURL.absoluteString)
92-
newRequest.method = method
93-
newRequest.headers = headers
94-
newRequest.body = body
84+
9585
return try await self.executeAndFollowRedirectsIfNeeded(
96-
newRequest,
86+
previousRequest.followingRedirect(to: redirectURL, status: response.status),
9787
deadline: deadline,
9888
logger: logger,
9989
redirectState: redirectState
@@ -105,44 +95,6 @@ extension HTTPClient {
10595
deadline: NIODeadline,
10696
logger: Logger
10797
) async throws -> HTTPClientResponse {
108-
/// There is currently no good way to asynchronously cancel an object that is initiated inside the `body` closure of `with*Continuation`.
109-
/// As a workaround we use `TransactionCancelHandler` which will take care of the race between instantiation of `Transaction`
110-
/// in the `body` closure and cancelation from the `onCancel` closure of `with*Continuation`.
111-
actor TransactionCancelHandler {
112-
private enum State {
113-
case initialised
114-
case register(Transaction)
115-
case cancelled
116-
}
117-
118-
private var state: State = .initialised
119-
120-
init() {}
121-
122-
func registerTransaction(_ transaction: Transaction) {
123-
switch self.state {
124-
case .initialised:
125-
self.state = .register(transaction)
126-
case .cancelled:
127-
transaction.cancel()
128-
case .register:
129-
preconditionFailure("transaction already set")
130-
}
131-
}
132-
133-
func cancel() {
134-
switch self.state {
135-
case .register(let bag):
136-
self.state = .cancelled
137-
bag.cancel()
138-
case .cancelled:
139-
break
140-
case .initialised:
141-
self.state = .cancelled
142-
}
143-
}
144-
}
145-
14698
let cancelHandler = TransactionCancelHandler()
14799

148100
return try await withTaskCancellationHandler(operation: { () async throws -> HTTPClientResponse in
@@ -170,4 +122,43 @@ extension HTTPClient {
170122
}
171123
}
172124

125+
/// There is currently no good way to asynchronously cancel an object that is initiated inside the `body` closure of `with*Continuation`.
126+
/// As a workaround we use `TransactionCancelHandler` which will take care of the race between instantiation of `Transaction`
127+
/// in the `body` closure and cancelation from the `onCancel` closure of `with*Continuation`.
128+
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
129+
private actor TransactionCancelHandler {
130+
private enum State {
131+
case initialised
132+
case register(Transaction)
133+
case cancelled
134+
}
135+
136+
private var state: State = .initialised
137+
138+
init() {}
139+
140+
func registerTransaction(_ transaction: Transaction) {
141+
switch self.state {
142+
case .initialised:
143+
self.state = .register(transaction)
144+
case .cancelled:
145+
transaction.cancel()
146+
case .register:
147+
preconditionFailure("transaction already set")
148+
}
149+
}
150+
151+
func cancel() {
152+
switch self.state {
153+
case .register(let bag):
154+
self.state = .cancelled
155+
bag.cancel()
156+
case .cancelled:
157+
break
158+
case .initialised:
159+
self.state = .cancelled
160+
}
161+
}
162+
}
163+
173164
#endif

Sources/AsyncHTTPClient/AsyncAwait/HTTPClientRequest+Prepared.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,23 @@ extension RequestBodyLength {
7474
}
7575
}
7676

77+
@available(macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0, *)
78+
extension HTTPClientRequest.Prepared {
79+
func followingRedirect(to redirectURL: URL, status: HTTPResponseStatus) -> HTTPClientRequest {
80+
let (method, headers, body) = transformRequestForRedirect(
81+
from: self.url,
82+
method: self.head.method,
83+
headers: self.head.headers,
84+
body: self.body,
85+
to: redirectURL,
86+
status: status
87+
)
88+
var newRequest = HTTPClientRequest(url: redirectURL.absoluteString)
89+
newRequest.method = method
90+
newRequest.headers = headers
91+
newRequest.body = body
92+
return newRequest
93+
}
94+
}
95+
7796
#endif

0 commit comments

Comments
 (0)