I have a mercurial web-frontend (hgwebdir.cgi) installed on a server, and an installation of nginx was installed in front of it as a reverse proxy to the web-frontend as my friend suggested. However, whenever a large changeset is pushed (via a script), it would fail. I found an issue ticket @google-code that describe similar problem, and there is a solution that says (#39)
So the server side answer is: don't
send the 401 back early. Be as
slow/dumb as 'hg serve' and make the
hg client send the bundle twice.
How do I do that? My current nginx config
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;
}
From the access log we keep seeing 408 entries
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"
Is there anything else I can do on the server because solving it on the server side is preferable :/
Further Findings
Bitbucket seems to have this solved ( Check liquidhg bitbucket project and the Diagnosis wiki page ) on the server side, can't find the config anywhere though :/
What happens next varies depending
on your server. Some servers refuse
the BODY, simplying closing the pipe
from the client and causing
Mercurial to fail. Some, like Apache
(at least the way I configure it,
and that could be part of the
problem) and nginx (they way
BitBucket.org configures it), accept
the BODY, though it may take a few
retries. Bottom line: if Mercurial
doesn't fail the push, it sends the
changeset data at least once to a
server that has already told it it
lacks credentials (more on this at
Blame).
Assuming Mercurial is still running,
it resends the "unbundle" request
and data, this time with
authentication.
Finally, Apache accepts the data
successfully. Nginx, OTOH, at least
under BitBucket's configuration,
seems to reassemble the previous
body (the one that lacked
authentication) and somehow keep
Mercurial from re-sending the whole
body.