Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#563 closed enhancement (wontfix)

improvement proposed for ngx_http_perl_module: add header_in_set

Reported by: David Coutadeur Owned by:
Priority: minor Milestone:
Component: nginx-core Version: 1.5.x
Keywords: Cc:
uname -a: Linux debian-wheezy-64-lemon 3.2.0-4-amd64 #1 SMP Debian 3.2.54-2 x86_64 GNU/Linux
nginx -V: nginx version: nginx/1.6.0
built by gcc 4.7.2 (Debian 4.7.2-5)
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' --with-ld-opt=-Wl,-z,relro --prefix=/opt/nginx --http-log-path=/var/log/nginx16/access.log --error-log-path=/var/log/nginx16/error.log --lock-path=/var/lock/nginx16.lock --pid-path=/run/nginx16.pid --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_flv_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_mp4_module --with-http_perl_module --with-http_random_index_module --with-http_secure_link_module --with-http_spdy_module --with-http_sub_module --with-http_xslt_module --with-mail --with-mail_ssl_module --with-http_authn_request_module --add-module=/root/nginx-1.6.0/contrib/headers-more-nginx-module-0.25

Description

Hi,

I would like to set input headers in perl module, but I realized that the functionnality was not present.
It can be useful, for example for this proxy configuration example:

server {
    listen *:8080;
    server_name test.example.com;

    # SSO protection
    location / {
        authn_request /auth;
        proxy_pass http://backend.lan/;
    }
    set $redirectURL "";

    location = /auth {
        perl My::Handler;
    }
}

With this example, the Handler perl module could have the directive:
$r->header_in_set('key', 'value');
so that the final backend could use this header.

It does not seems much complicated, just a modification of nginx.xs could be sufficient. The functionnality can be found for example in HttpHeadersMoreModule for example (http://wiki.nginx.org/HttpHeadersMoreModule#more_set_input_headers)

Change History (9)

comment:1 by Maxim Dounin, 6 years ago

Resolution: wontfix
Status: newclosed

There are no plans to add an ability to modify incoming request details, it was explained more than once in the mailing list. What headers_more module does is a dirty hack.

http://mailman.nginx.org/pipermail/nginx/2011-January/024869.html
http://mailman.nginx.org/pipermail/nginx-devel/2010-February/000135.html
http://mailman.nginx.org/pipermail/nginx-devel/2013-November/004480.html

comment:2 by David Coutadeur, 6 years ago

Thanks for the links.

So what is the best practice to insert, in the perl module, headers transmitted to the backend, in a generic way ?
The backend beeing a proxy, or a local site, or whatever...

comment:3 by Maxim Dounin, 6 years ago

Provide needed data in variables (e.g., via perl_set) and use as appropriate in the configuration (e.g., in proxy_set_header).

comment:4 by David Coutadeur, 6 years ago

Ok, but this method does not permit dynamic adjustment of exported variables. For example, I want client1 to have header1 and header2, client2 to have header3, and client3 to have no header.
There is no other way ?

comment:5 by Maxim Dounin, 6 years ago

Provide values for all potentially required headers. Set the value to an empty string if a header isn't needed. See http://nginx.org/r/proxy_set_header for details.

comment:6 by David Coutadeur, 6 years ago

Hi,
I noticed that the last headers_in part of a request was weird:
r->headers_in.headers.last

I expected last to point to the last part of headers_in but instead it points to a standalone part, not linked against the part structure starting from r->headers_in.headers.part.

Here are the corresponding structure definitions:

typedef struct ngx_list_part_s  ngx_list_part_t;

struct ngx_list_part_s {
    void             *elts;
    ngx_uint_t        nelts;
    ngx_list_part_t  *next;
};


typedef struct {
    ngx_list_part_t  *last;
    ngx_list_part_t   part;
    size_t            size;
    ngx_uint_t        nalloc;
    ngx_pool_t       *pool;
} ngx_list_t;
  • the elts element of last points to the same data area as the "real" last part's elts
  • the nelts element of last has the same value as the "real" last part's nelts
  • the next element of last points to the same location as the "real" last part's next

Is this a normal behaviour ? Shouldn't just last point to the last part ?

Thank you in advance for your answer.

(if you want some proof to test it yourself, you can try this: https://jira.ow2.org/secure/attachment/12646/nginx-modperl-header_in_set-patch.tar.gz)

comment:7 by Maxim Dounin, 6 years ago

The r->headers_in isn't expected to be modified after it's created, and list members not needed for reading the list may have unexpected values. See above for a proper solution to the problem you are trying to solve.

comment:8 by David Coutadeur, 6 years ago

Ok, I have understood that point, but I was just asking if it was the normal behaviour for last pointer to point to a standalone part after the headers_in are created.
It is a general question: maybe it is not a normal behaviour and can lead to bugs in Nginx core ? Or other modules ?

comment:9 by Maxim Dounin, 6 years ago

As said in previous comment, "list members not needed for reading the list may have unexpected values". In particular, this is known to happen with subrequests, see links provided above. This is normal behaviour though, and cannot lead to bugs in nginx core, as well as modules which do not try to violate the "don't modify r->headers_in" rule.

Note: See TracTickets for help on using tickets.