ChallengeHeaderParser.sys.mjs (2224B)
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/. */ 4 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, "") }; 17 } 18 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()); 37 38 let scheme = null; 39 let params = []; 40 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 } 50 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 } 63 64 params.push(parseChallengeParameter(part)); 65 } 66 } 67 68 if (scheme !== null) { 69 // If we have a challenge recorded, add it to the array. 70 challenges.push({ scheme, params }); 71 } 72 73 return challenges; 74 }