如何使git智能http传输工作在nginx上?

我尝试过很多不同的方式。 这可能是我设法实现的最好的configuration。

nginx

 server { server_name git.domain.com; access_log /var/log/nginx/git.domain.com-access.log; error_log /var/log/nginx/git.domain.com-error.log; include common; location / { fastcgi_pass unix:/var/run/fcgiwrap.socket; # fastcgi_param DOCUMENT_ROOT /home/yuri/git; # fastcgi_param SCRIPT_NAME /1.pl; fastcgi_param DOCUMENT_ROOT /usr/lib/git-core; fastcgi_param SCRIPT_NAME /git-http-backend; include fastcgi_params; fastcgi_param DOCUMENT_ROOT /home/yuri/git; fastcgi_param GIT_HTTP_EXPORT_ALL ""; fastcgi_param GIT_PROJECT_ROOT /home/yuri/git; fastcgi_param PATH_INFO $request_uri; } } 

我写了一个脚本来拦截fcgiwrapgit-http-backend之间的数据。 这里是:

 #!/usr/bin/perl use Data::Dumper; my $output = `/usr/lib/git-core/git-http-backend`; open my $fh, '>', '/home/yuri/git/1/1.txt'; print $fh $output; print $fh Dumper {map {$_ => $ENV{$_}} 'QUERY_STRING', 'REQUEST_METHOD', 'CONTENT_TYPE', 'CONTENT_LENGTH', 'SCRIPT_NAME', 'REQUEST_URI', 'DOCUMENT_URI', 'DOCUMENT_ROOT', 'SERVER_PROTOCOL', 'GATEWAY_INTERFACE', 'SERVER_SOFTWARE', 'REMOTE_ADDR', 'REMOTE_PORT', 'SERVER_ADDR', 'SERVER_PORT', 'SERVER_NAME', 'REDIRECT_STATUS'}; print $output; 

这里是我得到的输出:

 $ git clone http://git.domain.com/1.git Cloning into '1'... fatal: http://git.domain.com/1.git/info/refs?service=git-upload-pack not found: did you run git update-server-info on the server? 

显然,我没有运行git update-server-info 。 因为举例来说,我可以在不使用git-http-backend情况下克隆这个存储库:

 server { server_name git.domain.com; root /home/yuri/git; } 

这里是我在1.txt获得的数据:

 Status: 404 Not Found^M Expires: Fri, 01 Jan 1980 00:00:00 GMT^M Pragma: no-cache^M Cache-Control: no-cache, max-age=0, must-revalidate^M ^M $VAR1 = { 'SERVER_NAME' => 'git.domain.com', 'SCRIPT_NAME' => '/1.git/info/refs', 'CONTENT_LENGTH' => '', 'REQUEST_METHOD' => 'GET', 'SERVER_SOFTWARE' => 'nginx/0.7.67', 'REMOTE_PORT' => '53908', 'QUERY_STRING' => 'service=git-upload-pack', 'SERVER_PORT' => '80', 'REDIRECT_STATUS' => '200', 'REMOTE_ADDR' => 'xxxx', 'CONTENT_TYPE' => '', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'DOCUMENT_URI' => '/1.git/info/refs', 'REQUEST_URI' => '/1.git/info/refs?service=git-upload-pack', 'GATEWAY_INTERFACE' => 'CGI/1.1', 'SERVER_ADDR' => 'xxxx', 'DOCUMENT_ROOT' => '/home/yuri/git' }; 

我正在运行Debian squeezefcgiwrap-1.0git-1.7.2.5nginx-0.7.67

UPD我将不胜感激,如果有人能至less提供我的脚本在Apache下的输出?


在附注中,这个版本的fcgiwrap忽略了SCRIPT_FILENAMEDOCUMENT_ROOTSCRIPT_NAME连接在一起,并再次分解为脚本名称和PATH_INFO 。 但是第一个fastcgi_param DOCUMENT_ROOT必须指向正确的位置,否则fcgiwrap会因某种原因找不到脚本。 也就是说,这不起作用:

  fastcgi_param DOCUMENT_ROOT $document_root; # /usr/local/nginx/html fastcgi_param DOCUMENT_ROOT /home/yuri/git; 

但是这个工作:

  fastcgi_param DOCUMENT_ROOT /home/yuri/git; fastcgi_param DOCUMENT_ROOT $document_root; # /usr/local/nginx/html 

这是nginxconfiguration稍微模糊的原因:

  fastcgi_param DOCUMENT_ROOT /usr/lib/git-core; ... include fastcgi_params; fastcgi_param DOCUMENT_ROOT /home/yuri/git; 

但有一些设置时,它的工作…

DOCUMENT_ROOT + SCRIPT_NAME不能与PATH_INFO结合。 改为使用绝对SCRIPT_FILENAME (因为您的git-http-backend程序位于文档根目录之外)。

作为一个debugging提示,为了testing智能HTTP是否有效,请查看您的访问日志。

以下configuration在Debian 7.0 Wheezy上testing:

 # based on http-backend.c from git v1.8.2.1, service_cmd location ~ "^/[a-zA-Z0-9._-]+/(git-(receive|upload)-pack|HEAD|info/refs|objects/(info/(http-)?alternates|packs)|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\.(pack|idx))$" { fastcgi_param SCRIPT_FILENAME /usr/lib/git-core/git-http-backend; fastcgi_param GIT_PROJECT_ROOT /home/yuri/git; fastcgi_param PATH_INFO $fastcgi_script_name; include fastcgi_params; fastcgi_pass unix:/var/run/fcgi-wrap.sock; } 

添加诸如GIT_HTTP_EXPORT_ALL选项是读者的练习。

它没有工作的问题是PATH_INFO设置不正确。 由于“ DOCUMENT_ROOTSCRIPT_NAME被连接并再次分裂为脚本名称和PATH_INFO ”。 这是工作的configuration:

 server { server_name domain.com; root /home/yuri/git; access_log /var/log/nginx/domain.com-access.log; error_log /var/log/nginx/domain.com-error.log; location / { fastcgi_pass unix:/var/run/fcgiwrap.socket; fastcgi_param DOCUMENT_ROOT /usr/lib/git-core; fastcgi_param SCRIPT_NAME /git-http-backend$fastcgi_script_name; include fastcgi_params; fastcgi_param GIT_HTTP_EXPORT_ALL ""; fastcgi_param GIT_PROJECT_ROOT /home/yuri/git; } } 

然后你可以像这样克隆版本库:

 git clone http://domain.com/1.git 

1.git位于/home/yuri/git