Bug 1874684 - Part 33: Defer allocation of options object for CalendarDateFromFields...
[gecko.git] / remote / shared / ChallengeHeaderParser.sys.mjs
blob7cb73a4146d2678314d9385e6b0cbb6ad9bb8384
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3  * You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /**
6  * Parse the parameter in a name/value pair and remove quotes.
7  *
8  * @param {string} paramValue
9  *     A string representing a challenge parameter.
10  *
11  * @returns {object}
12  *     An object with name and value string properties.
13  */
14 function parseChallengeParameter(paramValue) {
15   const [name, value] = paramValue.split("=");
16   return { name, value: value?.replace(/["']/g, "") };
19 /**
20  * Simple parser for authenticate (WWW-Authenticate or Proxy-Authenticate)
21  * headers.
22  *
23  * Bug 1857847: Replace with Necko's ChallengeParser once exposed to JS.
24  *
25  * @param {string} headerValue
26  *     The value of an authenticate header.
27  *
28  * @returns {Array<object>}
29  *     Array of challenge objects containing two properties:
30  *     - {string} scheme: The scheme for the challenge
31  *     - {Array<object>} params: Array of { name, value } objects representing
32  *       all the parameters of the challenge.
33  */
34 export function parseChallengeHeader(headerValue) {
35   const challenges = [];
36   const parts = headerValue.split(",").map(part => part.trim());
38   let scheme = null;
39   let params = [];
41   const schemeRegex = /^(\w+)(?:\s+(.*))?$/;
42   for (const part of parts) {
43     const matches = part.match(schemeRegex);
44     if (matches !== null) {
45       // This is a new scheme.
46       if (scheme !== null) {
47         // If we have a challenge recorded, add it to the array.
48         challenges.push({ scheme, params });
49       }
51       // Reset the state for a new scheme.
52       scheme = matches[1];
53       params = [];
54       if (matches[2]) {
55         params.push(parseChallengeParameter(matches[2]));
56       }
57     } else {
58       if (scheme === null) {
59         // A scheme should always be found before parameters, this header
60         // probably needs a more careful parsing solution.
61         return [];
62       }
64       params.push(parseChallengeParameter(part));
65     }
66   }
68   if (scheme !== null) {
69     // If we have a challenge recorded, add it to the array.
70     challenges.push({ scheme, params });
71   }
73   return challenges;