-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Set FusedTransformer as default #2250
Conversation
…/json fix: do not throw on empty response bodies on HEAD requests when Content-Type is json
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.
Thanks again! I have no objections to changing the default transformer, but I'd like to hear the opinions on it from the others
dio/lib/src/dio_mixin.dart
Outdated
@@ -41,7 +41,8 @@ abstract class DioMixin implements Dio { | |||
/// The default [Transformer] that transfers requests and responses | |||
/// into corresponding content to send. | |||
@override | |||
Transformer transformer = BackgroundTransformer(); | |||
Transformer transformer = | |||
FusedTransformer(contentLengthIsolateThreshold: 50 * 1024); |
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.
Can you add a comment explaining this specific number? Is it chosen rather arbitrarily or an educated guess?
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.
Does it make sense to be configurable?
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.
50 * 1024 is the hardcoded default in BackgroundTransformer, I chose the same to keep the behavior as close as possible to the old one.
I did not measure how long it takes to decode on smartphones with the new approach. I copied the rationale for the 50 KiB threshold from BackgroundTransformer now.
IMO it makes sense to make it configurable, for example, when running the whole HTTP client in a background isolate already, users might not care about blocking the isolate for a few milliseconds, so they could set a higher (or -1 to disable spawning new isolates completely).
return decodedResponse; | ||
} else { | ||
if (responseBytes.isEmpty) { |
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.
Any references?
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.
Sorry, did not mean to commit that. Is unnecessary, utf8.decode returns an empty string anyway on an empty bytes list. removed.
// Successful HEAD requests don't have a response body, even if the content-length header | ||
// present. | ||
final contentLengthHeaderImpliesContent = options.method != 'HEAD'; |
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.
- With
CONNECT
too although it's an edge case? - Also the MDN reference would be helpful to be placed here.
- Could the name be
neverHasResponseBody
and then flip all conditions to the opposite?
final neverHasResponseBody = options.method == 'CONNECT' || options.method == 'HEAD';
if (neverHasResponseBody || !hasContentLengthHeader) {
// ...
}
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 issue only occurs when the ResponseType
is .json
, the response body has a Content-Type of application/json
, and a Content-Length header with a value > 0, but no response body.
A valid CONNECT
response will have no Content-Type and no Content-Length header, so the transformer won't try to parse it as json.
A server MUST NOT send any Transfer-Encoding or Content-Length header fields in a 2xx (Successful) response to CONNECT. A client MUST ignore any Content-Length or Transfer-Encoding header fields received in a successful response to CONNECT.
I mean sure, we could also support invalid responses to CONNECT, but I'd argue if a user want's that, they should just set the ResponseType
to .plain
, .bytes
or .stream.
or use their own decoder / transformer.
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.
Cool, thanks for the explanation. But the flag should be flipped because if you are using its opposite result always you should simply flip it.
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.
true. done
Co-authored-by: Alex Li <[email protected]> Signed-off-by: Martin Kamleithner <[email protected]>
Code Coverage Report: Only Changed Files listed
Minimum allowed coverage is |
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.
fixes #2279 This improves handling of the following case: - ResponseType is json - Server Content-Type is json - Server Content-Length is nonzero - Response Body is empty This can happen in some cases according to HTTP spec (e.g. HEAD requests), but some servers return responses like this (see #2279) also in other cases, even if it violates the HTTP spec. With #2250, in some of these cases dio would throw an exception, which caused a regression for some users; see #2279 I do believe that dio should handle these cases for gracefully, This PR brings back the previous behavior of returning null. ### New Pull Request Checklist - [x] I have read the [Documentation](https://pub.dev/documentation/dio/latest/) - [x] I have searched for a similar pull request in the [project](https://github.com/cfug/dio/pulls) and found none - [x] I have updated this branch with the latest `main` branch to avoid conflicts (via merge from master or rebase) - [x] I have added the required tests to prove the fix/feature I'm adding - [x] I have updated the documentation (if necessary) - [x] I have run the tests without failures - [x] I have updated the `CHANGELOG.md` in the corresponding package ### Additional context and info (if any) <!-- Provide more context and info about the PR. --> --------- Signed-off-by: Martin Kamleithner <[email protected]> Co-authored-by: Jonas Uekötter <[email protected]>
New Pull Request Checklist
main
branch to avoid conflicts (via merge from master or rebase)CHANGELOG.md
in the corresponding packageAdditional context and info (if any)
Also fix three oversights in the transformer
Fix parsing content as JSON when Content-Type is like
application/json
butResponseType == .plain
HEAD requests have an empty body, even when Content-Length is >0. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/HEAD . I did not take this into account. This is also fixed now.
Respect custom decoders returning null