vADC Docs

HowTo: Handle cookies in TrafficScript

by on ‎05-17-2013 01:49 AM - edited on ‎07-06-2015 03:56 PM by PaulWallace (2,529 Views)

Stingray provides a set of useful functions to help you handle HTTP cookies in requests and responses.

 

Processing cookies in HTTP requests

 

HTTP requests may contain cookies that were set by the application previously, or were set by client-side JavaScript.  Cookies are presented in a single HTTP header named 'Cookie':

 

Cookie: name1=value1; name2=value2...

 

You can use a web inspector such as the Chrome developer tools to see what cookies your web browser is sending to the sites you visit.

 

The TrafficScript functions http.getCookie( "name" ), http.setCookie( "name", "value" ) and http.removeCookie( "name" ) can be used to inspect and modify the 'Cookie' header; they are more convenient than reading the header directly and parsing the result.  http.getCookies() returns a hash datastructure mapping cookie names to cookie values.

 

Cookie parameters

 

When servers set HTTP cookies, they may specify the path, host, protocol or expiry time for that cookie.  The client will only present the cookie on requests that match those parameters:

 

Set-Cookie: name=value; expires=Wed, 09 Jun 2021 10:18:14 GMT; path=/secure; domain=*.site.com

 

There is no way to determine these parameters by inspecting the client cookie in the request.

 

Under certain circumstances, several instances of the same cookie may match a request.  For example, a server can set the same cookie with different values and different parameters.

 

http.setResponseCookie( "mycookie", "ABCDE", "path=/news" );

http.setResponseCookie( "mycookie", "XYZ", "path=/" );

 

If a client accesses a resource where the path begins '/', it will provide the cookie 'mycookie=XYZ'.  If the client accesses a resource where the path begins '/news', it will provide both cookie values:

 

Cookie: mycookie=XYZ; mycookie=ABCDE

 

This is a very unusual circumstance (most likely to happen because of a programming or design error - it's not something you would typically do intentionally).  In this situation, if you call http.getCookie( 'name' ), Stingray will you one of the values and ignore the other.  If this is a problem, you need to call http.getHeader( "Cookie" ) to get the entire Cookie header value and parse this yourself.

 

Processing cookies in responses

 

Servers set cookies in responses using the Set-Cookie header as described above.  A server may set multiple cookies in a response, and Stingray can add or edit these Set-Cookie headers to change the values or parameters that are provided.

 

You can use a web inspector such as the Chrome developer tools to see what cookies the server is setting on your web browser.

 

The TrafficScript functions http.getResponseCookie( "name" ), http.setResponseCookie( "name", "value" [, "options] ) and http.removeResponseCookie( "name" ) can be used to inspect and modify the 'Set-Cookie' headers; you can even call these while you are processing an HTTP request and Stingray will remember to apply these changes to the response that comes from the server.  http.getResponseCookies() returns a hash datastructure mapping cookie names to cookie values.

 

These functions are not sufficient if a) you want to get the options, or b) the server is setting the cookie twice (e.g. with two different paths).  In that case, here's a general-purpose solution:

 

# Build an array of cookies set by the server

$cookies = [];

$sc = http.getResponseHeader( "Set-Cookie" );
foreach( $line in string.split( $sc, "\r\nSet-Cookie:" ) ) {
   $cookie = [];
   $kvs = string.split( $line, ";" );
   $a = string.split( string.trim( array.shift( $kvs ) ), "=" );
   $cookie["name"]  = $a[0];
   $cookie["value"] = $a[1];
   foreach( $kv in $kvs ) {
      $a = string.split( string.trim( array.pop( $kvs ) ), "=" );
      $cookie[$a[0]] = $a[1];
   }
   array.push( $cookies, $cookie );
}



# Print the cookies out

foreach( $cookie in $cookies ) {
   $line = "Cookie: ".$cookie["name"]." is ".$cookie["value"];
   foreach( $k in hash.keys( $cookie ) ) {
      if( $k == "name" ) continue;
      if( $k == "value" ) continue;
      $line .= "; ".$k." = ".$cookie[$k];
   }
   log.info( $line );
}
Contributors