From 1a3360753b16f5908f62d1a01e8c8396fc314268 Mon Sep 17 00:00:00 2001 From: Vincent Cheung Date: Tue, 5 Nov 2019 03:28:05 -0800 Subject: [PATCH] Fix multiple `set-cookie` not aggregated correctly in response headers (#27066) Summary: Multiple `set-cookie` headers should be aggregated as one `set-cookie` with values in a comma separated list. It is working as expected on iOS but not on Android. On Android, only the last one is preserved The problem arises because `NetworkingModule.translateHeaders()` uses `WritableNativeMap` as the translated headers but uses both native and non-native methods. The mixup causes out of sync data that both sets of methods do no agree. A simple fix is to use `Bundle` as the storage and only convert it to `WritableMap` at the end in one go Related issues: https://github.com/facebook/react-native/issues/26280, https://github.com/facebook/react-native/issues/21795, https://github.com/facebook/react-native/issues/23185 ## Changelog [Android] [Fixed] - Fix multiple headers of the same name (e.g. `set-cookie`) not aggregated correctly Pull Request resolved: https://github.com/facebook/react-native/pull/27066 Test Plan: A mock api, https://demo6524373.mockable.io/, will return 2 `set-cookie` as follows: ``` set-cookie: cookie1=value1 set-cookie: cookie2=value2 ``` Verify the following will print the `set-cookie` with a value `cookie1=value1, cookie2=value2` ```javascript fetch('https://demo6524373.mockable.io/') .then(response => { console.log(response.headers); }); ``` On iOS, `set-cookie` will have `cookie1=value1, cookie2=value2` while on Android it will have `cookie2=value2` (preserving only the last one) Differential Revision: D18298933 Pulled By: cpojer fbshipit-source-id: ce53cd41d7c6de0469700617900f30a7d0914c26 --- .../facebook/react/modules/network/NetworkingModule.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java index 444c893989d8a4..84244d638afab1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java @@ -7,6 +7,7 @@ package com.facebook.react.modules.network; import android.net.Uri; +import android.os.Bundle; import android.util.Base64; import androidx.annotation.Nullable; import com.facebook.common.logging.FLog; @@ -625,18 +626,18 @@ private synchronized void cancelAllRequests() { } private static WritableMap translateHeaders(Headers headers) { - WritableMap responseHeaders = Arguments.createMap(); + Bundle responseHeaders = new Bundle(); for (int i = 0; i < headers.size(); i++) { String headerName = headers.name(i); // multiple values for the same header - if (responseHeaders.hasKey(headerName)) { + if (responseHeaders.containsKey(headerName)) { responseHeaders.putString( headerName, responseHeaders.getString(headerName) + ", " + headers.value(i)); } else { responseHeaders.putString(headerName, headers.value(i)); } } - return responseHeaders; + return Arguments.fromBundle(responseHeaders); } @ReactMethod