Question about accessing all Set-Cookie values from within javascript

scase
Participant III

We have Set-Cookie values coming from our southbound, one of which we need to manipulate within the gateway before returning to the requester.

When I do the request via curl using -v, the format in the headers is:

 Set-Cookie: COOKIE_ONE=-1%2C1; Path=/ 
 Set-Cookie: COOKIE_TWO=6tuDIqNZTQl%2FqbPXU0M13tcl0nM%3D%0A%3B2015-03-12+11%3A24%3A38.766_1426173878765-214752_1_-1002%2C-1%2CUSD_1; Expires=Sat, 11-Apr-15 15:24:38 GMT; Path=/

When I try to access them within javascript using the context variable context.targetResponse.headers['Set-Cookie'], it only returns the first value. I have tried other variations as well as inspecting the value(s) of Set-Cookie within trace. I am able to get the specific one using a pattern in an extract variables policy, but I would like to have access to all of them so I can edit it and then send them along.

I know that using cookies and cookie manipulation are not really in the spirit of RESTful APIs, but this is the southbound we have to deal with and the requirements of the consumer.

Solved Solved
3 9 3,609
1 ACCEPTED SOLUTION

kkleva
Participant V

I parsed this Set-Cookie header

JSESSIONID=00009H6QnwmbvT0HTm4hU3Ktvme:16kfvo759; Path=/,TSN=multi-test01; expires=Sat,16-May-2015 02:29:01 GMT; path=/; domain=.test.dss.com,LLBSS=D; expires=Sat,16-May-2015 02:29:01 GMT; path=/

Using this:

function getVatSetCookies (values) {
   var x = 0;
   while (context.targetResponse.headers['Set-Cookie'][x]){
     context.setVariable("x-set-cookie-" + x + ".content", context.targetResponse.headers['Set-Cookie'][x]);
	    x++;
   }
   x = 0;
   while (context.proxyResponse.headers['Set-Cookie'][x]){
     context.setVariable("x-set-cookie-" + x + ".content", context.proxyResponse.headers['Set-Cookie'][x]);
	    x++;
   }
}

getVatSetCookies();

Resulted in

x-set-cookie-0.content   JSESSIONID=00009H6QnwmbvT0HTm4hU3Ktvme:16kfvo759; Path=/  
x-set-cookie-1.content   TSN=multi-test01; expires=Sat 
x-set-cookie-2.content   16-May-2015 02:29:01 GMT; path=/; domain=.test.dss.com 
x-set-cookie-3.content   DSS=D; expires=Sat  
x-set-cookie-4.content   16-May-2015 02:29:01 GMT; path=/ 

This works as advertised assuming the parsing of the header is being fouled up by a malformed Set-Cookie header from origin. Reading http://tools.ietf.org/html/rfc6265#section-4.1.1 the syntax of the header seems correct yet it's not parsed exactly as expected.

View solution in original post

9 REPLIES 9

Not applicable

You should be able to access multiple values in a header by using the array operator

context.targetResponse.headers['Set-Cookie'][0]

context.targetResponse.headers['Set-Cookie'][1]

That works but have you ever noticed the cookie headers isn't exactly parsed correctly?

given header: Set-Cookie: DSS=D; expires=Sat, 16-May-2015 02:29:01 GMT; path=/

Will result in:

context.targetResponse.headers['Set-Cookie'][0] == "DSS=D; expires=Sat";

context.targetResponse.headers['Set-Cookie'][1] == "16-May-2015 02:29:01 GMT; path=/"

Does this odd parsing have anything to do with the way the target is generating the set-cookie header? I'd assume a comma in the expires portion of the Set-Cookie header wouldn't break the parsing. Unless perhaps the target is malforming the response header in someway.

Does this odd parsing have anything to do with the way the target is generating the set-cookie header?

No; the parsing is broken because Set-Cookie is special in regards to the presence of commas, and Apigee Edge does not take that into consideration.

Not applicable

One way to do it is to index into the value returned, like the following.

var cookie1=context.targetResponse.headers['Set-Cookie'][0]; var cookie2=context.targetResponse.headers['Set-Cookie'][1];

to get the different values.

kkleva
Participant V

I parsed this Set-Cookie header

JSESSIONID=00009H6QnwmbvT0HTm4hU3Ktvme:16kfvo759; Path=/,TSN=multi-test01; expires=Sat,16-May-2015 02:29:01 GMT; path=/; domain=.test.dss.com,LLBSS=D; expires=Sat,16-May-2015 02:29:01 GMT; path=/

Using this:

function getVatSetCookies (values) {
   var x = 0;
   while (context.targetResponse.headers['Set-Cookie'][x]){
     context.setVariable("x-set-cookie-" + x + ".content", context.targetResponse.headers['Set-Cookie'][x]);
	    x++;
   }
   x = 0;
   while (context.proxyResponse.headers['Set-Cookie'][x]){
     context.setVariable("x-set-cookie-" + x + ".content", context.proxyResponse.headers['Set-Cookie'][x]);
	    x++;
   }
}

getVatSetCookies();

Resulted in

x-set-cookie-0.content   JSESSIONID=00009H6QnwmbvT0HTm4hU3Ktvme:16kfvo759; Path=/  
x-set-cookie-1.content   TSN=multi-test01; expires=Sat 
x-set-cookie-2.content   16-May-2015 02:29:01 GMT; path=/; domain=.test.dss.com 
x-set-cookie-3.content   DSS=D; expires=Sat  
x-set-cookie-4.content   16-May-2015 02:29:01 GMT; path=/ 

This works as advertised assuming the parsing of the header is being fouled up by a malformed Set-Cookie header from origin. Reading http://tools.ietf.org/html/rfc6265#section-4.1.1 the syntax of the header seems correct yet it's not parsed exactly as expected.

scase
Participant III

Thanks for the replies. We are working on implementing the above-mentioned solution which iterates through context.targetResponse.headers['Set-Cookie'][], but we are also having to look into issues related to parsing of the dates in the gateway.

Yeah, It looks like the Set Cookie Header parser is not processing the "," after the day of the week. We could fix this but might then break any work around code that you have written. Which would you prefer us to do?

@Peter Johnson - I vote for fixing the parsing of Cookies to comply with the spec.

I'd agree fixing would be great. I don't think any of our work-arounds ever worked out.