自定义HTTP头时的注意事项

HTTP头是可以包含英文字母([A-Za-z])、数字([0-9])、连接号(-)hyphens, 也可义是下划线(_)。在使用nginx的时候应该避免使用包含下划线的HTTP头。主要的原因有以下2点。
1.默认的情况下nginx引用header变量时不能使用带下划线的变量。要解决这样的问题只能单独配置underscores_in_headers on。
2.默认的情况下会忽略掉带下划线的变量。要解决这个需要配置ignore_invalid_headers off。

当然,nginx设置变量的时候是没有任何这样的限制的,可以直接设置带下划线的header。但是最好不要这样做。在使用nginx做多级代理的时候,也需要注意一些header不要重复设置。比如用来保存用户IP的这个header只在最上层的nginx里配置就行,后面的nginx不要重复设置导致覆盖。

简单测试一下多个nginx做代理的时候处理的思路,为了方便我就直接在一个nginx上跑多个server测试

  
worker_processes  1;  
events {  
worker_connections  1024;  
}  
http {  
include       mime.types;  
default_type  application/octet-stream;  
log_format  main  ‘$http_orig_client_ip – $remote_addr – $remote_user [$time_local] "$request" ‘  
‘$status $body_bytes_sent "$http_referer" ‘  
‘"$http_user_agent" "$http_x_forwarded_for"  "$upstream_addr" ‘;  
sendfile        on;  
underscores_in_headers on;  
ignore_invalid_headers  off;  
keepalive_timeout  65;  
upstream test2081{  
server 10.209.128.28:2081;  
}  
upstream test2082{  
server 10.209.128.28:2082;  
}  
upstream test2083{  
server 10.209.128.28:80;  
}  
server {  
listen       2080;  
server_name  localhost;  
access_log  logs/access80.log  main;  
location / {  
root   html;  
proxy_set_header ORIG_CLIENT_IP $remote_addr;  
proxy_set_header Host $http_host;  
proxy_set_header X-Forwarded-By $server_addr:$server_port;  
proxy_set_header X-Forwarded-For $http_x_forwarded_for;  
proxy_pass http://test2081;  
}  
}  
server {  
listen       2081;  
server_name  localhost;  
access_log  logs/access81.log  main;  
location / {  
root   html;  
proxy_set_header Host $http_host;  
proxy_set_header X-Forwarded-By $server_addr:$server_port;  
proxy_set_header X-Forwarded-For $http_x_forwarded_for;  
proxy_pass http://test2082;  
}  
}  
server {  
listen       2082;  
server_name  localhost;  
access_log  logs/access82.log  main;  
location / {  
root   html;  
proxy_set_header Host $http_host;  
proxy_set_header X-Forwarded-By $server_addr:$server_port;  
proxy_set_header X-Forwarded-For $http_x_forwarded_for;  
proxy_pass http://test2083;  
}  
}  
}  
  
==> logs/access80.log <==  
– – 10.210.208.47 – – [29/Mar/2013:20:18:43 +0800] "GET / HTTP/1.1" 200 52873 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-"  "10.209.128.28:2081"

==> logs/access81.log <==  
10.210.208.47 – 10.209.128.28 – – [29/Mar/2013:20:18:43 +0800] "GET / HTTP/1.0" 200 52873 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-"  "10.209.128.28:2082"

==> logs/access82.log <==  
10.210.208.47 – 10.209.128.28 – – [29/Mar/2013:20:18:43 +0800] "GET / HTTP/1.0" 200 52873 "-" "curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5" "-"  "10.209.128.28:80"

server 2080收到请求后会设置一个不规范的HTTP头,后面连接了2段server。发起请求后,日志如下
可以看到2081和2082的都是能正确传递好这个header的(包括机器上80端口跑的也是可以的)。