Mercurial没有收到推

我有一个安装在服务器上的mercurial web-frontend(hgwebdir.cgi),并且安装了nginx作为web前端的反向代理被安装在我的朋友的build议之下。 但是,每当大的变更集被推送(通过脚本),它就会失败。 我发现了一个问题ticket @ google-code描述类似的问题,并且有一个解决scheme(#39)

所以服务器端的答案是:不要提早发回401。 像“hg serve”一样慢/哑,并使hg客户端发送捆绑包两次。

我怎么做? 我目前的nginxconfiguration

location /repo/testdomain.com { rewrite ^(.*) http://bpj.kkr.gov.my$1/hgwebdir.cgi; } location /repo/testdomain.com/ { rewrite ^(.*) http://bpj.kkr.gov.my$1hgwebdir.cgi; } location /repo/testdomain.com/hgwebdir.cgi { proxy_pass http://localhost:81/repo/testdomain.com/hgwebdir.cgi; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_buffering on; client_max_body_size 4096M; proxy_read_timeout 30000; proxy_send_timeout 30000; } 

从访问日志中我们可以看到408个条目

 incoming.ip.address - - [18/Nov/2009:08:29:31 +0800] "POST /repo/testdomain.com/hgwebdir.cgi/example_repository?cmd=unbundle&heads=73121b2b6159afc47cc3a028060902883d5b1e74 HTTP/1.1" 408 0 "-" "mercurial/proto-1.0" incoming.ip.address - - [18/Nov/2009:08:37:14 +0800] "POST /repo/testdomain.com/hgwebdir.cgi/example_repository?cmd=unbundle&heads=73121b2b6159afc47cc3a028060902883d5b1e74 HTTP/1.1" 408 0 "-" "mercurial/proto-1.0" 

有什么我可以做的服务器上,因为解决它在服务器端是最好的:/

进一步的发现

Bitbucket似乎已经解决了(检查liquidhg bitbucket项目和诊断维基页)在服务器端,但无法findconfiguration任何地方,但:/

  1. 接下来发生什么取决于您的服务器。 有些服务器拒绝BODY,简单地closures客户端的pipe道,导致Mercurial失败。 有些人,像Apache(至less是我configuration它的方式,这可能是问题的一部分)和nginx(他们的方式BitBucket.orgconfiguration它),接受BODY,虽然它可能需要一些重试。 底线:如果Mercurial没有失败的推送,它发送变更集数据至less一次到一个已经告诉它缺乏凭据的服务器(更多在这个责备)。
  2. 假设Mercurial仍在运行,则重新发送“unbundle”请求和数据,这次是通过身份validation。
  3. 最后,Apache成功接受数据。 Nginx,OTOH,至less在BitBucket的configuration下,似乎重新组装了前一个身份(缺乏身份validation的身份),并以某种方式阻止Mercurial重新发送整个身体。

我花了很多时间试图让hgwebdir和nginx一起工作,这有点麻烦,因为hgwebdir不会将请求发送到浏览器进行authentication。 最后我解决了这个问题:

 server { listen 80; listen 10240; server_name code.zofrex.com; access_log /home/zofrex/websites/code.zofrex.com/logs/access.log; error_log /home/zofrex/websites/code.zofrex.com/logs/errors.log; location / { limit_except GET { proxy_pass http://localhost:81; } fastcgi_pass 127.0.0.1:10001; include fastcgi_params; } location ~ ^/(HGBot|ZeroBotAHD|zoebot|FZeroZBot|RDPrototype|RSPS3000|zerobot|rmi) { proxy_pass http://localhost:81; } include defaults; } server { listen 81; access_log /home/zofrex/websites/code.zofrex.com/logs/access_secure.log; error_log /home/zofrex/websites/code.zofrex.com/logs/errors_secure.log; location / { auth_basic "Restricted"; auth_basic_user_file /home/zofrex/passwords; fastcgi_pass 127.0.0.1:10001; include fastcgi_params; } include defaults; } 

这是你唯一可以做的,真的,因为limit_except不能和fastcgi_pass结合 – 实际上没有条件可以,但是它们可以和proxy_pass结合使用。 不知道为什么。

那么这是如何工作的? 如果GET请求进来,它立即交给hgwebdir。 如果一个POST(即一个推送)进来,请求上游到端口81上的代理总是提示基本authentication,从而确保它发生。

为什么与巨大的正则expression式的位置? 那些受保护的项目,我想要求授权甚至读访问。

为什么在端口10240上收听? 我不记得为什么那里。

哦,我正在用spawn-fcgi使用wsgi,这就是为什么它是fastcgi_pass。 这个确切的configuration可能不适合你,但希望同样的技巧将解决你的推动困境。

问题是httplib是半双工的,服务器在响应之后主动closures套接字(其中的nginx)会导致httplib写入损坏的pipe道。 在1.4版本中有一个创可贴的解决方法,但它并没有让事情变得更快,而且完全崩溃的可能性也更小。 我不知道如何configurationnginx来做你想做的事情,但是我知道在足够大的推动下BitBucket也有这个问题。

你使用的是什么版本的Apache和nginx? 对我来说,build立一个更“完整”的testing设置可能是一个好方法。

你使用什么进行身份validation? 在二进制文件中的东西? 可能是Apache在validation失败后太快地关上了门。

另外,FWIW,liquidhg是Brad Olson的精彩作品,只是在BitBucket上托pipe。 只是想给它信用的地方。

我最近有类似的问题,并拒绝尝试listen 81解决办法。 我想出了这个。 我认为我们有类似的问题,请查看这里我的问题/答案: Nginx不会发送POST到FastCGI后端,但GET工作正常吗?

为什么不简单地做:

 server { listen 80; listen 10240; server_name code.zofrex.com; access_log /home/zofrex/websites/code.zofrex.com/logs/access.log; error_log /home/zofrex/websites/code.zofrex.com/logs/errors.log; location / { fastcgi_pass 127.0.0.1:10001; include fastcgi_params; limit_except GET HEAD { auth_basic "Restricted"; auth_basic_user_file /home/zofrex/passwords; } } location ~ ^/(HGBot|ZeroBotAHD|zoebot|FZeroZBot|RDPrototype|RSPS3000|zerobot|rmi) { auth_basic "Restricted"; auth_basic_user_file /home/zofrex/passwords; } include defaults; } 

它起作用nginx 0.8.48,在旧版本中有一个bug,其中fastcgi_pass没有被inheritance在limit_except块内。