Nginx perl模块处理post请求

接到一个有点无理的需求,需在nginx中对post的请求连接做逻辑重定向(前提是不增加任何后端动态服务)。
那就使用以下nginx的perl模块了(基本用法已在前些文章介绍过,或看nginx wiki的官网)。
编译一下nginx从而带入perl模块。(If you want to enable this module, is necessary to specify --with-http_perl_module when running configure.)

http://wiki.nginx.org/EmbeddedPerlModule  语法

写个对post的处理代码。
vi hpost.pm
package hpost;
use nginx;

sub handler {
  my $r = shift;
  if ($r->request_method ne "POST") {//如果不是post请求直接过掉不处理。
    return DECLINED;
  }

  if ($r->has_request_body(\&post)) {//存在request body内容,则对body数据进行处理
    return OK;
  }

  return 400;

}

sub post {
  my $r = shift;
  my $url = "test.php";
  #Test Unit---Start  测试单元
  #$r->send_http_header;
  #$r->print("request_body: \"", $r->request_body, "\"<br/>");
  #$r->print("request_body_file: \"", $r->request_body_file, "\"<br/>\n");
  #Test Unit---End
  if($r->request_body eq "mytest=1") { //可对body内容进行字符串的相关处理--从而进行逻辑相关的工作,这里只做测试
     $url = "test.jsp";
  }
  $r->internal_redirect($url); //根据相关的post数据进行相关的内部重定向
  return OK;
}
1;


nginx配置文件中进行调用:

http {
    include       mime.types;
    default_type  application/octet-stream;
    perl_modules  perl/lib; //引入perl相关类库
    perl_require  hpost.pm; //与nginx.conf配置文件在同一目录下
      ……
      ……
      ……
  server {
          listen       81;
          server_name  localhost;
            location ~ .*\.jsp$ {
             return 400;
       }
       location ~ .*\.php$ {
             return 401;
       }

        

        location / {
            #root   html;
            #index  index.html index.htm;
             #error_page 405 =200 /;
              perl  hpost::handler;
        } 
  }

}

可用 curl -d "mytest=1" http://127.0.0.1:81/  进行测试。


使用了perl模块后,尽量避免进行reload操作(kill -HUP pid 对造成使用perl模块nginx内存泄露--存在这个风险)
使用perl的代码越短越好,尽量降低nginx的性能消耗。


---------------------------------------------------------------------------------------------
今天测试将php的处理location 增加内容
    location ~ .*\.php {
        #return 402;
        #proxy_pass http://127.0.0.1:82;
        #proxy_set_header   Host             $host;
        #proxy_set_header   X-Real-IP        $remote_addr;
        #proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        expires off;
        fastcgi_hide_header X-Powered-By;
        include fastcgi_params;
        fastcgi_pass US_PHP404;
        #fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  /data1/www/itweb_up$fastcgi_script_name;
    }

但发现proxy pass后$uri $host $remote_add 等变量都为空,后端php就不能正确获取到
相应的http资源;经过一大堆测试问题还是没解决,决定换一个nginx版本进行测试(原为0.7
更换后为0.8);更换版本后所有变量回来了。

解决变量丢失问题后,又出现一个问题:proxy pass 过去后 uri还是原来用户请求的uri,
不是经过perl 模块更改的uri。
问题解决方法:
在pass 前增加rewrite (.*)    $1 break;作用为将内部跳转后所得的uri重写
到proxy pass中。
    location ~ .*\.php {
        #return 402;
        #proxy_pass http://127.0.0.1:82;
        #proxy_set_header   Host             $host;
        #proxy_set_header   X-Real-IP        $remote_addr;
        #proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        rewrite (.*)    $1 break;
        expires off;
        fastcgi_hide_header X-Powered-By;
        include fastcgi_params;
        fastcgi_pass US_PHP404;
        #fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  /data1/www/itweb_up$fastcgi_script_name;
    }

相关推荐