Setting a custom header on a proxied request

Sorin Manole sorin.v.manole at gmail.com
Mon Oct 12 18:07:07 UTC 2015


Hello,
This doesn't work probably because the request data (headers + body) that
is sent to the upstream is "compiled" before the actual connection is
established.
See http://lxr.nginx.org/source/src/http/ngx_http_upstream.c#0574
->create_request(...) is called before ngx_http_upstream_connect(...)

2015-10-12 20:04 GMT+03:00 Maxime Henrion <mhenrion at appnexus.com>:

> Hello Andrew,
>
> Thank you for your answer!
>
> I tried setting my header in r->upstream->headers_in but unfortunately, it
> seems the headers ngx_list_t isn't initialized yet at this point, and thus
> I end up with a crash in ngx_list_push(). I wish I could just initialize it
> myself, but it would most likely get overwritten when the actual
> initialization takes place.
>
> Thanks,
> Maxime
> ________________________________________
> From: nginx-devel [nginx-devel-bounces at nginx.org] on behalf of Andrew
> Hutchings [ahutchings at nginx.com]
> Sent: Monday, October 12, 2015 6:04 PM
> To: nginx-devel at nginx.org
> Subject: Re: Setting a custom header on a proxied request
>
> Hi Maxime,
>
> I could be wrong here (I'm not an expert at this section of code), but I
> believe what you need to set is:
>
> r->upstream->headers_in
>
> If this doesn't work please let me know and I'll build a test to try it
> out here.
>
> Kind Regards
> Andrew
>
> On 12/10/15 15:12, Maxime Henrion wrote:
> > Hi all,
> >
> >
> > I'm currently writing an nginx module that sends a number of subrequests
> to upstream servers based on application logic, and then aggregates the
> results and send them back. That part currently works just fine, thanks to
> the help I was given here in the past.
> >
> > However, I am now trying to add a custom header to the request that is
> being proxied and currently failing at it. For various technical reasons, I
> need to add a header that contains the IP address and port (from the point
> of view of nginx) of the upstream server currently being contacted. In
> order to get at that address, I have hooked my module into the peer
> selection mechanism, much like the keepalive, ip_hash modules and others
> do. So far so good, I get at that address and can log it just fine.
> However, I can't seem to be able to add it as a header to my request.
> >
> > Here's my init_peer callback :
> >
> > static ngx_int_t
> > ngx_http_dispatcher_upstream_init_peer(ngx_http_request_t *r,
> >     ngx_http_upstream_srv_conf_t *us)
> > {
> >         ngx_http_dispatcher_upstream_peer_data_t *dp;
> >         ngx_http_dispatcher_srv_conf_t *dscf;
> >         ngx_int_t rc;
> >
> >         dscf = ngx_http_conf_upstream_srv_conf(us,
> ngx_http_dispatcher_module);
> >
> >         dp = ngx_palloc(r->pool,
> sizeof(ngx_http_dispatcher_upstream_peer_data_t));
> >         if (dp == NULL) {
> >                 return NGX_ERROR;
> >         }
> >
> >         rc = dscf->original_init_peer(r, us);
> >         if (rc != NGX_OK) {
> >                 return rc;
> >         }
> >
> >         dp->request = r;
> >         dp->data = r->upstream->peer.data;
> >         dp->original_get_peer = r->upstream->peer.get;
> >         dp->original_free_peer = r->upstream->peer.free;
> >
> >         r->upstream->peer.data = dp;
> >         r->upstream->peer.get = ngx_http_dispatcher_upstream_get_peer;
> >         r->upstream->peer.free = ngx_http_dispatcher_upstream_free_peer;
> >
> > #if (NGX_HTTP_SSL)
> >         dp->original_set_session = r->upstream->peer.set_session;
> >         dp->original_save_session = r->upstream->peer.save_session;
> >         r->upstream->peer.set_session =
> ngx_http_dispatcher_upstream_set_session;
> >         r->upstream->peer.save_session =
> ngx_http_dispatcher_upstream_save_session;
> > #endif
> >
> >         return NGX_OK;
> > }
> >
> > Note that I save the pointer to the ngx_http_request_t object in my peer
> data structure to access it later. Now here's my peer selection hook :
> >
> > static ngx_int_t
> > ngx_http_dispatcher_upstream_get_peer(ngx_peer_connection_t *pc, void
> *data)
> > {
> >         ngx_http_dispatcher_upstream_peer_data_t *dp = data;
> >         u_char addrbuf[NGX_SOCKADDR_STRLEN];
> >         ngx_http_request_t *r;
> >         ngx_table_elt_t *h;
> >         ngx_str_t peeraddr;
> >         ngx_int_t rc;
> >
> >         rc = dp->original_get_peer(pc, dp->data);
> >         if (rc != NGX_OK) {
> >                 return rc;
> >         }
> >
> >         peeraddr.data = addrbuf;
> >         peeraddr.len = ngx_sock_ntop(pc->sockaddr, pc->socklen, addrbuf,
> >             sizeof(addrbuf), 1);
> >
> >         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
> >             "Selected peer address is: %V", &peeraddr);
> >
> >         r = dp->request;
> >
> >         h = ngx_list_push(&r->headers_in.headers);
> >         if (h == NULL) {
> >                 return NGX_ERROR;
> >         }
> >         h->hash = 1;
> >         ngx_str_set(&h->key, "X-Shard-Addr");
> >         h->value.data = ngx_pstrdup(r->pool, &peeraddr);
> >         if (h->value.data == NULL) {
> >                 return NGX_ERROR;
> >         }
> >
> >         h->value.len = peeraddr.len;
> >
> >         return NGX_OK;
> > }
> >
> > So after getting at the actual address we're forwarding our request to,
> I try to add a custom header to r->headers_in, on the request object that I
> saved in my peer data.
> >
> > I suspect I'm not actually dealing with the correct request here,
> because no matter what I try, I can't get this code to actually alter the
> headers of the forwarded request in any way.
> >
> > Any help would be greatly appreciated!
> > Thanks,
> > Maxime
> > _______________________________________________
> > nginx-devel mailing list
> > nginx-devel at nginx.org
> > http://mailman.nginx.org/mailman/listinfo/nginx-devel
> >
>
> --
> Andrew Hutchings (LinuxJedi)
> Senior Developer Advocate, Nginx Inc.
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20151012/aa3d4db6/attachment.html>


More information about the nginx-devel mailing list