Author: fdmanana
Date: Tue Jul 27 22:07:31 2010
New Revision: 979889

URL: http://svn.apache.org/viewvc?rev=979889&view=rev
Log:
Merge revision 979887 from trunk:

Fix issues with the replicator when using HTTP Basic authentication, receiving 
an HTTP redirect
response, and loosing the authentication credentials because they're not found 
in the Location header's URL.

This happens for example when the replicator does a request to the URI 
/somedb/_design%2Fmyddoc


Modified:
    couchdb/branches/0.11.x/src/couchdb/couch_rep_httpc.erl

Modified: couchdb/branches/0.11.x/src/couchdb/couch_rep_httpc.erl
URL: 
http://svn.apache.org/viewvc/couchdb/branches/0.11.x/src/couchdb/couch_rep_httpc.erl?rev=979889&r1=979888&r2=979889&view=diff
==============================================================================
--- couchdb/branches/0.11.x/src/couchdb/couch_rep_httpc.erl (original)
+++ couchdb/branches/0.11.x/src/couchdb/couch_rep_httpc.erl Tue Jul 27 22:07:31 
2010
@@ -91,18 +91,30 @@ db_exists(Req, CanonicalUrl, CreateDB) -
     {ok, "200", _, _} ->
         Req#http_db{url = CanonicalUrl};
     {ok, "301", RespHeaders, _} ->
-        MochiHeaders = mochiweb_headers:make(RespHeaders),
-        RedirectUrl = mochiweb_headers:get_value("Location", MochiHeaders),
+        RedirectUrl = redirect_url(RespHeaders, Req#http_db.url),
         db_exists(Req#http_db{url = RedirectUrl}, RedirectUrl);
     {ok, "302", RespHeaders, _} ->
-        MochiHeaders = mochiweb_headers:make(RespHeaders),
-        RedirectUrl = mochiweb_headers:get_value("Location", MochiHeaders),
+        RedirectUrl = redirect_url(RespHeaders, Req#http_db.url),
         db_exists(Req#http_db{url = RedirectUrl}, CanonicalUrl);
     Error ->
         ?LOG_DEBUG("DB at ~s could not be found because ~p", [Url, Error]),
         throw({db_not_found, ?l2b(Url)})
     end.
 
+redirect_url(RespHeaders, OrigUrl) ->
+    MochiHeaders = mochiweb_headers:make(RespHeaders),
+    RedUrl = mochiweb_headers:get_value("Location", MochiHeaders),
+    {url, _, Base, Port, _, _, Path, Proto} = ibrowse_lib:parse_url(RedUrl),
+    {url, _, _, _, User, Passwd, _, _} = ibrowse_lib:parse_url(OrigUrl),
+    Creds = case is_list(User) andalso is_list(Passwd) of
+    true ->
+        User ++ ":" ++ Passwd ++ "@";
+    false ->
+        []
+    end,
+    atom_to_list(Proto) ++ "://" ++ Creds ++ Base ++ ":" ++
+        integer_to_list(Port) ++ Path.
+
 full_url(#http_db{url=Url} = Req) when is_binary(Url) ->
     full_url(Req#http_db{url = ?b2l(Url)});
 
@@ -124,8 +136,7 @@ process_response({ok, Status, Headers, B
     if Code =:= 200; Code =:= 201 ->
         ?JSON_DECODE(maybe_decompress(Headers, Body));
     Code =:= 301; Code =:= 302 ->
-        MochiHeaders = mochiweb_headers:make(Headers),
-        RedirectUrl = mochiweb_headers:get_value("Location", MochiHeaders),
+        RedirectUrl = redirect_url(Headers, Req#http_db.url),
         do_request(redirected_request(Req, RedirectUrl));
     Code =:= 409 ->
         throw(conflict);


Reply via email to