How To Read A Custom Header From An Upstream Server In Nginx?

Published September 10, 2024

Problem: Reading Custom Headers from Upstream Servers in Nginx

Nginx, a web server and reverse proxy, sometimes needs to access custom headers from upstream servers. These headers may contain important information for request processing or logging. By default, Nginx doesn't automatically expose or pass through all upstream headers, which can be a problem for administrators who need this data.

Nginx's Solution for Reading Custom Headers

Using Nginx Variables for Header Access

Nginx offers a way to access custom headers from upstream servers. This method uses Nginx variables, which are values that can be used in different parts of the Nginx configuration.

To access custom headers, Nginx uses a prefix: $senthttp. This prefix lets you create variables that match specific headers sent by the upstream server. The prefix is followed by the header name you want to access, with hyphens replaced by underscores.

For example, to access a custom header named "My-Custom-Header", you would use the Nginx variable $sent_http_My_Custom_Header. This variable will hold the value of the "My-Custom-Header" sent by the upstream server.

This method works for any custom header, making it a useful tool for Nginx administrators who need to work with different types of upstream server responses.

Example: Logging Custom Headers

To log the value of a custom header in Nginx's access log, you can add it to the log_format directive in your Nginx configuration:

log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$sent_http_My_Custom_Header"';

access_log /var/log/nginx/access.log custom;

This configuration will include the value of the "My-Custom-Header" in each log entry.

Step-by-Step Guide to Reading Custom Headers

Identify the Custom Header

To read custom headers in Nginx, you need to find the header in the upstream server response. Custom headers are often added by the upstream server (like Apache or an application server) to provide extra information.

In this example, the custom header is:

My-custom-header: 1

This header is part of the HTTP response from the upstream server. Note the name and format of the custom header, as you'll need this information to access it in Nginx.

Tip: Header Naming Conventions

When creating custom headers, use a consistent naming convention. A common practice is to prefix your custom headers with 'X-' (e.g., X-My-Custom-Header). This helps distinguish them from standard HTTP headers and avoids potential conflicts.

Construct the Nginx Variable

After you find the custom header, you need to create the correct Nginx variable to access its value. Nginx uses a specific format for variables that represent response headers:

  1. Start with the prefix $sent_http_
  2. Add the header name, replacing hyphens with underscores
  3. The variable name is not case-sensitive

For the custom header "My-custom-header", the correct Nginx variable would be:

$sent_http_My_custom_header

This variable will contain the value of the "My-custom-header" sent by the upstream server. In this case, it would hold the value "1".

Implementing the Custom Header in Nginx Configuration

Adding the Header to Nginx Location Block

To use the custom header variable in a location block, add it to your Nginx configuration file. This lets you access the header value within that location.

Here's how to use the custom header variable in a location block:

location / {
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;

    # Access the custom header value
    add_header X-Custom-Header-Value $sent_http_My_custom_header;
}

In this setup, the value of the custom header "My-custom-header" from the upstream server is added to the response sent to the client using the add_header directive.

Tip: Log Custom Headers

To troubleshoot or monitor custom headers, you can log them in Nginx's access log:

log_format custom '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$sent_http_My_custom_header"';

access_log /var/log/nginx/access.log custom;

This will include the custom header value in each log entry, making it easier to track and debug.

Using Custom Headers in Conditional Statements

You can use custom header values in conditional statements in your Nginx configuration. This lets you make decisions based on the header value.

Here are examples of using custom headers in conditional logic:

  1. Redirecting based on header value:
location / {
    if ($sent_http_My_custom_header = "1") {
        return 301 /special-page;
    }
    # Regular processing continues here
}
  1. Modifying response based on header value:
location / {
    proxy_pass http://backend;

    if ($sent_http_My_custom_header = "premium") {
        add_header X-User-Type "Premium";
    }
}
  1. Controlling access based on header value:
location /restricted {
    if ($sent_http_My_custom_header != "authorized") {
        return 403;
    }
    # Authorized access continues here
}

These examples show how you can use the custom header value to control your Nginx server's behavior, allowing for more complex and dynamic configurations based on upstream server responses.