Logging header values from the first upstream

The HttpUpstreamModule states that variable values for
$upstream_http_$HEADER are only valid for the last upstream accessed
during a request. I’d like to know if there’s a workaround.

Specifically, I’m setting (and then clearing) headers in my first
upstream to get request-specific information like ‘username’. Here’s
what I’ve got:

===

http {
log_format myapp '$remote_addr [$time_local] ’
'$request_time ’
'"$request" $status ’
'$request_length $body_bytes_sent ’
‘"$upstream_addr" $upstream_response_time’
'$upstream_http_x_myapp_username ';

server {
    location /api/ {
        ...
        access_log /var/log/nginx/myapp_access.log myapp;

        proxy_pass http://myapp_upstream;

        more_clear_headers 'X-MyApp-Username';
        ...
    }

    location ~* /internal/media_url/(.*) {
        # only allowed for internal redirects (X-Accel-Redirect,

included)
internal;

        # still need to set our access log to get the original

request
access_log /var/log/nginx/myapp_access.log myapp;

        proxy_pass $1;
     }
}

}

===

Some of my /api accesses involve accessing media that is hosted
elsewhere, so I use
the X-Accel-Redirect header to redirect to that location.
Obviously, when the first location redirects to /internal/media_url/*,
the reference to $upstream_http_x_myapp_username in my log line refers
to the X-MyApp-Username header that is returned by the media server,
which is empty.

How can I log the username with my requests that result in an internal
redirect when the information is only available from the first upstream?

Thanks for your help!

Hello!

On Fri, Oct 11, 2013 at 12:27:34AM +0200, Matt Spitz wrote:

The HttpUpstreamModule states that variable values for
$upstream_http_$HEADER are only valid for the last upstream accessed
during a request. I’d like to know if there’s a workaround.

[…]

The $upstream_* variables are cleared once nginx starts to work
with a new upstream. If you want to preserve values before
X-Accel-Redirect, you may do so by using “set” in a destination
location of X-Accel-Redirect (this works as rewrite directives are
executed before upstream data is re-initialized). E.g.:

location /api/ {
    proxy_pass ...
}

location /internal/ {
    set $previous_upstream_http_foo $upstream_http_foo;
    proxy_pass ...
}


Maxim D.
http://nginx.org/en/donation.html

Perfect. Thank you very much!