openresty / headers-more-nginx-module

Set, add, and clear arbitrary output headers in NGINX http servers
1.65k stars 222 forks source link

more_set_headers and manipulating single cookie #18

Open rahul286 opened 11 years ago

rahul286 commented 11 years ago

@agentzh

I'm trying to solve a problem and this module is very close to intended workaround.

Backend app sets number of cookies and I need to alter value of a cookie in certain circumstances.

When I do:

more_set_headers "Set-Cookie: target-cookie=myvalue";

It does changes target-cookie's value but it removes other "Set-cookie" header from output.

My intention is to change value for target-cookie only without touching other cookies.

May I know is there any workaround for this? Or this can rectified by patching module itself?

Thanks.

agentzh commented 11 years ago

@rahul286 You're recommended to use the ngx_lua module to do this, which is much more flexible and also easier. Below is a tested example for your example above:

header_filter_by_lua '
    local cookies = ngx.header.set_cookie
    if cookies then
        if type(cookies) ~= "table" then
            cookies = {cookies}
        end
        local gsub = string.gsub
        local changed
        for i, cookie in ipairs(cookies) do
            local new_cookie = gsub(cookie, "^target%-cookie=[^;]*", "target-cookie=myvalue", 1)
            if new_cookie ~= cookie then
                cookies[i] = new_cookie
                changed = true
            end
        end
        if changed then
            ngx.header.set_cookie = cookies
        end
    end
';

The only bit that deserves some explanation is that - is a meta-character in Lua's pattern string, so we use % to escape it.

See ngx_lua's documentation for more details: https://github.com/chaoslawful/lua-nginx-module#readme

rahul286 commented 11 years ago

@agentzh Thanks for your help an Lua code.

I am aware of Lua module and possibilities with it.

There are few reasons I wanted to do it using headers-more-nginx-module

  1. I don't know Lua so I need to learn Lua (though learning is on my wishlist)
  2. I am using https://launchpad.net/~brianmercer/+archive/nginx PPA. So for Lua I need to compile nginx and replace nginx setup on more than dozen servers.
  3. Lua codes are lengthy while headers-mode module need only 1 line of code.

By the way, after posting this issue, I got my app working with headers-more module as well. Basically, I divided app in cached and non-cached zones. In cached zone, clearing all cookies did not hurt.

I will explore Lua soon as it looks like a magical solution to many different problems.

Our of curiosity, may I know if this will be resolved in headers-more-nginx-module as well? I somehow feel this is more like a bug (or side-effect).

Apart from cookies, there might be some extended headers with repetition. So if goal is to manipulate only one-line then removing other lines with same header-keys may not be expected behavior.

Thanks.

agentzh commented 11 years ago

Hello!

On Sun, Oct 27, 2013 at 11:11 PM, Rahul Bansal notifications@github.com wrote:

  1. I am using https://launchpad.net/~brianmercer/+archive/nginx PPA. So for Lua I need to compile nginx and replace nginx setup on more than dozen servers.

Seems like we need to set up a PPA for OpenResty :)

  1. Lua codes are lengthy while headers-mode module need only 1 line of code.

But you need to add such logic as C code anyway. Also, you can also reuse the Lua code in a custom Lua module file just like those lua-resty-* libraries out there. That way, it's also a one-liner, for example:

header_filter_by_lua

'require("override_cookie").set("target-cookie", "myvalue")';

Not bad at all, isn't it? ;)

I will explore Lua soon as it looks like a magical solution to many different problems.

You definitely should ;) We created ngx_lua just because we didn't write C code for every little things.

Our of curiosity, may I know if this will be resolved in headers-more-nginx-module as well?

It requires patching ngx_headers_more.

I somehow feel this is more like a bug (or side-effect).

No, it's not a bug. It's the expected behavior by design. more_set_headers always replace all the existing headers of the name specified with your new value.

Apart from cookies, there might be some extended headers with repetition. So if goal is to manipulate only one-line then removing other lines with same header-keys may not be expected behavior.

It may not. But it's the current behavior by design. I don't mind adding an option to more_set_headers to switch over to an alternative behavior but we need to clearly define the alternative behavior though. Frankly speaking I'm not particularly interested in hacking ngx_headers_more for something that can be trivially achieved by a few lines of Lua. But if you insist, I'm fine to merge your patch if it looks good enough :)

Best regards, -agentzh

rahul286 commented 11 years ago

Seems like we need to set up a PPA for OpenResty :)

Loos like there is already one - https://launchpad.net/~miurahr/+archive/openresty :-)

Lua codes are lengthy while headers-mode module need only 1 line of code. But you need to add such logic as C code anyway. Also, you can also reuse the Lua code in a custom Lua module file just like those lua-resty-* libraries out there. That way, it's also a one-liner, for example:

header_filter_by_lua 'require("override_cookie").set("target-cookie", "myvalue")';

Not bad at all, isn't it? ;)

It's really nice. It just pushed Lua to the top of my TO-DO list. Most likely this weekend I will nail it. :-)

But if you insist, I'm fine to merge your patch if it looks good enough :)

Last time I coded in C was back in 2006 for college assignment as student. Honestly, I haven't programmed in C ever but we are looking for a C-programmer to join our team. So I will ask my future-college to patch this module for sure.

I will definitely explore Lua for this and many other complex problems I am trying to handle at Nginx level.

But whenever we have a C programmer free for a day in team (in future), patching this module (in clean and intuitive way, with documentation) will help some people.

I strongly feel, most admins who want to use this module for cookies-modifications will be expecting an option or flag to control if a single cookie gets affected or all.

Thanks again.

sevmonster commented 8 months ago

Should this be closed now that multiple headers can be appended? c.f. #141