-
Notifications
You must be signed in to change notification settings - Fork 16
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
Longer POST/PUT body fails inconsistently (tests attached) #22
Comments
@dmzza Thanks for the report and repro! We think the behavior probably has to do with how we read a Vapor request into the URLRouting's request type:
I'm really not sure how the Vapor team expects us to read data from a request, but it's a bummer that it fails per the issue you link to. I did find that if we explicitly kick off a request to collect the request bytes, it does work: public func respond(
to request: Request,
chainingTo next: AsyncResponder
) async throws -> Response {
+ _ = try await request.body.collect().get()
guard let requestData = URLRequestData(request: request)
else { return try await next.respond(to: request) } But I'm not sure this is the "right" or "best" way of doing this (and I'm not sure if it causes problems for requests that don't have bodies). Do you have any other ideas/solutions we could try? Or maybe there's a way to ping the Vapor team for an update? Seems like a problem that can crop up quickly. |
Fixes #22. Request bodies of a certain size come in streaming and the properties return `nil`. We should check this and perform a check similar to what Vapor's routing tools do internally: https://github.com/vapor/vapor/blob/1d53c99b6ede0131bb02305f0d62fb2c6c830f3b/Sources/Vapor/Routing/RoutesBuilder%2BMethod.swift#L152
I assumed that line 21 was the source of the problem too, so I tried replacing that code with this. - let body: [UInt8]?
- if var buffer = request.body.data,
- let bytes = buffer.readBytes(length: buffer.readableBytes)
- {
- body = bytes
- } else {
- body = nil
- }
+ var bodyData: Data?
+ if let buffer = request.body.data,
+ let data = buffer.getData(at: buffer.readerIndex,
+ length: buffer.readableBytes,
+ byteTransferStrategy: .noCopy) {
+ bodyData = data
+ } else {
+ bodyData = nil
+ } I essentially copied that from Swift NIO's code for decoding JSON from a ByteBuffer https://github.com/apple/swift-nio/blob/dfd4bdad89c7369ce60e66259df2fe836b21f56c/Sources/NIOFoundationCompat/Codable%2BByteBuffer.swift#L31 But that solution didn't appear to affect my test results. I'll try testing your idea with other requests to see if it could be a workaround for now until we figure out the right way. |
I just noticed your commit. Thanks! I'll take a look and verify that it solves it for me. |
Fixes #22. Request bodies of a certain size come in streaming and the properties return `nil`. We should check this and perform a check similar to what Vapor's routing tools do internally: https://github.com/vapor/vapor/blob/1d53c99b6ede0131bb02305f0d62fb2c6c830f3b/Sources/Vapor/Routing/RoutesBuilder%2BMethod.swift#L152
I've created a test package with nearly the same SiteRoute used in
vapor-routing
's tests.I demonstrate several things in these tests that I've observed in real-world use.
✅ vapor-routing-test.zip
I've tried many things, but I've had no luck fixing this issue myself. I thought it might have been related to this open issue: vapor/vapor#2682 but that issue appears to be caused by the use of
data.getString(at: 0, length: data.capacity)
in the example project attached to that issue.There are a few important things you should know about running these tests
I like to pick Maximum Repetitions: 100, but 1,000 or even 10,000 will finish in a reasonable timeframe too.
The text was updated successfully, but these errors were encountered: