Browse Source

fix: use chrome headers in net.request for everything except cookie (#36666)

Jeremy Rose 2 years ago
parent
commit
8f23b1527b

+ 8 - 25
lib/browser/api/net.ts

@@ -56,31 +56,14 @@ class IncomingMessage extends Readable {
 
   get headers () {
     const filteredHeaders: Record<string, string | string[]> = {};
-    const { rawHeaders } = this._responseHead;
-    rawHeaders.forEach(header => {
-      const keyLowerCase = header.key.toLowerCase();
-      if (Object.prototype.hasOwnProperty.call(filteredHeaders, keyLowerCase) &&
-          discardableDuplicateHeaders.has(keyLowerCase)) {
-        // do nothing with discardable duplicate headers
-      } else {
-        if (keyLowerCase === 'set-cookie') {
-          // keep set-cookie as an array per Node.js rules
-          // see https://nodejs.org/api/http.html#http_message_headers
-          if (Object.prototype.hasOwnProperty.call(filteredHeaders, keyLowerCase)) {
-            (filteredHeaders[keyLowerCase] as string[]).push(header.value);
-          } else {
-            filteredHeaders[keyLowerCase] = [header.value];
-          }
-        } else {
-          // for non-cookie headers, the values are joined together with ', '
-          if (Object.prototype.hasOwnProperty.call(filteredHeaders, keyLowerCase)) {
-            filteredHeaders[keyLowerCase] += `, ${header.value}`;
-          } else {
-            filteredHeaders[keyLowerCase] = header.value;
-          }
-        }
-      }
-    });
+    const { headers, rawHeaders } = this._responseHead;
+    for (const [name, values] of Object.entries(headers)) {
+      filteredHeaders[name] = discardableDuplicateHeaders.has(name) ? values[0] : values.join(', ');
+    }
+    const cookies = rawHeaders.filter(({ key }) => key.toLowerCase() === 'set-cookie').map(({ value }) => value);
+    // keep set-cookie as an array per Node.js rules
+    // see https://nodejs.org/api/http.html#http_message_headers
+    if (cookies.length) { filteredHeaders['set-cookie'] = cookies; }
     return filteredHeaders;
   }
 

+ 1 - 3
shell/browser/api/electron_api_url_loader.cc

@@ -577,9 +577,7 @@ void SimpleURLLoaderWrapper::OnResponseStarted(
   dict.Set("statusCode", response_head.headers->response_code());
   dict.Set("statusMessage", response_head.headers->GetStatusText());
   dict.Set("httpVersion", response_head.headers->GetHttpVersion());
-  // Note that |response_head.headers| are filtered by Chromium and should not
-  // be used here.
-  DCHECK(!response_head.raw_response_headers.empty());
+  dict.Set("headers", response_head.headers.get());
   dict.Set("rawHeaders", response_head.raw_response_headers);
   Emit("response-started", final_url, dict);
 }

+ 13 - 0
spec/api-net-spec.ts

@@ -623,6 +623,19 @@ describe('net module', () => {
       expect(response.headers['set-cookie']).to.have.same.members(cookie);
     });
 
+    it('should be able to receive content-type', async () => {
+      const contentType = 'mime/test; charset=test';
+      const serverUrl = await respondOnce.toSingleURL((request, response) => {
+        response.statusCode = 200;
+        response.statusMessage = 'OK';
+        response.setHeader('content-type', contentType);
+        response.end();
+      });
+      const urlRequest = net.request(serverUrl);
+      const response = await getResponse(urlRequest);
+      expect(response.headers['content-type']).to.equal(contentType);
+    });
+
     it('should not use the sessions cookie store by default', async () => {
       const serverUrl = await respondOnce.toSingleURL((request, response) => {
         response.statusCode = 200;

+ 1 - 0
typings/internal-ambient.d.ts

@@ -145,6 +145,7 @@ declare namespace NodeJS {
     statusMessage: string;
     httpVersion: { major: number, minor: number };
     rawHeaders: { key: string, value: string }[];
+    headers: Record<string, string[]>;
   };
 
   type RedirectInfo = {