All subversion checkouts, commits and other basic operations work as expected, but when attempting to copy, move or tag (copy) a (502 Bad Gateway) error presents itself.
greg@codemine:~/code/Foo (git-svn)-[trunk] %>; git svn tag foo-2.1.1 Copying https://svn/projects/Foo/trunk at r18311 to https://svn/projects/Foo/tags/foo-2.1.1... RA layer request failed: Server sent unexpected return value (502 Bad Gateway) in response to COPY request for '/projects/!svn/bc/18311/Foo/trunk' at /usr/libexec/git-core/git-svn line 1123
There is a machine running nginx on port 80 (and 443 SSL) that serves as a reverse proxy for among other things subversion repositories. subversion runs on the backend on apache2.
When performing a remote svn operation like MOVE or COPY the actual request is translated into a WebDAV request that looks similar to this:
COPY /svn/repos/oldname.txt HTTP/1.1 Host: svn.example.org Destination: https://svn.example.org/svn/repos/newname.txt
Apache, the webserver, translates the above request to:
COPY https://svn.example.org/svn/repos/oldname.txt https://svn.example.org/svn/repos/newname.txt
It uses the Host parameter svn.example.org and the first request line COPY /svn/repos/oldname.txt HTTP/1.1 to assemble the source URL, https://svn.example.org/svn/repos/oldname.txt.
However, since requests are being reverse proxied through nginx, the source URL is changed from https:// to http:// as Apache listens on port 80 (HTTP). This results in a COPY operation that looks like this:
COPY http://svn.example.org/svn/repos/oldname.txt https://svn.example.org/svn/repos/newname.txt
Apache determines it can not move a file http://svn.example.org/svn/repos/oldname.txt to https://svn.example.org/svn/repos/newname.txt, for as far as Apache is concerned http://svn.example.org/ and https://svn.example.org/ are two entirely different hosts. This results with a "502 Bad Gateway" error.
Configure nginx to change the Destination header in the same way it changes the Host header; whereas, Apache can then handle the COPY or MOVE operation correctly. This is done by adding the following to your nginx configuration:
set $fixed_destination $http_destination; if ( $http_destination ~* ^https(.*)$ ) { set $fixed_destination http$1; } proxy_set_header Destination $fixed_destination;
/etc/nginx/sites-available/svn.example.org
server { listen 80; server_name svn.example.org; rewrite ^(.*) https://svn.example.org$1 permanent; } server { listen 443; server_name svn.example.org; ssl on; ssl_certificate /etc/nginx/conf.d/svn.example.org.crt; ssl_certificate_key /etc/nginx/conf.d/svn.example.org.key; ssl_verify_depth 3; client_max_body_size 100m; access_log /var/log/nginx/svn.example.org-access.log; location / { set $fixed_destination $http_destination; if ( $http_destination ~* ^https(.*)$ ) { set $fixed_destination http$1; } proxy_set_header Destination $fixed_destination; proxy_set_header Host $http_host; proxy_pass http://localhost:9080; proxy_connect_timeout 75; proxy_read_timeout 300; proxy_send_timeout 300; } }
/etc/apache2/sites-available/svn.example.org
<VirtualHost *:9080> ServerName svn.example.org ErrorLog /var/log/apache2/svn.example.org-error.log <Location /> DAV svn DAVMinTimeout 0 SVNParentPath /home/svn AuthType Basic AuthName "Subversion Repos" AuthUserFile /home/svn/.htpasswd AuthzSVNAccessFile /home/svn/conf/authz Require valid-user </Location> </VirtualHost>
Source(s)
https://sigterm.sh/2012/10/09/nginx-apache-2-and-subversion-502-bad-gateway-error/