Skip to content

Commit 4cad737

Browse files
nhunzakergrabbou
authored andcommittedFeb 27, 2019
Prevent okhttp from adding ;charset=utf8 to ContentType Header (#23580)
Summary: Before this commit, `fetch()` calls append `"charset=utf8"` to the `Content-Type` header on Android (and not on iOS). This is because of an implementation detail in the okhttp library. This means that you can make a call on the JavaScript side like: ```javascript let body = JSON.stringify({ key: "value" }); let headers = { "Content-Type": "application/json" }; fetch("http://10.0.2.2:3000", { method: "POST", body, headers }); ``` However the resulting request appends the utf8 character: ``` POST - 13:34:32: content-type: application/json; charset=utf-8 content-length: 15 host: 10.0.2.2:3000 connection: Keep-Alive accept-encoding: gzip user-agent: okhttp/3.12.1 ``` Passing byte array into the RequestBody avoids this, as recommended by a maintainer of okhttp: square/okhttp#2099 (comment) Related issues: #8237 [Android][fixed] - Prevent fetch() POST requests on Android from appending `charset=utf-8` to `Content-Type` header. Pull Request resolved: #23580 Differential Revision: D14180849 Pulled By: cpojer fbshipit-source-id: b84cadf83361331a9f64d1ff5f2e6399a55527a6
1 parent fee5031 commit 4cad737

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed
 

‎ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ public void onProgress(long bytesWritten, long contentLength, boolean done) {
372372
return;
373373
}
374374
} else {
375-
requestBody = RequestBody.create(contentMediaType, body);
375+
requestBody = RequestBody.create(contentMediaType, body.getBytes(StandardCharsets.UTF_8));
376376
}
377377
} else if (data.hasKey(REQUEST_BODY_KEY_BASE64)) {
378378
if (contentType == null) {

‎ReactAndroid/src/test/java/com/facebook/react/modules/network/NetworkingModuleTest.java

+38-1
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
247247
body.putString("string", "This is request body");
248248

249249
mockEvents();
250-
250+
251251
networkingModule.sendRequest(
252252
"POST",
253253
"http://somedomain/bar",
@@ -309,6 +309,43 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
309309
assertThat(requestHeaders.get("User-Agent")).isEqualTo("React test agent/1.0");
310310
}
311311

312+
@Test
313+
public void testPostJsonContentTypeHeader() throws Exception {
314+
OkHttpClient httpClient = mock(OkHttpClient.class);
315+
when(httpClient.newCall(any(Request.class))).thenAnswer(new Answer<Object>() {
316+
@Override
317+
public Object answer(InvocationOnMock invocation) throws Throwable {
318+
Call callMock = mock(Call.class);
319+
return callMock;
320+
}
321+
});
322+
OkHttpClient.Builder clientBuilder = mock(OkHttpClient.Builder.class);
323+
when(clientBuilder.build()).thenReturn(httpClient);
324+
when(httpClient.newBuilder()).thenReturn(clientBuilder);
325+
NetworkingModule networkingModule =
326+
new NetworkingModule(mock(ReactApplicationContext.class), "", httpClient);
327+
328+
JavaOnlyMap body = new JavaOnlyMap();
329+
body.putString("string", "{ \"key\": \"value\" }");
330+
331+
networkingModule.sendRequest(
332+
"POST",
333+
"http://somedomain/bar",
334+
0,
335+
JavaOnlyArray.of(JavaOnlyArray.of("Content-Type", "application/json")),
336+
body,
337+
/* responseType */ "text",
338+
/* useIncrementalUpdates*/ true,
339+
/* timeout */ 0,
340+
/* withCredentials */ false);
341+
342+
ArgumentCaptor<Request> argumentCaptor = ArgumentCaptor.forClass(Request.class);
343+
verify(httpClient).newCall(argumentCaptor.capture());
344+
345+
// Verify okhttp does not append "charset=utf-8"
346+
assertThat(argumentCaptor.getValue().body().contentType().toString()).isEqualTo("application/json");
347+
}
348+
312349
@Test
313350
public void testMultipartPostRequestSimple() throws Exception {
314351
PowerMockito.mockStatic(RequestBodyUtil.class);

0 commit comments

Comments
 (0)
Please sign in to comment.