diff options
author | jiangphcn <jiangph@cn.ibm.com> | 2017-12-18 20:52:17 +0800 |
---|---|---|
committer | Paul J. Davis <paul.joseph.davis@gmail.com> | 2018-01-26 10:50:47 -0600 |
commit | 52e7cbe659c1125bea52f1ebd025bf092ed391aa (patch) | |
tree | b2dde34f16843e9000e4fce7ce3745dd0f1b61f0 | |
parent | 4e35b36f5d089f8dd567033f3b1db1cc846c7b14 (diff) | |
download | couchdb-52e7cbe659c1125bea52f1ebd025bf092ed391aa.tar.gz |
Decode destination header for doc copy
Fixes #977
-rw-r--r-- | src/chttpd/src/chttpd_db.erl | 3 | ||||
-rw-r--r-- | src/chttpd/test/chttpd_db_test.erl | 26 | ||||
-rw-r--r-- | src/couch/src/couch_httpd_db.erl | 3 | ||||
-rw-r--r-- | src/couch/src/test_request.erl | 10 |
4 files changed, 39 insertions, 3 deletions
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl index e621d657a..3dc9f5794 100644 --- a/src/chttpd/src/chttpd_db.erl +++ b/src/chttpd/src/chttpd_db.erl @@ -851,7 +851,8 @@ db_doc_req(#httpd{method='COPY', user_ctx=Ctx}=Req, Db, SourceDocId) -> missing_rev -> nil; Rev -> Rev end, - {TargetDocId, TargetRevs} = couch_httpd_db:parse_copy_destination_header(Req), + {TargetDocId0, TargetRevs} = couch_httpd_db:parse_copy_destination_header(Req), + TargetDocId = list_to_binary(mochiweb_util:unquote(TargetDocId0)), % open old doc Doc = couch_doc_open(Db, SourceDocId, SourceRev, []), % save new doc diff --git a/src/chttpd/test/chttpd_db_test.erl b/src/chttpd/test/chttpd_db_test.erl index f6732939c..1725f87a9 100644 --- a/src/chttpd/test/chttpd_db_test.erl +++ b/src/chttpd/test/chttpd_db_test.erl @@ -19,6 +19,10 @@ -define(PASS, "pass"). -define(AUTH, {basic_auth, {?USER, ?PASS}}). -define(CONTENT_JSON, {"Content-Type", "application/json"}). +-define(DESTHEADER1, {"Destination", "foo%E5%95%8Abar"}). +-define(DESTHEADER2, {"Destination", "foo%2Fbar%23baz%3Fpow%3Afiz"}). + + -define(FIXTURE_TXT, ?ABS_PATH(?FILE)). -define(i2l(I), integer_to_list(I)). @@ -70,7 +74,8 @@ all_test_() -> fun should_succeed_on_all_docs_with_queries_limit_skip/1, fun should_succeed_on_all_docs_with_multiple_queries/1, fun should_succeed_on_design_docs_with_multiple_queries/1, - fun should_fail_on_multiple_queries_with_keys_and_queries/1 + fun should_fail_on_multiple_queries_with_keys_and_queries/1, + fun should_return_correct_id_on_doc_copy/1 ] } } @@ -303,6 +308,25 @@ should_fail_on_multiple_queries_with_keys_and_queries(Url) -> end). +should_return_correct_id_on_doc_copy(Url) -> + ?_test(begin + {ok, _, _, _} = create_doc(Url, "testdoc"), + {_, _, _, ResultBody1} = test_request:copy(Url ++ "/testdoc/", + [?CONTENT_JSON, ?AUTH, ?DESTHEADER1]), + {ResultJson1} = ?JSON_DECODE(ResultBody1), + Id1 = couch_util:get_value(<<"id">>, ResultJson1), + + {_, _, _, ResultBody2} = test_request:copy(Url ++ "/testdoc/", + [?CONTENT_JSON, ?AUTH, ?DESTHEADER2]), + {ResultJson2} = ?JSON_DECODE(ResultBody2), + Id2 = couch_util:get_value(<<"id">>, ResultJson2), + [ + ?assertEqual(<<102,111,111,229,149,138,98,97,114>>, Id1), + ?assertEqual(<<"foo/bar#baz?pow:fiz">>, Id2) + ] + end). + + attachment_doc() -> {ok, Data} = file:read_file(?FIXTURE_TXT), {[ diff --git a/src/couch/src/couch_httpd_db.erl b/src/couch/src/couch_httpd_db.erl index 05e63ba97..79ba84dab 100644 --- a/src/couch/src/couch_httpd_db.erl +++ b/src/couch/src/couch_httpd_db.erl @@ -616,7 +616,8 @@ db_doc_req(#httpd{method='COPY'}=Req, Db, SourceDocId) -> missing_rev -> nil; Rev -> Rev end, - {TargetDocId, TargetRevs} = parse_copy_destination_header(Req), + {TargetDocId0, TargetRevs} = parse_copy_destination_header(Req), + TargetDocId = list_to_binary(mochiweb_util:unquote(TargetDocId0)), % open old doc Doc = couch_doc_open(Db, SourceDocId, SourceRev, []), % save new doc diff --git a/src/couch/src/test_request.erl b/src/couch/src/test_request.erl index a1b8b57c5..4dfde1a33 100644 --- a/src/couch/src/test_request.erl +++ b/src/couch/src/test_request.erl @@ -12,6 +12,7 @@ -module(test_request). +-export([copy/1, copy/2, copy/3]). -export([get/1, get/2, get/3]). -export([post/2, post/3, post/4]). -export([put/2, put/3, put/4]). @@ -19,6 +20,15 @@ -export([options/1, options/2, options/3]). -export([request/3, request/4, request/5]). +copy(Url) -> + copy(Url, []). + +copy(Url, Headers) -> + copy(Url, Headers, []). + +copy(Url, Headers, Opts) -> + request(copy, Url, Headers, [], Opts). + get(Url) -> get(Url, []). |