不知道为什么,但很高兴发送一个GET到FastCGI后端(在这种情况下是Mercurial hgwebdir),但是如果请求是一个POST,只需使用文件系统。
nginx.conf相关部分:
location / { root /var/www/htdocs/; index index.html; autoindex on; } location /hg { fastcgi_pass unix:/var/run/hg-fastcgi.socket; include fastcgi_params; if ($request_uri ~ ^/hg([^?#]*)) { set $rewritten_uri $1; } limit_except GET { allow all; deny all; auth_basic "hg secured repos"; auth_basic_user_file /var/trac.htpasswd; } fastcgi_param SCRIPT_NAME "/hg"; fastcgi_param PATH_INFO $rewritten_uri; # for authentication fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; #fastcgi_pass_header Authorization; #fastcgi_intercept_errors on; }
GET的工作正常,但POST将此错误传递给error_log:
2010/05/17 14:12:27 [error] 18736#0: *1601 open() "/usr/html/hg/test" failed (2: No such file or directory), client: XX.XX.XX.XX, server: domain.com, request: "POST /hg/test HTTP/1.1", host: "domain.com"
什么可能是这个问题? 我试图允许通过GET的只读访问页面,但需要授权时使用hg push送到发送POST请求相同的url。
这是nginx中的一个bug,修复了0.8.48 。
顺便说一句,你必须使用fastcgi_split_path_info , if好像不能用limit_except正确触发。
所以最后这样的事情应该适合你:
location /hg { fastcgi_pass unix:/var/run/hg-fastcgi.socket; include fastcgi_params; limit_except GET HEAD { auth_basic "hg secured repos"; auth_basic_user_file /var/trac.htpasswd; } fastcgi_split_path_info ^(/hg)(.*)$; fastcgi_param SCRIPT_NAME $fastcgi_script_name; fastcgi_param PATH_INFO $fastcgi_path_info; # for authentication fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; }
如果有人挖到我做的那个洞,我就是这样挖掘出来的:
location /hg { fastcgi_pass unix:/var/run/hg-fastcgi.socket; include fastcgi_params; if ($request_uri ~ ^/hg([^?#]*)) { set $rewritten_uri $1; } rewrite ^/hg$ /hg/ redirect; fastcgi_param SCRIPT_NAME "/hg"; fastcgi_param PATH_INFO $rewritten_uri; # for authentication fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; fastcgi_intercept_errors on; error_page 401 = @hgauth; } location @hgauth { fastcgi_pass unix:/var/run/hg-fastcgi.socket; include fastcgi_params; if ($request_uri ~ ^/hg([^?#]*)) { set $rewritten_uri $1; } auth_basic "hg secured repos"; auth_basic_user_file /var/trac.htpasswd; fastcgi_param SCRIPT_NAME "/hg"; fastcgi_param PATH_INFO $rewritten_uri; # for authentication fastcgi_param AUTH_USER $remote_user; fastcgi_param REMOTE_USER $remote_user; }
重要的部分是fastcgi_intercept_errors on; , error_page 401 = @hgauth; ,并使用location @hgauth { 。 我不确定是否有可能以其他方式做到这一点。 请让我知道这个答案是否有帮助!