1.定义

在
./nginx-1.24.0/src/http/ngx_http_variables.c

/*
 * the $http_host, $http_user_agent, $http_referer, and $http_via
 * variables may be handled by generic
 * ngx_http_variable_unknown_header_in(), but for performance reasons
 * they are handled using dedicated entries
 */

static ngx_http_variable_t  ngx_http_core_variables[] = {

    { ngx_string("http_host"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_in.host), 0, 0 },

    { ngx_string("http_user_agent"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },

    { ngx_string("http_referer"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },

#if (NGX_HTTP_GZIP)
    { ngx_string("http_via"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_in.via), 0, 0 },
#endif

#if (NGX_HTTP_X_FORWARDED_FOR)
    { ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
#endif

    { ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
      offsetof(ngx_http_request_t, headers_in.cookie), 0, 0 },

    { ngx_string("content_length"), NULL, ngx_http_variable_content_length,
      0, 0, 0 },

    { ngx_string("content_type"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },

    { ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 },

    { ngx_string("binary_remote_addr"), NULL,
      ngx_http_variable_binary_remote_addr, 0, 0, 0 },

    { ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 },

    { ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },

    { ngx_string("proxy_protocol_addr"), NULL,
      ngx_http_variable_proxy_protocol_addr,
      offsetof(ngx_proxy_protocol_t, src_addr), 0, 0 },

    { ngx_string("proxy_protocol_port"), NULL,
      ngx_http_variable_proxy_protocol_port,
      offsetof(ngx_proxy_protocol_t, src_port), 0, 0 },

    { ngx_string("proxy_protocol_server_addr"), NULL,
      ngx_http_variable_proxy_protocol_addr,
      offsetof(ngx_proxy_protocol_t, dst_addr), 0, 0 },

    { ngx_string("proxy_protocol_server_port"), NULL,
      ngx_http_variable_proxy_protocol_port,
      offsetof(ngx_proxy_protocol_t, dst_port), 0, 0 },

    { ngx_string("proxy_protocol_tlv_"), NULL,
      ngx_http_variable_proxy_protocol_tlv,
      0, NGX_HTTP_VAR_PREFIX, 0 },

    { ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },

    { ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },

    { ngx_string("server_protocol"), NULL, ngx_http_variable_request,
      offsetof(ngx_http_request_t, http_protocol), 0, 0 },

    { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },

    { ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },

    { ngx_string("request_uri"), NULL, ngx_http_variable_request,
      offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },

    { ngx_string("uri"), NULL, ngx_http_variable_request,
      offsetof(ngx_http_request_t, uri),
      NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("document_uri"), NULL, ngx_http_variable_request,
      offsetof(ngx_http_request_t, uri),
      NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },

    { ngx_string("document_root"), NULL,
      ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("realpath_root"), NULL,
      ngx_http_variable_realpath_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("query_string"), NULL, ngx_http_variable_request,
      offsetof(ngx_http_request_t, args),
      NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("args"),
      ngx_http_variable_set_args,
      ngx_http_variable_request,
      offsetof(ngx_http_request_t, args),
      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("is_args"), NULL, ngx_http_variable_is_args,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("request_filename"), NULL,
      ngx_http_variable_request_filename, 0,
      NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },

    { ngx_string("request_method"), NULL,
      ngx_http_variable_request_method, 0,
      NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },

    { ngx_string("bytes_sent"), NULL, ngx_http_variable_bytes_sent,
      0, 0, 0 },

    { ngx_string("body_bytes_sent"), NULL, ngx_http_variable_body_bytes_sent,
      0, 0, 0 },

    { ngx_string("pipe"), NULL, ngx_http_variable_pipe,
      0, 0, 0 },

    { ngx_string("request_completion"), NULL,
      ngx_http_variable_request_completion,
      0, 0, 0 },

    { ngx_string("request_body"), NULL,
      ngx_http_variable_request_body,
      0, 0, 0 },

    { ngx_string("request_body_file"), NULL,
      ngx_http_variable_request_body_file,
      0, 0, 0 },

    { ngx_string("request_length"), NULL, ngx_http_variable_request_length,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("request_time"), NULL, ngx_http_variable_request_time,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("request_id"), NULL,
      ngx_http_variable_request_id,
      0, 0, 0 },

    { ngx_string("status"), NULL,
      ngx_http_variable_status, 0,
      NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("sent_http_content_type"), NULL,
      ngx_http_variable_sent_content_type, 0, 0, 0 },

    { ngx_string("sent_http_content_length"), NULL,
      ngx_http_variable_sent_content_length, 0, 0, 0 },

    { ngx_string("sent_http_location"), NULL,
      ngx_http_variable_sent_location, 0, 0, 0 },

    { ngx_string("sent_http_last_modified"), NULL,
      ngx_http_variable_sent_last_modified, 0, 0, 0 },

    { ngx_string("sent_http_connection"), NULL,
      ngx_http_variable_sent_connection, 0, 0, 0 },

    { ngx_string("sent_http_keep_alive"), NULL,
      ngx_http_variable_sent_keep_alive, 0, 0, 0 },

    { ngx_string("sent_http_transfer_encoding"), NULL,
      ngx_http_variable_sent_transfer_encoding, 0, 0, 0 },

    { ngx_string("sent_http_cache_control"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_out.cache_control), 0, 0 },

    { ngx_string("sent_http_link"), NULL, ngx_http_variable_header,
      offsetof(ngx_http_request_t, headers_out.link), 0, 0 },

    { ngx_string("limit_rate"), ngx_http_variable_set_limit_rate,
      ngx_http_variable_request_get_size,
      offsetof(ngx_http_request_t, limit_rate),
      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("connection"), NULL,
      ngx_http_variable_connection, 0, 0, 0 },

    { ngx_string("connection_requests"), NULL,
      ngx_http_variable_connection_requests, 0, 0, 0 },

    { ngx_string("connection_time"), NULL, ngx_http_variable_connection_time,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,
      0, 0, 0 },

    { ngx_string("hostname"), NULL, ngx_http_variable_hostname,
      0, 0, 0 },

    { ngx_string("pid"), NULL, ngx_http_variable_pid,
      0, 0, 0 },

    { ngx_string("msec"), NULL, ngx_http_variable_msec,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("time_iso8601"), NULL, ngx_http_variable_time_iso8601,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("time_local"), NULL, ngx_http_variable_time_local,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

#if (NGX_HAVE_TCP_INFO)
    { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,
      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("tcpinfo_rttvar"), NULL, ngx_http_variable_tcpinfo,
      1, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("tcpinfo_snd_cwnd"), NULL, ngx_http_variable_tcpinfo,
      2, NGX_HTTP_VAR_NOCACHEABLE, 0 },

    { ngx_string("tcpinfo_rcv_space"), NULL, ngx_http_variable_tcpinfo,
      3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
#endif

    { ngx_string("http_"), NULL, ngx_http_variable_unknown_header_in,
      0, NGX_HTTP_VAR_PREFIX, 0 },

    { ngx_string("sent_http_"), NULL, ngx_http_variable_unknown_header_out,
      0, NGX_HTTP_VAR_PREFIX, 0 },

    { ngx_string("sent_trailer_"), NULL, ngx_http_variable_unknown_trailer_out,
      0, NGX_HTTP_VAR_PREFIX, 0 },

    { ngx_string("cookie_"), NULL, ngx_http_variable_cookie,
      0, NGX_HTTP_VAR_PREFIX, 0 },

    { ngx_string("arg_"), NULL, ngx_http_variable_argument,
      0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },

      ngx_http_null_variable
};

2.分析

这个数组定义了所有可以在 Nginx 配置中使用的 内置变量(built-in variables),例如 $http_host、$remote_addr、$uri 等。


1.整体结构说明

每个元素是一个 ngx_http_variable_t 结构体,其定义大致如下(简化):

typedef struct {
    ngx_str_t                     name;          // 变量名(如 "http_host")
    ngx_http_set_variable_pt      set_handler;   // 设置变量值的回调(可为 NULL)
    ngx_http_get_variable_pt      get_handler;   // 获取变量值的回调
    uintptr_t                     data;          // 附加数据(通常是结构体偏移量或标识符)
    ngx_uint_t                    flags;         // 标志位(如 NGX_HTTP_VAR_NOCACHEABLE)
    ngx_uint_t                    index;         // 内部索引(通常为 0)
} ngx_http_variable_t;

2.详解


1. http_host

{ ngx_string("http_host"), NULL, ngx_http_variable_header,
  offsetof(ngx_http_request_t, headers_in.host), 0, 0 },
  • 变量名:$http_host
  • 作用:获取请求头中的 Host 字段。
  • 逻辑:
    • 使用通用的 ngx_http_variable_header 函数来提取 header。
    • offsetof(..., headers_in.host) 表示从 ngx_http_request_t 结构体中偏移到 headers_in.host 字段(该字段在解析请求时已填充)。
  • 为什么专用? 注释说:虽然可以用通用函数 ngx_http_variable_unknown_header_in,但为了性能,对常用 header 单独优化。

2. http_user_agent

{ ngx_string("http_user_agent"), NULL, ngx_http_variable_header,
  offsetof(ngx_http_request_t, headers_in.user_agent), 0, 0 },
  • 对应请求头 User-Agent。
  • 同样使用专用字段提升性能。

3. http_referer

{ ngx_string("http_referer"), NULL, ngx_http_variable_header,
  offsetof(ngx_http_request_t, headers_in.referer), 0, 0 },
  • 对应 Referer 请求头(注意拼写是 referer,不是 referrer,这是 HTTP 标准历史遗留)。

4. http_via(条件编译)

#if (NGX_HTTP_GZIP)
{ ngx_string("http_via"), NULL, ngx_http_variable_header,
  offsetof(ngx_http_request_t, headers_in.via), 0, 0 },
#endif
  • 仅当启用 gzip 模块时才定义 $http_via。
  • Via 头常用于代理链,记录请求经过的代理服务器。
  • 虽然逻辑上 Via 与 gzip 无直接关系,但 Nginx 将其放在 NGX_HTTP_GZIP 条件下,可能是历史原因或模块依赖。

⚠️ 实际上,在较新版本中,http_via 已不再依赖 NGX_HTTP_GZIP,但在 1.24.0 中仍如此。


5. http_x_forwarded_for(条件编译)

#if (NGX_HTTP_X_FORWARDED_FOR)
{ ngx_string("http_x_forwarded_for"), NULL, ngx_http_variable_header,
  offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0, 0 },
#endif
  • 用于获取 X-Forwarded-For 头,常用于反向代理场景传递真实客户端 IP。
  • 该功能需显式启用(通过 --with-http_x_forwarded_for_module 或默认包含)。

6. http_cookie

{ ngx_string("http_cookie"), NULL, ngx_http_variable_cookies,
  offsetof(ngx_http_request_t, headers_in.cookie), 0, 0 },
  • 获取整个 Cookie 请求头。
  • 使用专用函数 ngx_http_variable_cookies(而非通用 header 函数),因为 Cookie 可能有多个,需特殊处理。

7. content_length

{ ngx_string("content_length"), NULL, ngx_http_variable_content_length,
  0, 0, 0 },
  • 获取请求体长度(即 Content-Length 头的数值)。
  • 使用专用函数解析为整数,避免字符串处理开销。

8. content_type

{ ngx_string("content_type"), NULL, ngx_http_variable_header,
  offsetof(ngx_http_request_t, headers_in.content_type), 0, 0 },
  • 获取 Content-Type 请求头。

9. host

{ ngx_string("host"), NULL, ngx_http_variable_host, 0, 0, 0 },
  • 注意:这不是 $http_host!
  • $host 是 Nginx 特殊变量:
    • 优先取 Host 请求头;
    • 若无,则取 server_name 指令配置的值;
    • 若仍无,则取 IP 地址。
  • 常用于重定向或日志,比 $http_host 更“安全”(不会为空)。

10–12. 客户端地址相关

{ ngx_string("binary_remote_addr"), NULL, ngx_http_variable_binary_remote_addr, 0, 0, 0 },
{ ngx_string("remote_addr"), NULL, ngx_http_variable_remote_addr, 0, 0, 0 },
{ ngx_string("remote_port"), NULL, ngx_http_variable_remote_port, 0, 0, 0 },
  • binary_remote_addr:客户端 IP 的二进制形式(4 或 16 字节),用于高效比较或哈希。
  • remote_addr:客户端 IP 字符串(如 “192.168.1.1”)。
  • remote_port:客户端端口号。

13–16. Proxy Protocol 支持

{ ngx_string("proxy_protocol_addr"), ..., offsetof(ngx_proxy_protocol_t, src_addr), ... },
{ ngx_string("proxy_protocol_port"), ..., offsetof(ngx_proxy_protocol_t, src_port), ... },
{ ngx_string("proxy_protocol_server_addr"), ..., offsetof(ngx_proxy_protocol_t, dst_addr), ... },
{ ngx_string("proxy_protocol_server_port"), ..., offsetof(ngx_proxy_protocol_t, dst_port), ... },
  • 当启用了 proxy_protocol(如 listen ... proxy_protocol;),
  • 这些变量可获取原始客户端/服务端地址(由代理服务器通过 PROXY 协议传递)。

17. proxy_protocol_tlv_

{ ngx_string("proxy_protocol_tlv_"), NULL,
  ngx_http_variable_proxy_protocol_tlv,
  0, NGX_HTTP_VAR_PREFIX, 0 },
  • 支持 PROXY 协议 v2 的 TLV(Type-Length-Value)扩展字段。
  • 例如:$proxy_protocol_tlv_ssl 可获取 SSL 相关信息。
  • NGX_HTTP_VAR_PREFIX 表示这是一个前缀变量,实际使用时需拼接后缀(如 tlv_name)。

18–19. 服务器地址/端口

{ ngx_string("server_addr"), NULL, ngx_http_variable_server_addr, 0, 0, 0 },
{ ngx_string("server_port"), NULL, ngx_http_variable_server_port, 0, 0, 0 },
  • 本地服务器接收请求的 IP 和端口(即 Nginx 监听的地址)。

20. server_protocol

{ ngx_string("server_protocol"), NULL, ngx_http_variable_request,
  offsetof(ngx_http_request_t, http_protocol), 0, 0 },
  • HTTP 协议版本,如 "HTTP/1.1"。
  • 从请求结构体中直接读取。

21. scheme

{ ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },
  • 返回 "http" 或 "https"。
  • 判断依据:是否启用了 SSL(r->connection->ssl)。

22. https

{ ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
  • 若为 HTTPS,返回 "on";否则返回空字符串。
  • 常用于 if ($https) 判断。

23–26. URI 相关

{ ngx_string("request_uri"), ..., offsetof(ngx_http_request_t, unparsed_uri), ... },
{ ngx_string("uri"), ..., offsetof(ngx_http_request_t, uri), NGX_HTTP_VAR_NOCACHEABLE, ... },
{ ngx_string("document_uri"), ..., offsetof(ngx_http_request_t, uri), NGX_HTTP_VAR_NOCACHEABLE, ... },
{ ngx_string("request"), NULL, ngx_http_variable_request_line, 0, 0, 0 },
  • request_uri:原始请求 URI(含查询字符串,未解码)。
  • uri:标准化后的 URI(已解码,不含 query string)。
  • document_uri:同 uri(别名)。
  • request:完整请求行,如 "GET /index.html HTTP/1.1"。
  • NGX_HTTP_VAR_NOCACHEABLE:表示该变量值可能变化,不能缓存(如内部重写后 uri 会变)。

27–28. 文件路径

{ ngx_string("document_root"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_string("realpath_root"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 },
  • document_root:由 root 指令指定的根目录。
  • realpath_root:document_root 的绝对路径(解析符号链接后)。

29–31. 查询参数

{ ngx_string("query_string"), ..., offsetof(ngx_http_request_t, args), NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_string("args"), ngx_http_variable_set_args, ..., NGX_HTTP_VAR_CHANGEABLE|..., 0 },
{ ngx_string("is_args"), NULL, ngx_http_variable_is_args, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
  • query_string / args:URI 中 ? 后的部分(如 a=1&b=2)。
  • args 是可写的(set_handler 非空),可通过 set $args "..." 修改。
  • is_args:如果存在 query string,返回 "?",否则为空。用于拼接 URI。

32–34. 请求文件 & 方法

{ ngx_string("request_filename"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },
{ ngx_string("request_method"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 },
  • request_filename:映射到磁盘的完整文件路径(root + uri)。
  • server_name:匹配当前请求的 server_name 配置值。
  • request_method:如 "GET", "POST"。

35. remote_user

{ ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },
  • HTTP Basic Auth 认证的用户名(来自 Authorization 头)。

36–45. 响应 & 性能指标

{ ngx_string("bytes_sent"), ..., 0, 0, 0 },                // 总发送字节数
{ ngx_string("body_bytes_sent"), ..., 0, 0, 0 },           // 响应体字节数(不含头)
{ ngx_string("pipe"), ..., 0, 0, 0 },                      // 是否使用 pipe(AIO)
{ ngx_string("request_completion"), ..., 0, 0, 0 },        // "OK" 或 ""
{ ngx_string("request_body"), ..., 0, 0, 0 },              // 请求体内容(内存中)
{ ngx_string("request_body_file"), ..., 0, 0, 0 },         // 请求体临时文件路径
{ ngx_string("request_length"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 }, // 请求总长度
{ ngx_string("request_time"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 },   // 处理耗时(秒,带小数)
{ ngx_string("request_id"), ..., 0, 0, 0 },                // 唯一请求 ID(需开启)
{ ngx_string("status"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 }, // HTTP 响应状态码

46–52. 响应头变量(sent_http_*)

{ ngx_string("sent_http_content_type"), ..., 0, 0, 0 },
...
{ ngx_string("sent_http_link"), ..., offsetof(..., link), 0, 0 },
  • 这些变量反映 实际发送给客户端的响应头。
  • 例如:$sent_http_location 是重定向时发送的 Location 头。
  • 用于日志记录或调试。

53. limit_rate

{ ngx_string("limit_rate"), ngx_http_variable_set_limit_rate,
  ngx_http_variable_request_get_size,
  offsetof(ngx_http_request_t, limit_rate),
  NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
  • 控制响应速率(字节/秒)。
  • 可通过 set $limit_rate 1024; 动态限速。

54–56. 连接信息

{ ngx_string("connection"), ..., 0, 0, 0 },               // 连接 ID
{ ngx_string("connection_requests"), ..., 0, 0, 0 },      // 此连接上处理的请求数(HTTP/1.1 keep-alive)
{ ngx_string("connection_time"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 }, // 连接持续时间

57–60. 系统信息

{ ngx_string("nginx_version"), ..., 0, 0, 0 },   // 如 "1.24.0"
{ ngx_string("hostname"), ..., 0, 0, 0 },        // 主机名
{ ngx_string("pid"), ..., 0, 0, 0 },             // worker 进程 PID
{ ngx_string("msec"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 }, // 当前时间(毫秒,自 epoch)

61–62. 时间格式

{ ngx_string("time_iso8601"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 }, // ISO 8601 格式
{ ngx_string("time_local"), ..., NGX_HTTP_VAR_NOCACHEABLE, 0 },   // CLF 格式(日志常用)

63–66. TCP 信息(条件编译)

#if (NGX_HAVE_TCP_INFO)
{ ngx_string("tcpinfo_rtt"), ..., 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
...
#endif
  • 获取内核 TCP socket 信息(如 RTT、拥塞窗口等)。
  • 需系统支持 TCP_INFO(Linux 等)。

67–70. 通用前缀变量(核心机制)

67. http_
{ ngx_string("http_"), NULL, ngx_http_variable_unknown_header_in,
  0, NGX_HTTP_VAR_PREFIX, 0 },
  • 通用 HTTP 请求头变量。
  • 例如:$http_x_custom → 查找 X-Custom 请求头。
  • NGX_HTTP_VAR_PREFIX 表示这是一个前缀,运行时动态匹配。
68. sent_http_
{ ngx_string("sent_http_"), ..., ngx_http_variable_unknown_header_out, ... },
  • 通用响应头变量(只读)。
69. sent_trailer_
{ ngx_string("sent_trailer_"), ..., ngx_http_variable_unknown_trailer_out, ... },
  • HTTP/1.1 trailers(分块传输编码尾部)。
70. cookie_
{ ngx_string("cookie_"), NULL, ngx_http_variable_cookie,
  0, NGX_HTTP_VAR_PREFIX, 0 },
  • 用于提取单个 Cookie,如 $cookie_sessionid。
  • 自动解析 Cookie: a=1; b=2 并返回对应值。
71. arg_
{ ngx_string("arg_"), NULL, ngx_http_variable_argument,
  0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
  • 获取 URL 参数,如 $arg_page → 获取 ?page=2 中的 2。
  • 自动 URL 解码。

72. 结束标记

ngx_http_null_variable
  • 空变量,作为数组终止符(类似字符串的 \0)。

总结

这个数组是 Nginx 变量系统的基石,它:

  1. 高性能:常用变量(如 host、user-agent)直接映射到结构体字段,避免哈希查找。
  2. 灵活性:通过 *_prefix 机制支持无限扩展(如 $http_xxx)。
  3. 安全性:区分只读/可写变量(如 args 可写,uri 不可写)。
  4. 可观测性:提供丰富的请求/响应/连接/系统指标。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐