Set-Cookie header parsing issue

Not applicable

Hi Team,

I have a requirement of replacing/adding domain in set-cookie header coming in response from target server and sending the modified set-cookie header to my front-end system.

Set-Cookie value from target -server:

securityStatus=0; expires=Tue,30-Jan-2018 06:37:25 GMT; path=/,cartCount=0; expires=Thu,01-Mar-2018 06:22:25 GMT; path=/

Problem statement:

While trying to fetch all the set-cookie by parsing this array we were not able to split above cookie splitted on basis of comma since comma is also present in expires so it is parsing incorrectly.

While we have found a way by which atleast we can fetch cookie correctly and have correct set-cookie[1],set-cookie[2] and so on but when i try to set the set-cookie in proxy response then it again parses the cookie based on comma present in expires and set in correct set-cookie response .

Below is the snippet of code being used for setting the set-cookie response while iterating over splitted cookie:

for(var i = 0; i < transformedCookieData.length; i++) { context.setVariable('message.header.set-cookie.' + i, transformedCookieData[i]); }

0 2 2,112
2 REPLIES 2

Commas are not used in Cookie values - ideally you should use a different date format.

There is a discussion here on this.

Hope this helps!

You have described two problems: parsing and setting cookie values.

Parsing

For parsing cookies of the form you described: The short answer is: Don't split on commas.

You can parse the cookie string with a regexp, and be smarter about it.

This works for your specific test case. (I ran this outside of the apigee JS callout, but the RegExp will work the same when run inside the JS callout)

var testCookie = "securityStatus=0; expires=Tue,30-Jan-2018 06:37:25 GMT; path=/,cartCount=0; expires=Thu,01-Mar-2018 06:22:25 GMT; path=/";
var re = new RegExp('(([a-zA-Z]+)=([^ ]+)); expires=([^;]+); path=([^ ,]+)', 'g');
var match;
for (var match = re.exec(testCookie); match; match = re.exec(testCookie)) {
  var nameValuePair = match[1];
  var expiryString = match[4];
  var pathString = match[5];
  console.log(match);
  // [ 'securityStatus=0; expires=Tue,30-Jan-2018 06:37:25 GMT; path=/',
  // 'securityStatus=0',
  // 'securityStatus',
  // '0',
  // 'Tue,30-Jan-2018 06:37:25 GMT',
  // '/',
  // index: 0,
  // input: 'securityStatus=0; expires=Tue,30-Jan-2018 06:37:25 GMT; path=/,cartCount=0; expires=Thu,01-Mar-2018 06:22:25 GMT; path=/' ]
}

You may need to check other cookie combinations - for example a missing path.

Setting Cookies

Just use Max-Age instead of Expires. Max-Age allows cookie expiry to be expressed in a numeric. This form was created specifically to address the problem you described. For a cookie as above, it would look like this:

cartCount=0; Max-Age=2440415; path=/

And to convert between "expires" and "Max-Age", you can use this JS:

  var d1 = new Date(expiryString);
  var now = new Date();
  var maxAge = Math.round((d1 - now) / 1000);

And here again you may want to consider edge cases like a negative value indicating an expired cookie.