Merge branch 'jk/maint-http-half-auth-push'
authorJunio C Hamano <gitster@pobox.com>
Fri, 7 Sep 2012 18:09:49 +0000 (11:09 -0700)
committerJunio C Hamano <gitster@pobox.com>
Fri, 7 Sep 2012 18:09:50 +0000 (11:09 -0700)
Pushing to smart HTTP server with recent Git fails without having
the username in the URL to force authentication, if the server is
configured to allow GET anonymously, while requiring authentication
for POST.

* jk/maint-http-half-auth-push:
  http: prompt for credentials on failed POST
  http: factor out http error code handling
  t: test http access to "half-auth" repositories
  t: test basic smart-http authentication
  t/lib-httpd: recognize */smart/* repos as smart-http
  t/lib-httpd: only route auth/dumb to dumb repos
  t5550: factor out http auth setup
  t5550: put auth-required repo in auth/dumb

1  2 
http.c
t/lib-httpd.sh
t/lib-httpd/apache.conf
t/t5541-http-push.sh
t/t5551-http-fetch.sh

diff --cc http.c
index 18bc6bf7bf17bab9037fade3af2151da6b298b2d,7c4a4072f24647bd3ab6cb6c24142d31c595bb86..9bac1d89fdb639f6991bfe9f683ccf7bd5ada4cb
--- 1/http.c
--- 2/http.c
+++ b/http.c
@@@ -745,6 -744,33 +745,35 @@@ char *get_remote_object_url(const char 
        return strbuf_detach(&buf, NULL);
  }
  
+ int handle_curl_result(struct active_request_slot *slot)
+ {
+       struct slot_results *results = slot->results;
+       if (results->curl_result == CURLE_OK) {
+               credential_approve(&http_auth);
+               return HTTP_OK;
+       } else if (missing_target(results))
+               return HTTP_MISSING_TARGET;
+       else if (results->http_code == 401) {
+               if (http_auth.username && http_auth.password) {
+                       credential_reject(&http_auth);
+                       return HTTP_NOAUTH;
+               } else {
+                       credential_fill(&http_auth);
+                       init_curl_http_auth(slot->curl);
+                       return HTTP_REAUTH;
+               }
+       } else {
++#if LIBCURL_VERSION_NUM >= 0x070c00
+               if (!curl_errorstr[0])
+                       strlcpy(curl_errorstr,
+                               curl_easy_strerror(results->curl_result),
+                               sizeof(curl_errorstr));
++#endif
+               return HTTP_ERROR;
+       }
+ }
  /* http_request() targets */
  #define HTTP_REQUEST_STRBUF   0
  #define HTTP_REQUEST_FILE     1
diff --cc t/lib-httpd.sh
Simple merge
index 36b1596a10c04b5c5c095e96e8e247463eb3f022,ec8618dfde3b106c79f1d056bc0ed085075fc8c8..49d5d877ceeeba3738b0939f14d059c2a75ff3ae
@@@ -42,30 -42,25 +42,28 @@@ ErrorLog error.lo
  </IfModule>
  </IfVersion>
  
 +PassEnv GIT_VALGRIND
 +PassEnv GIT_VALGRIND_OPTIONS
 +
  Alias /dumb/ www/
- Alias /auth/ www/auth/
+ Alias /auth/dumb/ www/auth/dumb/
  
- <Location /smart/>
+ <LocationMatch /smart/>
        SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
        SetEnv GIT_HTTP_EXPORT_ALL
- </Location>
- <Location /smart_noexport/>
+ </LocationMatch>
+ <LocationMatch /smart_noexport/>
        SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
- </Location>
- <Location /smart_custom_env/>
+ </LocationMatch>
+ <LocationMatch /smart_custom_env/>
        SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH}
        SetEnv GIT_HTTP_EXPORT_ALL
        SetEnv GIT_COMMITTER_NAME "Custom User"
        SetEnv GIT_COMMITTER_EMAIL custom@example.com
- </Location>
- ScriptAlias /smart/ ${GIT_EXEC_PATH}/git-http-backend/
- ScriptAlias /smart_noexport/ ${GIT_EXEC_PATH}/git-http-backend/
- ScriptAlias /smart_custom_env/ ${GIT_EXEC_PATH}/git-http-backend/
+ </LocationMatch>
+ ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1
  <Directory ${GIT_EXEC_PATH}>
 -      Options None
 +      Options FollowSymlinks
  </Directory>
  <Files ${GIT_EXEC_PATH}/git-http-backend>
        Options ExecCGI
Simple merge
Simple merge