Multiple Set-Cookie Headers: same-name headers


#1

My origin is returning a response with multiple Set-Cookie headers:

set-cookie: cookie_one=value1; expires=Sat, 27-Apr-2019 20:34:33 GMT; Max-Age=31536000; path=/; domain=.mydomain.com
set-cookie: cookie_two=value2; expires=Sat, 27-Apr-2019 20:34:33 GMT; Max-Age=31536000; path=/; domain=.mydomain.com

I have tried several methods for getting the ENTIRE header (value, expires, Max-Age, etc):

I am able to get the VALUES of both set-cookie headers by using: setcookie.get_value_by_name(beresp, “<cookie_name>”). I have been unable to get the entire header for the second Set-Cookie header and I’ve tried regular expressions and beresp.http.Set-Cookie:<cookie_name> (https://docs.fastly.com/guides/vcl/isolating-header-values-without-regular-expressions).

Does Fastly not support manipulation of the second same-name header? I can see from this post: Having multiple Set-Cookie that as of 03/2015 it was not supported via the interface but is there a way to do this in VCL?

Thanks


#2

Hi Eric,

Thanks for reaching out.
Unfortunately, beresp.http.Set-Cookie will read/write the value of the first Set-Cookie header sent by your origin at this moment.

If you are looking to log multiple Set-Cookie headers, there is no way to architect a logging statement for subsequent Set-Cookies other than logging the value of the first one.

However, if you are looking to deliver the response with multiple Set-Cookie headers to the client, you can achieve it at the Fastly edge. You’ll need to enable custom VCL and add the following line in the vcl_deliver subroutine:

add resp.http.Set-Cookie = <your_secod_cookie_value>;

Best,
Hiro


#3

Yes, thank you. I have already done that but I need to get the extra information out of the second set-cookie header. I not only need the value but also the expires, domain, max-age, path and any other information from the set-cookie header.

Is there any way to do this?


#4

Understood - one approach you could take is to collect all cookies, store it as a variable, and add it to the response header after separating it.
This can be handled in the vcl_deliver.

## declare a custom variable in VCL. 
  declare local var.cookies STRING;

## read and collect all cookies separated by the pipe(assuming the cookie doesn't contain the pipe). 
  std.collect(resp.http.Set-Cookie, "|");

## store it as a variable and unset the original one.
  set var.cookies = resp.http.Set-Cookie;
  unset resp.http.Set-Cookie;

## regex logic to grab the cookie separated by the pipe.
## add cookie everything before the pipe, and after the pipe.
  if (var.cookies ~ "([^|]*)") {
    add resp.http.Set-Cookie = re.group.1;
  }
  if (var.cookies ~ "\| ([^|]*)") {
    add resp.http.Set-Cookie = re.group.1;
  }

This will add two separate cookies that include the whole information to the response header.
You can see the sample test here: https://fiddle.fastlydemo.net/fiddle/bec17849 (click run)
Hope this will help to work around.