-
Notifications
You must be signed in to change notification settings - Fork 31
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
feat: Add support for flexible checksums on streaming payloads #659
Conversation
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.
Just a couple questions.
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedBufferedStream.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedBufferedStream.swift
Outdated
Show resolved
Hide resolved
…rt 0.27.0, remove content-md5 todo, add tests
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.
Will approve once all swift lint warnings get addressed.
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.
Lgtm, after corrresponding PR in aws-sdk-swift passes all CIs, should be good to go.
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedBufferedStream.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedReader.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedReader.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/Http/URLSession/FoundationStreamBridge.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedReader.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/AwsChunked/AwsChunkedUtil.swift
Outdated
Show resolved
Hide resolved
Sources/ClientRuntime/Networking/Http/Middlewares/FlexibleChecksumsRequestMiddleware.swift
Outdated
Show resolved
Hide resolved
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.
I have fixed several issues in this feature, both in this PR and in awslabs/aws-sdk-swift#1329.
Some refactoring & performance improvements are required, but will be done in a separate PR.
…ws-chunked-encoding
…thy-swift into day/aws-chunked-encoding
import AwsCommonRuntimeKit | ||
|
||
/// Reads data from the input stream, chunks it, and passes it out through its output stream. | ||
class AWSChunkedStream { |
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 used to be a protocol, I changed it to a concrete stream type that chunks its input and outputs an AWS-chunked stream.
self.outputStream.isSeekable | ||
} | ||
|
||
func read(upToCount count: Int) throws -> Data? { |
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.
read() and readAsync() will use the input stream and reader to create a new chunk once the output stream has been exhausted. This will prevent chunks from building up in memory well in advance of when they can be transmitted.
} | ||
} | ||
|
||
public func setAwsChunkedBody( |
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 now just wraps the body stream in a AWSChunkedStream when the request is chunked.
} | ||
} | ||
} | ||
|
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.
The chunk method that used to be here is removed; AWSChunkedStream and the CRT HTTP client now have their own code for this.
@@ -165,6 +165,49 @@ public class CRTClientEngine: HTTPClient { | |||
do { | |||
let stream = try connection.makeRequest(requestOptions: requestOptions) | |||
try stream.activate() | |||
if request.isChunked { |
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 block of code now incorporates the code that used to be in the static method for chunking a body.
/// Actor used to isolate the stream status from multiple concurrent accesses. | ||
actor ReadableStreamStatus { | ||
/// A Logger for logging events. | ||
private let logger: LogAgent |
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.
I put a Logger in this type, and I also fixed the issue where stream writes can get out-of-order.
@@ -130,7 +130,7 @@ public final class URLSessionHTTPClient: HTTPClient { | |||
func urlSession( | |||
_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse | |||
) async -> URLSession.ResponseDisposition { | |||
logger.debug("urlSession(_:dataTask:didReceive:) called") | |||
logger.debug("urlSession(_:dataTask:didReceive response:) called") |
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.
Logging changes in this type, plus I adjusted the buffer size for streams a bit.
@@ -61,6 +61,13 @@ public class BufferedStream: Stream { | |||
/// Access this value only while `lock` is locked, to prevent simultaneous access. | |||
private var _buffer: Data | |||
|
|||
/// The number of bytes currently in the buffer, awaiting read. | |||
public var bufferCount: Int { |
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.
Added this bufferCount
property (to see if the stream is holding any data in-memory) and a little refactoring in this type.
import SmithyTestUtil | ||
@testable import ClientRuntime | ||
|
||
class FlexibleChecksumsMiddlewareTests: XCTestCase { |
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.
I reordered some of the steps in these tests since the middleware doesn't call next()
at the very end of execution anymore.
@@ -102,7 +111,7 @@ public struct FlexibleChecksumsResponseMiddleware<OperationStackOutput>: Middlew | |||
throw ClientError.dataNotFound("Cannot calculate the checksum of an empty body!") | |||
} | |||
|
|||
return try await next.handle(context: context, input: input) | |||
return output |
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.
Rearranged where next.handle()
is called in this middleware so that multiple GET requests are not made to the server.
} else { | ||
let currentChunkBody = awsChunkedStream.chunkedReader.getCurrentChunkBody() | ||
if !currentChunkBody.isEmpty { | ||
try await http1Stream.writeChunk(chunk: awsChunkedStream.chunkedReader.getCurrentChunk(), endOfStream: false) |
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.
lint warning
Issue #
awslabs/aws-sdk-swift#1319
Description of changes
Also:
FoundationStreamBridge
where data could be written to its output out-of-order.Scope
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.