-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Implement URLSessionTaskDelegate needNewBodyStream method #715
Conversation
/// A Foundation `OutputStream` that will read from the `ReadableStream`. | ||
/// | ||
/// Will be replaced when `replaceStreams(_:)` is called to replace the input stream. | ||
private var outputStream: OutputStream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Input & output Foundation streams are now var
s because they may need to be replaced during a HTTP request.
(inputStream, outputStream) = Self.makeStreams(boundStreamBufferSize: self.boundStreamBufferSize, queue: queue) | ||
} | ||
|
||
func replaceStreams(completion: @escaping (InputStream?) -> Void) async { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method will be called by the HTTP client when a new body stream is needed.
The output stream is closed, both streams are replaced with new ones & configured, and the output stream is reopened.
Note that I never do anything to the input stream, only the URLSessionDataTask ever manipulates that stream.
await open() | ||
} | ||
|
||
private static func makeStreams(boundStreamBufferSize: Int, queue: DispatchQueue) -> (InputStream, OutputStream) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method just extracts the stream creation logic from the initializer so it can be used to replace the streams as well as at this class's initialization.
@@ -14,6 +14,9 @@ extension URLSessionConfiguration { | |||
public static func from(httpClientConfiguration: HttpClientConfiguration) -> URLSessionConfiguration { | |||
let config = URLSessionConfiguration.default | |||
config.timeoutIntervalForRequest = httpClientConfiguration.socketTimeout | |||
config.httpShouldSetCookies = false | |||
config.httpCookieAcceptPolicy = .never | |||
config.httpCookieStorage = nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not strictly related to the rest of this PR but this should be done... the URLSession is configured to ignore cookies completely.
AWS HTTP APIs should never use cookies, but this guards against any weirdness from a proxy or gateway a customer may use.
(lol been bit by this before on other apps, hence I'm adding it here)
/// - Parameters: | ||
/// - session: The `URLSession` the task belongs to. | ||
/// - task: The `URLSessionTask` that needs a new body stream. | ||
/// - completionHandler: A block to be called with the new `InputStream` when it is ready. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This delegate method replaces the InputStream
used for body streaming on request.
The FoundationStreamBridge
performs the actual replacement, then informs the completion block of the new stream.
The guard
below should never fail, because this only gets called when an input stream is used, and the only way we make an input stream is through a FoundationStreamBridge
.
Issue #
awslabs/aws-sdk-swift#1457
Description of changes
urlSession(_:task:needNewBodyStream:)
delegate method. This method must be implemented wheneverURLRequest
input body streaming is used. When called, theFoundationStreamBridge
replaces its bound stream pair and passes the newInputStream
to theURLSessionTask
.Also:
URLSession
to never handle cookies, which are not set or used on AWS API endpoints.Scope
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.