-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
Feature: Provide RequestBody.create WITHOUT default charset=utf-8 #3081
Comments
There are cases where adding charset=utf-8 breaks server-side implementations, most notably, Amazon AWS Gateway API JSON model mapping. JSON's default encoding is UTF-8 per https://tools.ietf.org/html/rfc7158#section-8.1 so sending an "application/json" should be equivalent to "application/json; charset=utf-8". Proposal: Introduce another RequestBody.create OR modify MediaType to handle contentType="". And please don't break current work-around: public static RequestBody create(final MediaType contentType, final byte[] content Line 46: RequestBody.java
|
You should also ask Amazon to fix their API. Not accepting the UTF-8 charset is certainly an easy-to-fix mistake. |
|
You can opt-out of this behavior with the |
okHttp code would be better served by using principle of "least surprise". In this case, a developer sets the MediaType to NADA, feeds it to RequestBody. The "least surprising" thing is the header is set as per the developers instruction not shove a charset=XXX modifier on the header - something that is NOT required by the spec. In any case, I'll let the issue go. |
This issue is also causing problems when trying to access the Dropbox API from React-Native. There are also a few other examples mentioned in this thread: facebook/react-native#8237 Although the "charset=utf-8" part is technically valid, it seems to be unexpected by many servers and so breaks many APIs. In my opinion, the lib shouldn't modify the content-type in any way. If the developer sets a charset, then append it, but otherwise leave it as it is. |
I got exactly the same problem using the dropbox upload API from react native. |
@matt-42, I've contacted Dropbox support and they told me they have now raised the issue with the engineering team to see if they can change that behavior, so hopefully it will be fixed at some point. |
This should work:
With okhttp it becomes I agree with @SoftwareArtisan . And regarding using If okhttp wishes to keep its current behavior, would at least it be possible to honor MIME type parameters and |
The workaround @swankjesse suggested is still working. As such, personally I think OkHttp should continue to do the most correct thing in the default cases.
@ceefour is "Content-Encoding: base64" valid and common in some APIs? |
@yschimke the problem is not everybody is able to access okhttp directly, e.g. people coming from React Native, especially CRNA and Expo where accessing Java code is not possible. There are a lot of people using RN/CRNA/Expo. Base64 is currently ubiquitous in the RN world due to weird RN Networking APIs (which lead to facebook/react-native#8237); and AWS S3 supports it. However, my point is not about Base64 specifically. It's that there are only limited Content-Types where I'd argue that setting |
image/* won't have it set unless you also base64 encode and send as a string, at which point arguably you should specify ASCII anyway? If you send images as byte[] it won't happen. So it seems like this is where the handling should happen, not in OkHttp. |
I think the right fix here is to change React Native to offer an API that does what you need. It's unfortunate that your frameworks don't give you access to the features that do what you want; changing OkHttp to accommodate this is intractible. |
@swankjesse I agree that it's possible for React Native to use Consider the original request, application/json does not accept charset parameter - RFC 7158 section 11. Regardless whether the content body is a string or byte[], a client should not append a charset parameter for the simple reason that the MIME type doesn't support it. |
@yschimke "image/* won't have it set unless you also base64 encode and send as a string, at which point arguably you should specify ASCII anyway?" No,
To get the HTML string, what you'd do is:
|
@ceefour That is fine and supported. You should just provide a byte[] instead of asking OkHttp to do the string encoding, and add the charset parameter for you. OkHttp doesn't currently encode specific logic for all these MediaTypes. i.e. rfc7158 isn't considered by OkHttp currently, but the library doesn't contradict if if used properly. |
I have come across at least 2 vendor APIs that have similar issues. They are proprietary APIs. When I request that they change their API to accommodate common standards, they say no. While it might not be ideal, it is a common issue when dealing with eclectic HTTP APIs that specifying a charset will cause the request to fail. |
Use axios to resolve this: |
I just spend a lot of time on this because i didn't realize okhttp adds headers i don't know about ... Please add a note in the method description, so that we know whats going on inside. |
Having the same issue with MS Dynamics API. |
Had the same problem with Amazon API Gateway, my workaround was using addNetworkInterceptor to overwrite the Content-Type header: FixContentTypeInterceptor.java:
Main.java:
|
already exists! Don’t send pull requests to implement new features without first getting our
support. Sometimes we leave features out on purpose to keep the project small.
There are cases where adding charset=utf-8 breaks server-side implementations, most notably, Amazon AWS Gateway API JSON model mapping.
JSON's default encoding is UTF-8 per https://tools.ietf.org/html/rfc7158#section-8.1 so sending an "application/json" should be equivalent to "application/json; charset=utf-8".
Proposal:
Introduce another RequestBody.create OR modify MediaType to handle contentType="".
And please don't break current work-around:
public static RequestBody create(final MediaType contentType, final byte[] content
Line 46: RequestBody.java
The text was updated successfully, but these errors were encountered: