FastCGI处理HTTP头得一点说明

http://blog.sina.com.cn/s/blog_52cf3a630100y5h0.html

1.首先在nginx fastcgi配置中:
fastcgi_param  HTTP_TRUE_CLIENT_IP $http_http_true_client_ip;
在php中通过$_SERVER["HTTP_TRUE_CLIENT_IP"]获取这个值。

 

nginx fastcgi不用作任何配置,将头部里的HTTP_TRUE_CLIENT_IP改成HTTP-TRUE-CLIENT-IP即可,nginx会过滤掉header里带_的变量,但apache照样能获取

现在是这种情况,有一个特定的请求,client的http请求头部中有一个自行定义的头部变量HTTP_TRUE_CLIENT_IP

GET /test.php HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
HTTP_TRUE_CLIENT_IP: 1.1.1.1
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT5.1; SV1; CIBA; .NET CLR 2.0.50727)
Host: 
www.test.com
Connection: Keep-Alive

http://www.pagefault.info/?p=293


nginxfastcgi模块的一个bug


在nginx0.8.40之后,如果你的fastcgi_param定义的变量以HTTP_开头,则传递给后端的头会忽略requestheader中的这个头,比如定义了一个 fastcgi_param $HTTP_HOST test,那么传递给后端时,host这个头的值就是test.

这里的逻辑是这样子的,当nginx创建一个fastcgirequest的时候,会先计算所需要的长度,首先是计算header的长度,在计算之前会先分配一个ignored数组(用来保存将要被忽略的头),它的大小是配置文件中fastcgi_param定义的以HTTP_开头的变量的个数.然后遍历所有的requestheader,如果发现header的名字和fastcgi_param中定义的变量的(HTTP_开头)名字相同(使用hash),则将这个header指针放到ignored数组中,最后在拷贝requestheader的时候直接在这个数组里面查找,如果有则跳过,否则拷贝头以及它的值。

看起来没什么问题,可是这里忽略了requestheader有可能会有重复的这个情况,此时ignored数组可能就会越界,从而导致core dump.

http://wiki.nginx.org/HttpHeadersModule#add_header

http://blog.csdn.net/vaal_water/article/details/6004372
$http_自定义header名  这里要注意 header名要都转成小写 中划线改成下划线

2、FastCGI获取头

      char *myheader = FCGX_GetParam("HTTP_TRUE_CLIENT_IP",request.envp);

3、fastcgi返回状态码

如果想要fastcgi返回401 为认证错误,要将返回的状态码放在返回的头content-type的前面,如:

                FCGX_FPrintF(request.out,"Status:401 Unauthorized\r\n"
                                                      "Content-type: text/html\r\n"
                                                      "\r\n"
                                                     "<title>401Unauthorized</title>");

          注:Content-type:text/html后需要加两个\n,表示http内容结束,接下来的部分为http内容,且此变量必须设置。

4、libcurl设置http头

               struct curl_slist *http_header = NULL;
               http_header= curl_slist_append(http_header, "HTTP_TRUE_CLIENT_IP:*****");

        注:libcurl设置头信息时不能有添加换行符\n,因为libcurl每调用一次设置头函数curl_slist_append都会自动加一个换行符\n,当在增加一个换行符\n时,就会连续出现两个换行符\n,此时http头部信息设置完,后面的头信息自动列为http内容。

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

公司的网站要加入动态加速 一个直接的问题是经过转发 客户端请求的头被改了一部分remote_addr这个被改成了自定义的True-Client-IP为了不改动已有的程序需要在nginx那转发的时候把这个头重新打到Remote_Addr 上

要实现这个 有两个关键点 现记录如下。
1 ,nginx 设置 header 搜索下很容易找到这样的例子
      proxy_set_header Host   $host;
      proxy_set_header   X-Real-IP        $remote_addr;
    但对自定义的头怎么取 就没什么例子了经过反复摸索发现nginx要取自定义的变量是这样的
    $http_自定义header名  这里要注意 header名要都转成小写 中划线改成下划线
    比如我们的  True-Client-IP到nginx里 用 $http_true_client_ip就可以接收到了
      proxy_set_header  Remote_Addr  $http_true_client_ip;
2. 因为不是所有的域名都加速了 所有有的请求是有  True-Client-IP  有的没有 ,nginx要判断下 ,没有那个头的 就转发remote_addr到后台
    开始我是这么写的
    if($http_true_client_ip!= ''){
proxy_set_header  Remote_Addr  $http_true_client_ip;
}
    会报  "proxy_set_header"directive is not allowed here 这个错误
    G之在  http://www.pubbs.net/200908/nginx/14399-possible-to-normalize-headers-in-nginx.html  得到方法,proxy_set_header  不能在if里 但 if里可以set变量
    最终配置写法:
            if($http_true_client_ip != ''){
              set $clientip $http_true_client_ip;
              break;
                }
                               
          if ($http_true_client_ip =''){
                set $clientip$remote_addr;
                  break;
                       
                       
          proxy_set_header    Remote_Addr       $clientip;
    注意: if  和 ( 之间一定要有空格 
BTW://中文的资料就那一两篇文章转来转去...哎
PS : APACHE不能直接得到转发的IP php里用getallheaders() 看到头其实是打过来了 但$_SERVER里 变成了
http_remote_addr   要直接得到真实IP需要apache上安装个mod  mod_rpaf
apache的第三方的mod 最 新版本是 mod_rpaf-0.6.tar.gz

首先安装

引用:

# tar zxvf mod_rpaf-0.6.tar.gz
# cd mod_rpaf-0.6
# /usr/local/www/apache/bin/apxs -i -c -n mod_rpaf-2.0.somod_rpaf-2.0.c
接 着在 httpd.conf中添加

LoadModule rpaf_module modules/mod_rpaf-2.0.so
RPAFenable On
RPAFsethostname On
RPAFproxy_ips 127.0.0.1 这里注意下加上nginx那台的ip 我的是10.10.10.170 
RPAFheader remote_addr

重启apache ok
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值