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

React-Native appends "charset=utf-8" to HTTP call Content-Type #14445

Open
laurent22 opened this Issue Jun 10, 2017 · 14 comments

Comments

Projects
None yet
@laurent22

laurent22 commented Jun 10, 2017

Description

I'm trying to use the Dropbox API with React-Native but when I try to call filesUpload I'm getting the following error:

Error in call to API function "files/upload": Bad HTTP "Content-Type" header: "application/octet-stream; charset=utf-8".  Expecting one of "application/octet-stream", "text/plain; charset=dropbox-cors-hack".

The Dropbox SDK makes use of the superagent library and it sets up the call like this:

apiRequest = request.post(getBaseURL(host) + path)
  .type('application/octet-stream')
  .set('Authorization', 'Bearer ' + accessToken)
  .set('Dropbox-API-Arg', httpHeaderSafeJson(args));

So the content-type is set to just "application/octet-stream" but when the request is eventually executed it's changed to "application/octet-stream; charset=utf-8". I'm assuming the SDK works fine in Node or in a browser, and that it's something that React-Native is adding. Is it a known issue? Is there any way to go around it?

Solution

Make sure that HTTP calls coming from React-Native do not append ; charset=utf-8 to the Content-Type (or make it optional).

Additional Information

  • React Native version: 0.44
  • Platform: Android (running on emulator under Windows)
  • Development Operating System: Windows 10
  • Dev tools: Android Studio
@hramos

This comment has been minimized.

Show comment
Hide comment
@hramos

hramos Jun 12, 2017

Contributor

As this involves a third party library, can you try and reproduce this using fetch()? If RN is modifying the request in the way you describe, then the behavior can likely be observed using fetch().

Contributor

hramos commented Jun 12, 2017

As this involves a third party library, can you try and reproduce this using fetch()? If RN is modifying the request in the way you describe, then the behavior can likely be observed using fetch().

@laurent22

This comment has been minimized.

Show comment
Hide comment
@laurent22

laurent22 Jun 13, 2017

After some digging, it seems to be related to the okhttp library. I've put my findings in this related issue:

#8237 (comment)

I've also added a comment to the okhttp issue but it doesn't look like they are going to fix it:

square/okhttp#3081 (comment)

laurent22 commented Jun 13, 2017

After some digging, it seems to be related to the okhttp library. I've put my findings in this related issue:

#8237 (comment)

I've also added a comment to the okhttp issue but it doesn't look like they are going to fix it:

square/okhttp#3081 (comment)

@ericwooley

This comment has been minimized.

Show comment
Hide comment
@ericwooley

ericwooley Jun 22, 2017

I am having the same issue using super agent directly, in emulators and on device. It doesn't occur in ios.

If i find a solution I will post it here

I am having the same issue with XHR requests.

xhr.open("POST", "https://REDACTED");
xhr.setRequestHeader("content-type", "application/vnd.api+json");
xhr.setRequestHeader("authorization", "Bearer REDACTED");
xhr.setRequestHeader("cache-control", "no-cache");

xhr.send(data);

Charles shows application/vnd.api+json; charset=utf-8 as the content-header

as @laurent22 points out, it's okhttp adding the content not superagent. I didn't realize that okhttp was a java library, not js library.

another issue to read is square/okhttp#2099 where they suggest:

  1. Fix the server to allow the utf-8;
  2. Second, work around the problem by manually converting the string to UTF-8 bytes with getBytes() and use the byte[] to create the response body.

I tracked down react native code as far as here https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.java#L123

But i am out of time to figure out further tonight. If i get time over the weekend I'll keep going.

ericwooley commented Jun 22, 2017

I am having the same issue using super agent directly, in emulators and on device. It doesn't occur in ios.

If i find a solution I will post it here

I am having the same issue with XHR requests.

xhr.open("POST", "https://REDACTED");
xhr.setRequestHeader("content-type", "application/vnd.api+json");
xhr.setRequestHeader("authorization", "Bearer REDACTED");
xhr.setRequestHeader("cache-control", "no-cache");

xhr.send(data);

Charles shows application/vnd.api+json; charset=utf-8 as the content-header

as @laurent22 points out, it's okhttp adding the content not superagent. I didn't realize that okhttp was a java library, not js library.

another issue to read is square/okhttp#2099 where they suggest:

  1. Fix the server to allow the utf-8;
  2. Second, work around the problem by manually converting the string to UTF-8 bytes with getBytes() and use the byte[] to create the response body.

I tracked down react native code as far as here https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/modules/network/RequestBodyUtil.java#L123

But i am out of time to figure out further tonight. If i get time over the weekend I'll keep going.

@dauane

This comment has been minimized.

Show comment
Hide comment
@dauane

dauane Jul 11, 2017

I have the same issue. Tried using different third party libraries and even RN fetch. It all failed.

dauane commented Jul 11, 2017

I have the same issue. Tried using different third party libraries and even RN fetch. It all failed.

@dauane

This comment has been minimized.

Show comment
Hide comment
@dauane

dauane Jul 11, 2017

Fixing the server was the simplest solution for me. Thanks @ericwooley

dauane commented Jul 11, 2017

Fixing the server was the simplest solution for me. Thanks @ericwooley

@hramos

This comment has been minimized.

Show comment
Hide comment
@hramos

hramos Sep 21, 2017

Contributor

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

Contributor

hramos commented Sep 21, 2017

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

@hramos hramos added the Icebox label Sep 21, 2017

@hramos hramos closed this Sep 21, 2017

@laurent22

This comment has been minimized.

Show comment
Hide comment
@laurent22

laurent22 Sep 21, 2017

@hramos , this is still a major issue for me and quite a few others. The Dropbox API still cannot be used from React Native, which prevents me from adding support for it in my app. It would be good if the issue could be re-opened. It's still not working in the latest release candidate and as far as I know there's currently no pull request addressing the issue.

laurent22 commented Sep 21, 2017

@hramos , this is still a major issue for me and quite a few others. The Dropbox API still cannot be used from React Native, which prevents me from adding support for it in my app. It would be good if the issue could be re-opened. It's still not working in the latest release candidate and as far as I know there's currently no pull request addressing the issue.

@Kottidev

This comment has been minimized.

Show comment
Hide comment
@Kottidev

Kottidev Oct 10, 2017

@hramos , Our server does not prepare api for “utf-8”, and android avd sent requests with “charset=utf-8". So it cause 500 status error.

the issue should be re-opened

Kottidev commented Oct 10, 2017

@hramos , Our server does not prepare api for “utf-8”, and android avd sent requests with “charset=utf-8". So it cause 500 status error.

the issue should be re-opened

@hramos hramos reopened this Oct 10, 2017

@tastafur

This comment has been minimized.

Show comment
Hide comment
@tastafur

tastafur Oct 18, 2017

In our react-native application we have the same problem

tastafur commented Oct 18, 2017

In our react-native application we have the same problem

@ferroblesh

This comment has been minimized.

Show comment
Hide comment
@ferroblesh

ferroblesh Oct 31, 2017

same thing here. It's incredible that react native claims to be same core and uses different kind of http request for each platform. It should be same behavior on both sides

ferroblesh commented Oct 31, 2017

same thing here. It's incredible that react native claims to be same core and uses different kind of http request for each platform. It should be same behavior on both sides

@lil5

This comment has been minimized.

Show comment
Hide comment
@lil5

lil5 Dec 10, 2017

Here's a workaround #13487 (comment)

lil5 commented Dec 10, 2017

Here's a workaround #13487 (comment)

@Schonhoffer

This comment has been minimized.

Show comment
Hide comment
@Schonhoffer

Schonhoffer Dec 20, 2017

For anyone else stuck, here's what I did to get around it.

npm install --save buffer

import { Buffer } from 'buffer'

let content = "foo";
let resp = await fetch(
            'https://content.dropboxapi.com/2/files/upload', {
            method: 'POST',
            body:  Buffer.from(content, 'utf8'),
            headers: new Headers({
              'Authorization': 'Bearer ' + this._accessToken,
              'Dropbox-API-Arg': JSON.stringify(args),
              'Content-Length' : content.length,
              'Content-Type': 'application/octet-stream'
            })}
        );

Schonhoffer commented Dec 20, 2017

For anyone else stuck, here's what I did to get around it.

npm install --save buffer

import { Buffer } from 'buffer'

let content = "foo";
let resp = await fetch(
            'https://content.dropboxapi.com/2/files/upload', {
            method: 'POST',
            body:  Buffer.from(content, 'utf8'),
            headers: new Headers({
              'Authorization': 'Bearer ' + this._accessToken,
              'Dropbox-API-Arg': JSON.stringify(args),
              'Content-Length' : content.length,
              'Content-Type': 'application/octet-stream'
            })}
        );
@Dubidubiduu

This comment has been minimized.

Show comment
Hide comment
@Dubidubiduu

Dubidubiduu Jan 18, 2018

Please can someone solves this bug? Waiting for nextcloud support which isn't developed before closing this bug: http://joplin.cozic.net/

Dubidubiduu commented Jan 18, 2018

Please can someone solves this bug? Waiting for nextcloud support which isn't developed before closing this bug: http://joplin.cozic.net/

@vovkasm

This comment has been minimized.

Show comment
Hide comment
@vovkasm

vovkasm Jan 19, 2018

Contributor

@Schonhoffer excellent!
Buffer will use ArrayBuffer, then
in convertRequestBody.js it will be encoded as base64 to marshal JS->Java, finally
in NetworkingModule.java it will properly reach OkHttp as ByteString!

@Dubidubiduu try solution from @Schonhoffer it should work.

Contributor

vovkasm commented Jan 19, 2018

@Schonhoffer excellent!
Buffer will use ArrayBuffer, then
in convertRequestBody.js it will be encoded as base64 to marshal JS->Java, finally
in NetworkingModule.java it will properly reach OkHttp as ByteString!

@Dubidubiduu try solution from @Schonhoffer it should work.

@threkk threkk referenced this issue Feb 12, 2018

Closed

Dropbox synchronisation? #210

8 of 8 tasks complete

@hramos hramos removed the Icebox label Mar 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment