question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

HTTP response headers with the same key are not processed properly. [The expected behaviour is that the values of the identical keys are combined to a string separated by a comma]

See original GitHub issue

Environment

OS: macOS High Sierra 10.13.6 Node: 8.12.0 Yarn: Not Found npm: 6.4.1 Watchman: 4.9.0 Xcode: Xcode 10.0 Build version 10A255 Android Studio: 3.2 AI-181.5540.7.32.5014246

Packages: (wanted => installed) react: 16.3.1 => 16.3.1 react-native: https://github.com/expo/react-native/archive/sdk-30.0.0.tar.gz => 0.55.4

Description

I have an issue supporting multiple cookies passed on the response header on Android. I tracked the issue to line 607 in translateHeaders function in NetworkingModule.java file from the link below.

https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java

I debugged and realised that the code that checks if the headerMap of type WritableMap has the header key already in it is always failing and defaulting to the “Else” part which always replaces the previous key and value every time instead of combining previous key’s value string separated by a comma as it is supposed to. Due to this, only one cookie is always passed to React side.

Furthermore, the code I mentioned above use ReadableNativeMap class which holds the actual key-value map as an instance variable. getLocalMap function in ReadableNativeMap class is used to retrieve the “mLocalMap” variable but always return an object that doesn’t have values hence the code inside NetworkingModule is not doing what it is supposed to.

Lastly, I’m aware that my environment info state that I’m using react-native from Expo https://github.com/expo/react-native, however the code that I found an issue on, Expo also use it as is from https://github.com/facebook/react-native hence I created an issue here.

Reproducible Demo

Pass multiple headers with the same key from a network request.

In my case I’m getting response headers with multiple cookies with key “Set-Cookie” from a network request, but after it has been processed by the code I mentioned above, there is always one.

Sample response header with multiple cookies similar to what get from the server.

Server: Example Date: Tue, 16 Oct 2018 10:35:21 GMT Content-Type: application/json;charset=UTF-8 Connection: keep-alive Expires: 0 X-B3-TraceId: d6745404c1d2a7fb Set-Cookie: MyDBTokenForApps=6c785634-d62d-32a2-a4f7-8c1e0f42a93f; path=/; secure; Max-Age=43198; Expires=Tue, 16-Oct-2018 22:35:19 GMT Set-Cookie: anotherCookie=1$E4AAA5C9C37865158B02402AFFDB7856; path=/; domain=.example.co.za; secure X-XSS-Protection: 1; mode=block X-Frame-Options: DENY X-Content-Type-Options: nosniff Strict-Transport-Security: max-age=31536000 ; includeSubDomains Instance: /CSG/pool_vcoza_summer_80 10.112.205.215 80 Vary: Accept-Encoding Transfer-Encoding: chunked Cache-Control: public, max-age=0

After this has been processed by translateHeaders function, only one cookie header that was processed last remains.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:6
  • Comments:41 (5 by maintainers)

github_iconTop GitHub Comments

6reactions
jerolimovcommented, Apr 4, 2019

Hello, I had the same problem here and analysed the internal issue:

The problem is a combination of NetworkingModule.java and the usage of WritableNativeMap. The function translateHeaders maps the OKHTTP header objekt to a React Native header map. Headers with the same key was overridden because the hasKey method always return false.

https://github.com/facebook/react-native/blob/9895d011374e655bcaeb390167abafb9c01fef18/ReactAndroid/src/main/java/com/facebook/react/modules/network/NetworkingModule.java#L647-L661

That hasKey always return false is an implementation error in ReadableNativeMap and WritableNativeMap (which extends the readable map). This native maps supports two different modes, which can be enabled and disabled for all maps with a static boolean useNativeAccessor.

This flag defines if the ReadableNativeMap reads data from a native map or a internal (java.util.) HashMap.

But the problem was that WritableNativeMap always writes into the native map and never uses the (Readable) internal HashMap.

That was the reason why hasKey always return null if useNativeAccessor was false and only one header was returned by translateHeaders.

Like said by @hey99xx in https://github.com/facebook/react-native/issues/21795#issuecomment-430384534 and by @Return-1 https://github.com/facebook/react-native/issues/23005#issuecomment-457107736 its possible to activate the this native accessor, if you add this code to your own/project MainActivity.java:

Add this imports:

import com.facebook.react.bridge.ReadableNativeArray;
import com.facebook.react.bridge.ReadableNativeMap;

And this add the beginning of the createReactActivityDelegate method, before your application was loaded.

        ReadableNativeArray.setUseNativeAccessor(true);
        ReadableNativeMap.setUseNativeAccessor(true);

For me this works fine. But notice that this global flag may cause some other troubles.

I also started to fix this behaviour in the latest React Native 0.59.3 release, but notice than that the master version of ReadableNativeMap/WritableNativeMap was already changed.

The commits https://github.com/facebook/react-native/commit/b257e06bc6c29236a1a19f645fb46b85b2ffc4d2 and https://github.com/facebook/react-native/commit/a062b34493f07b28378de2772914d838cb28e3d8 by FB eng @sahrens changed/removed the useNativeAccessor behaviour, so I hope this issue was also fixed with the next/upcoming minor release 0.60.0. 🙌

(I couldn’t test the new version yet, because running from the npm package (also with sourcecode changes) works fine for me, but the sourcecode version of RN let fail some of my 3rd party libraries. I’m looking forward for a RC of 0.60.0 and maybe will update this text here then.)

3reactions
pinstripe-potatoheadcommented, Aug 22, 2019

@sahrens This issue still persists on 0.60.4, and the workaround doesn’t work since you removed it. Please look into it, as it makes react native with cookie based auth unusable

Read more comments on GitHub >

github_iconTop Results From Across the Web

Are Duplicate HTTP Response Headers acceptable?
Yes. So, multiple headers with the same name is ok (www-authenticate is such a case) if the entire field-value is defined as a...
Read more >
HTTP headers - MDN Web Docs - Mozilla
An HTTP header consists of its case-insensitive name followed by a colon ( : ), then by its value. Whitespace before the value...
Read more >
HTTP/1.1: Header Field Definitions
If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept...
Read more >
Top 5 Things Every Apache Kafka Developer Should Know
If the keys or values are not strings, you'll need to provide the deserializers via the command line flags --key-deserializer and --value- ...
Read more >
RFC 7231: Hypertext Transfer Protocol (HTTP/1.1)
This document defines the semantics of HTTP/1.1 messages, as expressed by request methods, request header fields, response status codes, and response header ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found