Input Headers. - headers_more_module

I am trying to figure out what I dont see request headers added to the
request.

I am trying to add ‘X-Server-ID: $id’

Here is a snippet form my config.

location /{
more_set_input_headers ‘X-Server-ID: $id’;
more_set_headers ‘X-Server-ID: $id’;

 uwsgi_pass://upstream;

}

I see X-Server-ID sent in the response headers, but my upstream
application does not seem to get the Header Variable.

I am not sure what I am doing wrong here. I read the docs here for
explanation, but I cant seem to figure it out.

and
Module ngx_http_uwsgi_module.

Thanks in advance for any help.

Il giorno 30/ago/2012, alle ore 19:12, David | StyleFlare
[email protected] ha scritto:

uwsgi_pass://upstream;
}

I see X-Server-ID sent in the response headers, but my upstream application does
not seem to get the Header Variable.

I am not sure what I am doing wrong here. I read the docs here for explanation,
but I cant seem to figure it out.
Headers More | NGINX
and
Module ngx_http_uwsgi_module.

If you need to pass custom data to a uWSGI backend just use

uwsgi_param Server_ID $id;

(you can use whatever key name you want, it will be appended to the WSGI
environ)


Roberto De Ioris
http://unbit.it
JID: [email protected]

Thanks Roberto,

That’s one way to do it.

I would still like to know why the first way of adding a request Header
in nginx didnt work.

Hello!

On Thu, Aug 30, 2012 at 10:12 AM, David | StyleFlare
[email protected] wrote:

uwsgi_pass://upstream;

}

I see X-Server-ID sent in the response headers, but my upstream application
does not seem to get the Header Variable.

The more_set_input_headers directive runs at the end of the nginx
“rewrite” phase and I think your $id variable just didn’t have a value
(yet) at that phase.

You can try inserting a constant header like this:

set $id "My-ID";
more_set_input_headers "X-Server-ID: $id";

I’ve tested the following example with nginx 1.2.3 and ngx_headers_more
0.18:

location = /t {
    set $id "123456";
    more_set_input_headers 'X-Server-ID: $id';
    uwsgi_pass 127.0.0.1:1234;
}

And then in another terminal, start “nc” to listen on the local port,
1234:

$ nc -l 1234

And then accessing the /t location defined above:

$ curl localhost:8080/t

assuming your nginx is listening on the local port 8080.

And now on the terminal running “nc”, you should get something like
this (omitted those non-printable bytes):

H  HTTP_HOST  localhostHTTP_CONNECTIONCloseHTTP_X_SERVER_ID123456

We can see that the X-Server-ID request header name and its value,
“123456”, are indeed sent by ngx_uwsgi.

Best regards,
-agentzh

Hello!

On Thu, Aug 30, 2012 at 1:12 PM, David | StyleFlare
[email protected] wrote:

Thank You

So this worked.

Cool :slight_smile:

When is $pg_server actually set?

Are you using the ngx_http_auth_request module? The auth_request
directive runs at the access phase. The order of running phases in
nginx for any nginx locations always looks like this:

rewrite phase  (set, rewrite, more_set_input_headers, 

rewrite_by_lua, etc)
access phase (auth_request, allow, deny, access_by_lua, etc)
content phase (proxy_pass, postgres_pass, uwsgi_pass,
content_by_lua, etc)
log phase (log_by_lua, etc)

A solution is to use the ngx_lua module’s access_by_lua module to
replace both auth_request and more_set_input_headers, as in

location / {
    access_by_lua '
        local res = ngx.location.capture("/auth")
        if res.status == 200 then
            ngx.req.set_header("X-Server-ID", res.var.pg_server)
        end
    ';

    uwsgi_pass ...;
}

location = /auth {
    internal;
    postgres_query "...";
    postgres_pass ...;
    postgres_set $pg_server ...;
}

You can check out the ngx_lua’s documentation for more details:

http://wiki.nginx.org/HttpLuaModule

Best regards,
-agentzh

Thank You

So this worked.

The question is then if I am setting a value in /auth

When does it get actually set?

postgres_set $pg_server 0 0 required;

Then in my location block;
I do

more_set_input_headers ‘X-Server-ID: $pg_server’;

When is $pg_server actually set?

Thanks.

Hello!

On Thu, Aug 30, 2012 at 2:30 PM, agentzh [email protected] wrote:

location / {
    access_by_lua '
        local res = ngx.location.capture("/auth")
        if res.status == 200 then
            ngx.req.set_header("X-Server-ID", res.var.pg_server)

Sorry, typo here, this line should be

             ngx.req.set_header("X-Server-ID", ngx.var.pg_server)

Best regards,
-agentzh

Strangely

I still dont see the header variable set.

I installed nginx-lua and I added the snippet you sent me to the nginx
config.

nginx starts fine, but I dont see the value set.

Any ideas?

I also upgraded to the 1.3.4 version of Nginx while I did this.

Thanks so much…

David.

LUA.

Yay I needed an excuse to play with lua.

Seriously sounds a bit scary but I will take the plunge and see what
happens.

Thanks

Hello!

On Fri, Aug 31, 2012 at 9:12 AM, David | StyleFlare
[email protected] wrote:

Strangely

I still dont see the header variable set.

I installed nginx-lua and I added the snippet you sent me to the nginx
config.

Sorry, ngx.location.capture disables nginx variable sharing between
subrequests and their parent by default (for safety reasons). You need
to explicitly allow that for your variable:

ngx.location.capture("/auth", { share_all_vars = true })

See the official documentation of ngx_lua for more details:

http://wiki.nginx.org/HttpLuaModule#ngx.location.capture

But it’s highly recommended to use the response body and/or headers
(instead of nginx variables) to return data from the subrequest back
to its parent, for example:

location / {
    access_by_lua '
        local res = ngx.location.capture("/auth")
        if res.status == 200 and res.body then
            ngx.req.set_header("X-Server-ID", res.body)
        end
    ';

    uwsgi_pass ...;
}

location = /auth {
    internal;
    postgres_query "select server_id from ...";
    postgres_pass backend;
    postgres_output  value 0 0;
}

That is, we use the postgres_output directive instead of postgres_set
in location /auth here so that the server ID data will be returned as
the subrequest’s response body.

Best regards,
-agentzh

OK I can use that method.
I prefer it.

Thank you very much for this solution. I am very excited to learn a
little
bit of LUA to.

Updated Today.

This worked nicely.

Thank you.