Get content of second Set-Cookie header with Lua

2k Views Asked by At

Nginx has a known issue that if multiple Set-Cookie header is set, then Nginx can log only one of them(still not sure whether it's first or random one). So for example if backend sets

  1. "CSESSIONID=XXXXXXXXXXXXXXX"
  2. "JSESSIONID=XXXXXXXXXXXXXXX"

then using $sent_http_set_cookie variable in access log it will be possible to log only CSESSIONID, even on the client side it will be seen as single header Set-Cookie: CSESSIONID=XXXXXXXXXXXXXXX,JSESSIONID=XXXXXXXXXXXXXXX

I use OpenResty and the question is how I can access response header data and obtain value of second cookie (JSESSIONID in my case)?

UPDATE
I have tried to extract JSESSIONID into resp_header variable using this snippet in my server section, but it's empty. Any ideas are appreciated

    set $resp_header "";
    header_filter_by_lua_block {
      local headers, err = ngx.resp.get_headers()
      if err then
        ngx.log(ngx.ERR, "err: ", err)
        return ngx.exit(500)
      end
      for k, v in pairs(headers) do
        if k:lower() == "set-cookie" then
          local set_cookie = v
          if (type(set_cookie) == "table") then
            for key, value in pairs(set_cookie) do
              if string.match(value:lower(), "jsessionid") then
                val = string.match(value:upper(), "JSESSIONID=[%a%d]+")
                ngx.var.resp_header = val
              end
            end
          end
        end
      end
    }
1

There are 1 best solutions below

0
On

After some fighting with Lua I came to the following solution(needed to handle case when only single Set-Cookie was present):

    set $resp_header='';
    header_filter_by_lua_block {
      if ngx.var.uri == "/v1/auth" then
          local headers, err = ngx.resp.get_headers()
          if err then
            ngx.log(ngx.ERR, "err: ", err)
            return ngx.exit(500)
          end
          for k, v in pairs(headers) do
            if k:lower() == "set-cookie" then
              local set_cookie = v
              if (type(set_cookie) == "table") then
                for key, value in pairs(set_cookie) do
                  if string.match(value:lower(), "jsessionid") then
                    val = string.match(value:upper(), "JSESSIONID=([%w]+)")
                    ngx.var.resp_header = val
                  end
                end
              elseif (type(set_cookie) == "string") then
                val = string.match(set_cookie:upper(), "JSESSIONID=([%w]+)")
                ngx.var.resp_header = val
              end
            end
          end
      end 
    }