summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFilipe David Borba Manana <fdmanana@apache.org>2010-09-22 18:53:49 +0000
committerFilipe David Borba Manana <fdmanana@apache.org>2010-09-22 18:53:49 +0000
commit3c96e92582e2273bf6760a5b4561ad87cb62c69b (patch)
tree3b581e30d29e762d399cb97371b0273a9dfc5425 /src
parentf2cfb2fae3f0decab8485272cc939bc7821fc5a1 (diff)
Replicator: avoid percent encoding the slashes of design and local document IDs.
This avoids receiving and following redirect responses from the peer. It also removes the eventual need of special rules in proxies (like Apache httpd). git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@1000140 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
-rw-r--r--src/couchdb/couch_rep.erl6
-rw-r--r--src/couchdb/couch_rep_reader.erl6
-rw-r--r--src/couchdb/couch_rep_writer.erl2
-rw-r--r--src/couchdb/couch_util.erl12
4 files changed, 19 insertions, 7 deletions
diff --git a/src/couchdb/couch_rep.erl b/src/couchdb/couch_rep.erl
index 92142b77..e7c57d06 100644
--- a/src/couchdb/couch_rep.erl
+++ b/src/couchdb/couch_rep.erl
@@ -557,7 +557,7 @@ fold_replication_logs([Db|Rest]=Dbs, Vsn, LogId, NewId,
end.
open_replication_log(#http_db{}=Db, DocId) ->
- Req = Db#http_db{resource=couch_util:url_encode(?b2l(DocId))},
+ Req = Db#http_db{resource=couch_util:encode_doc_id(DocId)},
case couch_rep_httpc:request(Req) of
{[{<<"error">>, _}, {<<"reason">>, _}]} ->
?LOG_DEBUG("didn't find a replication log for ~s", [Db#http_db.url]),
@@ -767,9 +767,9 @@ ensure_full_commit(Source, RequiredSeq) ->
InstanceStartTime
end.
-update_local_doc(#http_db{} = Db, #doc{id=DocId} = Doc) ->
+update_local_doc(#http_db{} = Db, Doc) ->
Req = Db#http_db{
- resource = couch_util:url_encode(DocId),
+ resource = couch_util:encode_doc_id(Doc),
method = put,
body = couch_doc:to_json_obj(Doc, [attachments]),
headers = [{"x-couch-full-commit", "false"} | Db#http_db.headers]
diff --git a/src/couchdb/couch_rep_reader.erl b/src/couchdb/couch_rep_reader.erl
index 5c824cbc..4f81c8e4 100644
--- a/src/couchdb/couch_rep_reader.erl
+++ b/src/couchdb/couch_rep_reader.erl
@@ -17,7 +17,7 @@
-export([start_link/4, next/1]).
--import(couch_util, [url_encode/1]).
+-import(couch_util, [encode_doc_id/1]).
-define (BUFFER_SIZE, 1000).
-define (MAX_CONCURRENT_REQUESTS, 100).
@@ -234,7 +234,7 @@ open_doc_revs(#http_db{url = Url} = DbS, DocId, Revs) ->
%% all this logic just splits up revision lists that are too long for
%% MochiWeb into multiple requests
BaseQS = [{revs,true}, {latest,true}, {att_encoding_info,true}],
- BaseReq = DbS#http_db{resource=url_encode(DocId), qs=BaseQS},
+ BaseReq = DbS#http_db{resource=encode_doc_id(DocId), qs=BaseQS},
BaseLength = length(couch_rep_httpc:full_url(BaseReq)) + 11, % &open_revs=
{RevLists, _, _} = lists:foldl(fun split_revlist/2,
@@ -264,7 +264,7 @@ open_doc_revs(#http_db{url = Url} = DbS, DocId, Revs) ->
open_doc(#http_db{url = Url} = DbS, DocId) ->
% get latest rev of the doc
Req = DbS#http_db{
- resource=url_encode(DocId),
+ resource=encode_doc_id(DocId),
qs=[{att_encoding_info, true}]
},
{Props} = Json = couch_rep_httpc:request(Req),
diff --git a/src/couchdb/couch_rep_writer.erl b/src/couchdb/couch_rep_writer.erl
index 129e279c..f7bc9a72 100644
--- a/src/couchdb/couch_rep_writer.erl
+++ b/src/couchdb/couch_rep_writer.erl
@@ -119,7 +119,7 @@ write_multi_part_doc(#http_db{headers=Headers} = Db, #doc{atts=Atts} = Doc) ->
end
end,
Request = Db#http_db{
- resource = couch_util:url_encode(Doc#doc.id),
+ resource = couch_util:encode_doc_id(Doc),
method = put,
qs = [{new_edits, false}],
body = {BodyFun, nil},
diff --git a/src/couchdb/couch_util.erl b/src/couchdb/couch_util.erl
index 5c85c050..ae5cc3c4 100644
--- a/src/couchdb/couch_util.erl
+++ b/src/couchdb/couch_util.erl
@@ -28,6 +28,7 @@
-export([md5/1, md5_init/0, md5_update/2, md5_final/1]).
-export([reorder_results/2]).
-export([url_strip_password/1]).
+-export([encode_doc_id/1]).
-include("couch_db.hrl").
-include_lib("kernel/include/file.hrl").
@@ -439,3 +440,14 @@ url_strip_password(Url) ->
"http(s)?://([^:]+):[^@]+@(.*)$",
"http\\1://\\2:*****@\\3",
[{return, list}]).
+
+encode_doc_id(#doc{id = Id}) ->
+ encode_doc_id(Id);
+encode_doc_id(Id) when is_list(Id) ->
+ encode_doc_id(?l2b(Id));
+encode_doc_id(<<"_design/", Rest/binary>>) ->
+ "_design/" ++ url_encode(Rest);
+encode_doc_id(<<"_local/", Rest/binary>>) ->
+ "_local/" ++ url_encode(Rest);
+encode_doc_id(Id) ->
+ url_encode(Id).