-
-
Save DinoChiesa/cad04fc62be91e6c9a31469b09c4e1b8 to your computer and use it in GitHub Desktop.
Modified the parseSetCookieHeader function to handle some additional combinations. Looks like it works fine. I have tested for following combinations
//Last cookie ends with HttpOnly
var H = "AWSALB=lnTSVTHpyba6/qH2QWVOVQWEuJjwwww5yt/l628OSKMZtEmZaGHFQojsda11Tl7cn2lOqmXAEWpTsaMyFcd6oPYNAmGZCKpc7BbGi4B+8ZQzoxw0SqbFqw; Expires=Thu,26 Jan 2020 12:21:46 GMT; Path=/,JSESSIONID=B1D80E6395A35D4210B9F254835CC627; Path=/ED; HttpOnly"
//First Cookie ends with HttpOnly
var H = "JSESSIONID=B1D80E6395A3ghfghfgnfgf54835CC627; Path=/ED; HttpOnly, AWSALB=lnTSVTHpyba6/qH2QWVjhghjghjghkBnpBP5yt/l628OSKMZtEmZaGHFQojsda11Tl7cn2lOqmXAEWpTsaMyFcd6oPYNAmGZCKpc7BbGi4B+8ZQzoxw0SqbFqw; Expires=Thu,26 Jan 2020 12:21:46 GMT; Path=/"
//First cookie ends with Expires
var H = "AWSALB=lnTSVTHpyba6/qH2QWVOVhkjhkkjhkBnpBP5yt/l628OSKMZtEmZaGHFQojsda11Tl7cn2lOqmXAEWpTsaMyFcd6oPYNAmGZCKpc7BbGi4B+8ZQzoxw0SqbFqw; Path=/; Expires=Thu,26 Jan 2020 12:21:46 GMT, JSESSIONID=B1D80E6395A35D4210B9F254835CC627; Path=/ED; HttpOnly"
//Last cookie ends with Expires
var H = "JSESSIONID=B1D80E6ASFSFSFSF0B9F254835CC627; Path=/ED; HttpOnly, AWSALB=lnTSVTHpyba6/qH2QWVOASfSFSFFi1kBnpBP5yt/l628OSKMZtEmZaGHFQojsda11Tl7cn2lOqmXAEWpTsaMyFcd6oPYNAmGZCKpc7BbGi4B+8ZQzoxw0SqbFqw; Path=/; Expires=Thu,26 Jan 2020 12:21:46 GMT"
//one of the cookie ends with secure
var H = "AWSALB=x8C2TBnkGNlmjDU+qbcWrzGO6DMdcDAddffgfghfhfg4+16eTF8Pnz1wcDsAoQfZIMpHoX4nwRfVhEEy0y6aoUTD7hz6hHsuaEEWIuwem0q/kqyuBsVZKuMpu; Max-Age=604800; Path=/digital, AWSALBCORS=x7C2TBnkGNlmjDU+qbcWrzGOdgdfdfdfgf6ltIeahenQx2+15eTF8Pnz5wcDsAoQfZIMpHoX1nwRfVhEEy0y6aoUTD7hz6hHsuaEEWIuwem0q/kqyuBsVZKuMpu; Max-Age=604800; Path=/digital; SameSite=None; Secure, JSESSIONID=9C3A1D2E1DA5FSAASASSADC2A43C01W2D; Path=/digital; HttpOnly"
Here is updated function--
var ParseState = {
BEGIN : 0,
NAME : 1,
VALUE : 2,
SEPARATOR : 3,
VALUE_OR_OPENQUOTE : 4,
VALUE_OR_CLOSEQUOTE : 5,
EXPIRES : 6,
NO_VALUE : 7
};
var parseSetCookieHeader = function(str, wantRaw) {
var content = str.trim(),
state = ParseState.NAME,
name = '',
value = '',
parsed = {},
cookies = [],
i = 0;
do {
var c = content.charAt(i);
//console.log(name + "---" + Number(state) + "----" + c);
//console.log('state: ' + Number(state));
switch (Number(state)) {
case ParseState.NAME:
if (c === '=') {
if (parsed[name])
throw new Error('duplicate param at position ' + i);
state = (name == 'Expires') ? ParseState.EXPIRES : ParseState.VALUE_OR_OPENQUOTE;
value = '';
//console.log('name: ' + name);
//console.log('state: ' + state);
}
else if(name == "HttpOnly" || name == "Secure") {
state = ParseState.NO_VALUE;
}
else if (c === ';') {
//console.log('value end, value: ' + value);
parsed[name] = '';
name = '';
value = '';
state = ParseState.NAME;
}
else if (c === ' ') { // allow ws
if (name !== '') {
throw new Error('whitespace in name at position ' + i);
}
}
else {
name += c;
}
break;
case ParseState.EXPIRES:
if (c === ';') {
parsed[name] = value;
value = '';
name = '';
state = ParseState.NAME;
}
else if (c === ',' && value.includes(',')) {
parsed[name] = value;
cookies.push(parsed);
parsed = {};
state = ParseState.NAME;
name = '';
value = '';
} else {
value += c;
}
break;
case ParseState.NO_VALUE:
parsed[name] = value;
cookies.push(parsed);
parsed = {};
state = ParseState.NAME;
name = '';
value = '';
break;
case ParseState.VALUE_OR_OPENQUOTE:
value = c;
if (c === '"') {
//console.log('open quote');
state = ParseState.VALUE_OR_CLOSEQUOTE;
} else {
state = ParseState.VALUE;
}
break;
case ParseState.VALUE:
if (name.length === 0) {
throw new Error('bad param name at posn ' + i);
}
if (c === ';') {
//console.log('value end, value: ' + value);
parsed[name] = value;
name = '';
value = '';
state = ParseState.NAME;
} else if (c === ',') {
parsed[name] = value;
name = '';
value = '';
cookies.push(parsed);
parsed = {};
state = ParseState.NAME;
} else {
value += c;
}
break;
case ParseState.VALUE_OR_CLOSEQUOTE:
if (name.length === 0) {
throw new Error('bad param name at posn ' + i);
}
if (c === '"') {
value += c;
//console.log('close quote, value: ' + value);
parsed[name] = value;
name = '';
value = '';
state = ParseState.SEPARATOR;
} else {
value += c;
}
break;
case ParseState.SEPARATOR:
if (c === ';') {
state = ParseState.NAME;
} else if (c === ',') {
cookies.push(parsed);
parsed = {};
state = ParseState.NAME;
} else if (c === ' ') {
// do nothing with WS
} else {
throw new Error('bad param format');
}
break;
default:
throw new Error('Invalid format at posn ' + i);
}
i++;
} while (i < content.length);
if (name !== '') {
parsed[name] = value;
cookies.push(parsed);
}
if (wantRaw) {
var raw = {};
cookies.forEach(function(c) {
var keys = Object.keys(c);
raw[keys[0]] = c;
});
return raw;
}
return cookies.map(function(c) {
return Object.keys(c).map(function(key){
var v = c[key];
return (v === '') ? key : (key + '=' + v);
}).join('; ');
});
};
Hope this is covered all the combination. Thank you very much.
Thanks, helpful.
Hi Dino,
I am getting cookie value like below from backend service. The parsing failed with error whitespace in name at position 354. Is there any issue in cookie?
AWSALB=x8C2TBnkGNlmjDU+qbcWrzGO6DMdcH3LaLv4ltIeahenQx4+16eTF8Pnz1wcDsAoQfZIMpHoX4nwRfVhEEy0y6aoUTD7hz6hHsuaEEWIuwem0q/kqyuBsVZKuMpu; Max-Age=604800; Path=/digital, AWSALBCORS=x7C2TBnkGNlmjDU+qbcWrzGO6DMdcH2LaLv6ltIeahenQx2+15eTF8Pnz5wcDsAoQfZIMpHoX1nwRfVhEEy0y6aoUTD7hz6hHsuaEEWIuwem0q/kqyuBsVZKuMpu; Max-Age=604800; Path=/digital; SameSite=None; Secure, JSESSIONID=9C3A1D2E1DA5F83ECA01QC2A43C01W2D; Path=/digital; HttpOnly
Thank,
Sujnan,