config: make the leading /r/ prefix optional on https?: URLs
authorKyle J. McKay <mackyle@gmail.com>
Sat, 12 Apr 2014 04:12:54 +0000 (11 21:12 -0700)
committerKyle J. McKay <mackyle@gmail.com>
Sat, 12 Apr 2014 04:12:54 +0000 (11 21:12 -0700)
Do not require Git clients that set the User-Agent header to a
string containing "git/" (case insensitively) to use the /r/
prefix to access the https?: repository URLs.

This makes for a cleaner user experience.

Girocco/Config.pm
apache.conf

index ad6fc86..9ece320 100644 (file)
@@ -255,11 +255,19 @@ our $webadmurl = "http://repo.or.cz";
 our $htmlurl = "http://repo.or.cz/h";
 
 # HTTP URL of the repository collection (undef if N/A)
+# If mod_rewrite is enabled and the sample apache.conf configuration is used
+# (with paths suitably updated), the trailing "/r" is optional for Git clients
+# that send a User-Agent string containing "git/" (case insensitively).
 our $httppullurl = "http://repo.or.cz/r";
 
 # HTTPS push URL of the repository collection (undef if N/A)
 # If this is defined, the openssl command must be available
+# The sample apache.conf configuration requires mod_rewrite be enabled to
+# support https push operations.
 # Normally this should be set to $httppullurl with http: replaced with https:
+# If the sample apache.conf configuration is used (with paths suitably updated),
+# the trailing "/r" is optional for Git clients that send a User-Agent string
+# containing "git/" (case insensitively).
 our $httpspushurl = undef;
 
 # Git URL of the repository collection (undef if N/A)
index 9e70102..0b92fc9 100644 (file)
@@ -51,6 +51,7 @@
                Order deny,allow
                Deny from all
                <Files git-http-backend-verify>
+                       Options ExecCGI
                        Allow from all
                </Files>
                Satisfy all
        # non-smart HTTP requests can be denied directly by the web server
 
        <IfDefine !SmartHTTPOnly>
-       # These accelerate non-smart HTTP access to loose objects and packs
+       # These accelerate non-smart HTTP access to loose objects and packs with the /r/ prefix
        AliasMatch ^/r/(.*/objects/[0-9a-f]{2}/[0-9a-f]{38})$           /srv/git/$1
        AliasMatch ^/r/(.*/objects/pack/pack-[0-9a-f]{40}.(pack|idx))$  /srv/git/$1
+
+       # These accelerate non-smart HTTP access for Git user agents without the /r/ prefix
+       <IfModule rewrite_module>
+                       RewriteEngine On
+                       RewriteCond %{HTTP_USER_AGENT} git/ [NC]
+                       RewriteRule "(?x) ^/((?!r/).*/objects/(?: \
+                               (?:[0-9a-f]{2}/[0-9a-f]{38}) | \
+                               (?:pack/pack-[0-9a-f]{40}.(?:pack|idx)) ))$" \
+                               /srv/git/$1 [L]
+       </IfModule>
        </IfDefine>
 
        <IfDefine SmartHTTPOnly>
        RewriteEngine On
        RewriteCond %{REQUEST_METHOD} !^POST$
        RewriteRule ^/r/.*(?<!/info/refs)$ - [F]
+       RewriteCond %{HTTP_USER_AGENT} git/ [NC]
+       RewriteCond %{REQUEST_METHOD} !^POST$
+       RewriteRule ^/(?!r/).*(?<!/info/refs)$ - [F]
        RewriteCond %{QUERY_STRING} !(^|&)service=git-(upload|receive)-pack(&|$)
        RewriteRule ^/r/.*/info/refs$ - [F]
+       RewriteCond %{HTTP_USER_AGENT} git/ [NC]
+       RewriteCond %{QUERY_STRING} !(^|&)service=git-(upload|receive)-pack(&|$)
+       RewriteRule ^/(?!r/).*/info/refs$ - [F]
        </IfDefine>
 
        # SetEnv GIT_HTTP_BACKEND_BIN to override Config.pm $git_http_backend_bin
        ScriptAlias /r/ /home/repo/repomgr/bin/git-http-backend-verify/
 
+       # This allows HTTP access for Git user agents without the /r/ prefix
+       <IfModule rewrite_module>
+                       RewriteEngine On
+                       RewriteCond %{HTTP_USER_AGENT} git/ [NC]
+                       RewriteRule ^/(?!r/)(.*)$ \
+                               /home/repo/repomgr/bin/git-http-backend-verify/$1 \
+                               [L,H=cgi-script]
+       </IfModule>
 </VirtualHost>
 
 
        SSLVerifyDepth 3
        SSLOptions +FakeBasicAuth +StrictRequire
        SSLEngine on
-       <Location />
-               SSLRequireSSL
-       </Location>
 
        # This configuration allows fetching over https without a certificate
        # while always requiring a certificate for pushing over https
        SSLVerifyClient optional
        RewriteCond %{QUERY_STRING} (^|&)service=git-receive-pack(&|$)
        RewriteRule ^/r/.*/info/refs$ - [env=client_auth_required:1]
+       RewriteCond %{HTTP_USER_AGENT} git/ [NC]
+       RewriteCond %{QUERY_STRING} (^|&)service=git-receive-pack(&|$)
+       RewriteRule ^/(?!r/).*/info/refs$ - [env=client_auth_required:1]
        RewriteRule ^/r/.*/git-receive-pack$ - [env=client_auth_required:1]
+       RewriteCond %{HTTP_USER_AGENT} git/ [NC]
+       RewriteRule ^/(?!r/).*/git-receive-pack$ - [env=client_auth_required:1]
        RewriteCond %{ENV:client_auth_required} 1
        RewriteCond %{SSL:SSL_CLIENT_VERIFY} !^SUCCESS$
        RewriteRule .* %{REQUEST_URI} [R=401]
-       <LocationMatch ^/r/>
+       <Location />
+               SSLRequireSSL
                Order deny,allow
                Deny from env=client_auth_required
                SSLOptions +FakeBasicAuth
                Anonymous *
                Require valid-user
                Satisfy any
-       </LocationMatch>
+       </Location>
 
        # *** IMPORTANT ***
        #