From 40b26418c1278439607c7001786f249f70402f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C=28Mingyu=20Kim=29?= Date: Thu, 9 Apr 2026 16:37:23 +0900 Subject: [PATCH 1/2] test: add setRequestHeader append behavior tests Add tests verifying XHR spec compliance for setRequestHeader: - Same header called multiple times should append with ', ' - Case-insensitive header name merging - Throw when called before open() These tests currently FAIL, exposing the spec violation. --- .../Network/__tests__/XMLHttpRequest-test.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/react-native/Libraries/Network/__tests__/XMLHttpRequest-test.js b/packages/react-native/Libraries/Network/__tests__/XMLHttpRequest-test.js index f80f71a7508d..a9be11994738 100644 --- a/packages/react-native/Libraries/Network/__tests__/XMLHttpRequest-test.js +++ b/packages/react-native/Libraries/Network/__tests__/XMLHttpRequest-test.js @@ -294,6 +294,32 @@ describe('XMLHttpRequest', function () { expect(GlobalPerformanceLogger.stopTimespan).not.toHaveBeenCalled(); }); + it('should append values when setRequestHeader is called with the same header', function () { + xhr.open('GET', 'blabla'); + xhr.setRequestHeader('X-Custom', 'value1'); + xhr.setRequestHeader('X-Custom', 'value2'); + + // $FlowFixMe[prop-missing] + expect(xhr._headers['x-custom']).toBe('value1, value2'); + }); + + it('should lowercase header names in setRequestHeader', function () { + xhr.open('GET', 'blabla'); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.setRequestHeader('content-type', 'text/plain'); + + // $FlowFixMe[prop-missing] + expect(xhr._headers['content-type']).toBe( + 'application/json, text/plain', + ); + }); + + it('should throw when setRequestHeader is called before open', function () { + expect(() => { + xhr.setRequestHeader('foo', 'bar'); + }).toThrow('Request has not been opened'); + }); + it('should sort and lowercase response headers', function () { // Derived from XHR Web Platform Test: https://github.com/web-platform-tests/wpt/blob/master/xhr/getallresponseheaders.htm xhr.open('GET', 'blabla'); From 5f3ff21637f24744887551b387b3b2d5b7531a84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=AF=BC=EA=B7=9C=28Mingyu=20Kim=29?= Date: Thu, 9 Apr 2026 16:37:32 +0900 Subject: [PATCH 2/2] fix: setRequestHeader should append per XHR spec Comply with XHR Living Standard 4.5.2: when setRequestHeader is called multiple times with the same header, append with ', ' instead of overwriting. --- packages/react-native/Libraries/Network/XMLHttpRequest.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/react-native/Libraries/Network/XMLHttpRequest.js b/packages/react-native/Libraries/Network/XMLHttpRequest.js index 038be3dde36c..f42e87828cc9 100644 --- a/packages/react-native/Libraries/Network/XMLHttpRequest.js +++ b/packages/react-native/Libraries/Network/XMLHttpRequest.js @@ -509,7 +509,9 @@ class XMLHttpRequest extends EventTarget { if (this.readyState !== this.OPENED) { throw new Error('Request has not been opened'); } - this._headers[header.toLowerCase()] = String(value); + const key = header.toLowerCase(); + const existing = this._headers[key]; + this._headers[key] = existing ? existing + ', ' + String(value) : String(value); } /**