Setting a custom header on a proxied request
Maxime Henrion
mhenrion at appnexus.com
Mon Oct 12 14:12:47 UTC 2015
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
More information about the nginx-devel
mailing list