<div dir="ltr">Hello,<div>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.<br></div><div>See <a href="http://lxr.nginx.org/source/src/http/ngx_http_upstream.c#0574">http://lxr.nginx.org/source/src/http/ngx_http_upstream.c#0574</a></div><div>->create_request(...) is called before ngx_http_upstream_connect(...)</div></div><div class="gmail_extra"><br><div class="gmail_quote">2015-10-12 20:04 GMT+03:00 Maxime Henrion <span dir="ltr"><<a href="mailto:mhenrion@appnexus.com" target="_blank">mhenrion@appnexus.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello Andrew,<br>
<br>
Thank you for your answer!<br>
<br>
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.<br>
<br>
Thanks,<br>
Maxime<br>
________________________________________<br>
From: nginx-devel [<a href="mailto:nginx-devel-bounces@nginx.org">nginx-devel-bounces@nginx.org</a>] on behalf of Andrew Hutchings [<a href="mailto:ahutchings@nginx.com">ahutchings@nginx.com</a>]<br>
Sent: Monday, October 12, 2015 6:04 PM<br>
To: <a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
Subject: Re: Setting a custom header on a proxied request<br>
<div class="HOEnZb"><div class="h5"><br>
Hi Maxime,<br>
<br>
I could be wrong here (I'm not an expert at this section of code), but I<br>
believe what you need to set is:<br>
<br>
r->upstream->headers_in<br>
<br>
If this doesn't work please let me know and I'll build a test to try it<br>
out here.<br>
<br>
Kind Regards<br>
Andrew<br>
<br>
On 12/10/15 15:12, Maxime Henrion wrote:<br>
> Hi all,<br>
><br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
> Here's my init_peer callback :<br>
><br>
> static ngx_int_t<br>
> ngx_http_dispatcher_upstream_init_peer(ngx_http_request_t *r,<br>
>     ngx_http_upstream_srv_conf_t *us)<br>
> {<br>
>         ngx_http_dispatcher_upstream_peer_data_t *dp;<br>
>         ngx_http_dispatcher_srv_conf_t *dscf;<br>
>         ngx_int_t rc;<br>
><br>
>         dscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_dispatcher_module);<br>
><br>
>         dp = ngx_palloc(r->pool, sizeof(ngx_http_dispatcher_upstream_peer_data_t));<br>
>         if (dp == NULL) {<br>
>                 return NGX_ERROR;<br>
>         }<br>
><br>
>         rc = dscf->original_init_peer(r, us);<br>
>         if (rc != NGX_OK) {<br>
>                 return rc;<br>
>         }<br>
><br>
>         dp->request = r;<br>
>         dp->data = r->upstream->peer.data;<br>
>         dp->original_get_peer = r->upstream->peer.get;<br>
>         dp->original_free_peer = r->upstream->peer.free;<br>
><br>
>         r->upstream->peer.data = dp;<br>
>         r->upstream->peer.get = ngx_http_dispatcher_upstream_get_peer;<br>
>         r->upstream->peer.free = ngx_http_dispatcher_upstream_free_peer;<br>
><br>
> #if (NGX_HTTP_SSL)<br>
>         dp->original_set_session = r->upstream->peer.set_session;<br>
>         dp->original_save_session = r->upstream->peer.save_session;<br>
>         r->upstream->peer.set_session = ngx_http_dispatcher_upstream_set_session;<br>
>         r->upstream->peer.save_session = ngx_http_dispatcher_upstream_save_session;<br>
> #endif<br>
><br>
>         return NGX_OK;<br>
> }<br>
><br>
> 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 :<br>
><br>
> static ngx_int_t<br>
> ngx_http_dispatcher_upstream_get_peer(ngx_peer_connection_t *pc, void *data)<br>
> {<br>
>         ngx_http_dispatcher_upstream_peer_data_t *dp = data;<br>
>         u_char addrbuf[NGX_SOCKADDR_STRLEN];<br>
>         ngx_http_request_t *r;<br>
>         ngx_table_elt_t *h;<br>
>         ngx_str_t peeraddr;<br>
>         ngx_int_t rc;<br>
><br>
>         rc = dp->original_get_peer(pc, dp->data);<br>
>         if (rc != NGX_OK) {<br>
>                 return rc;<br>
>         }<br>
><br>
>         peeraddr.data = addrbuf;<br>
>         peeraddr.len = ngx_sock_ntop(pc->sockaddr, pc->socklen, addrbuf,<br>
>             sizeof(addrbuf), 1);<br>
><br>
>         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,<br>
>             "Selected peer address is: %V", &peeraddr);<br>
><br>
>         r = dp->request;<br>
><br>
>         h = ngx_list_push(&r->headers_in.headers);<br>
>         if (h == NULL) {<br>
>                 return NGX_ERROR;<br>
>         }<br>
>         h->hash = 1;<br>
>         ngx_str_set(&h->key, "X-Shard-Addr");<br>
>         h->value.data = ngx_pstrdup(r->pool, &peeraddr);<br>
>         if (h->value.data == NULL) {<br>
>                 return NGX_ERROR;<br>
>         }<br>
><br>
>         h->value.len = peeraddr.len;<br>
><br>
>         return NGX_OK;<br>
> }<br>
><br>
> 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.<br>
><br>
> 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.<br>
><br>
> Any help would be greatly appreciated!<br>
> Thanks,<br>
> Maxime<br>
> _______________________________________________<br>
> nginx-devel mailing list<br>
> <a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
> <a href="http://mailman.nginx.org/mailman/listinfo/nginx-devel" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
><br>
<br>
--<br>
Andrew Hutchings (LinuxJedi)<br>
Senior Developer Advocate, Nginx Inc.<br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-devel" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
<br>
_______________________________________________<br>
nginx-devel mailing list<br>
<a href="mailto:nginx-devel@nginx.org">nginx-devel@nginx.org</a><br>
<a href="http://mailman.nginx.org/mailman/listinfo/nginx-devel" rel="noreferrer" target="_blank">http://mailman.nginx.org/mailman/listinfo/nginx-devel</a><br>
</div></div></blockquote></div><br></div>