This is an automated email from the ASF dual-hosted git repository. jiangphcn pushed a commit to branch COUCHDB-3326-clustered-purge-pr5-implementation in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/COUCHDB-3326-clustered-purge-pr5-implementation by this push: new d3d66c9 Set limit for Ids and total Revs in one purge req d3d66c9 is described below commit d3d66c94bfa7c9d84b8c8ea566798c0b001ecc46 Author: jiangphcn <jian...@cn.ibm.com> AuthorDate: Tue Jun 26 23:02:06 2018 +0800 Set limit for Ids and total Revs in one purge req COUCHDB-3326 --- src/chttpd/src/chttpd_db.erl | 13 +++++++++ src/chttpd/test/chttpd_purge_tests.erl | 53 +++++++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl index 83375cd..cbdb641 100644 --- a/src/chttpd/src/chttpd_db.erl +++ b/src/chttpd/src/chttpd_db.erl @@ -502,6 +502,19 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_purge">>]}=Req, Db) -> Options = [{user_ctx, Req#httpd.user_ctx}, {w, W}], {IdsRevs} = chttpd:json_body_obj(Req), IdsRevs2 = [{Id, couch_doc:parse_revs(Revs)} || {Id, Revs} <- IdsRevs], + MaxIds = config:get_integer("purge", "max_document_id_number", 100), + case length(IdsRevs2) =< MaxIds of + false -> throw({bad_request, "Document numbers larger than expected"}); + true -> ok + end, + RevsLen = lists:foldl(fun({_Id, Revs}, Acc) -> + length(Revs) + Acc + end, 0, IdsRevs2), + MaxRevs = config:get_integer("purge", "max_revisions_number", 1000), + case RevsLen =< MaxRevs of + false -> throw({bad_request, "Document revs larger than expected"}); + true -> ok + end, {ok, Results} = fabric:purge_docs(Db, IdsRevs2, Options), {Code, Json} = purge_results_to_json(IdsRevs2, Results), send_json(Req, Code, {[{<<"purge_seq">>, null}, {<<"purged">>, {Json}}]}); diff --git a/src/chttpd/test/chttpd_purge_tests.erl b/src/chttpd/test/chttpd_purge_tests.erl index 04456cb..2b06b2a 100644 --- a/src/chttpd/test/chttpd_purge_tests.erl +++ b/src/chttpd/test/chttpd_purge_tests.erl @@ -72,6 +72,7 @@ purge_test_() -> fun test_ok_purge_request/1, fun test_partial_purge_request/1, fun test_mixed_purge_request/1, + fun test_overmany_ids_or_revs_purge_request/1, fun test_exceed_limits_on_purge_infos/1, fun should_error_set_purged_docs_limit_to0/1 ] @@ -190,7 +191,7 @@ test_mixed_purge_request(Url) -> IdsRevsEJson = {[ {<<"doc1">>, [Rev1]}, % partial purge - {<<"doc2">>, [Rev3]}, % correct format, but invalid rev + {<<"doc2">>, [Rev3, Rev1]}, % correct format, but invalid rev {<<"doc3">>, [Rev3]} % correct format and rev ]}, IdsRevs = binary_to_list(?JSON_ENCODE(IdsRevsEJson)), @@ -218,6 +219,56 @@ test_mixed_purge_request(Url) -> end). +test_overmany_ids_or_revs_purge_request(Url) -> + ?_test(begin + {ok, _, _, Body} = create_doc(Url, "doc1"), + {Json} = ?JSON_DECODE(Body), + Rev1 = couch_util:get_value(<<"rev">>, Json, undefined), + + NewDoc = "{\"new_edits\": false, \"docs\": [{\"_id\": \"doc1\", + \"_revisions\": {\"start\": 1, \"ids\": [\"12345\", \"67890\"]}, + \"content\": \"updated\", \"_rev\": \"" ++ ?b2l(Rev1) ++ "\"}]}", + {ok, _, _, _} = test_request:post(Url ++ "/_bulk_docs/", + [?CONTENT_JSON, ?AUTH], NewDoc), + + {ok, _, _, _Body2} = create_doc(Url, "doc2", "content2"), + {ok, _, _, Body3} = create_doc(Url, "doc3", "content3"), + {Json3} = ?JSON_DECODE(Body3), + Rev3 = couch_util:get_value(<<"rev">>, Json3, undefined), + + IdsRevsEJson = {[ + {<<"doc1">>, [Rev1]}, % partial purge + {<<"doc2">>, [Rev3, Rev1]}, % correct format, but invalid rev + {<<"doc3">>, [Rev3]} % correct format and rev + ]}, + IdsRevs = binary_to_list(?JSON_ENCODE(IdsRevsEJson)), + + % Ids larger than expected + config:set("purge", "max_document_id_number", "1"), + {ok, Status, _, Body4} = test_request:post(Url ++ "/_purge/", + [?CONTENT_JSON, ?AUTH], IdsRevs), + config:delete("purge", "max_document_id_number"), + ResultJson = ?JSON_DECODE(Body4), + ?assertEqual(400, Status), + ?assertMatch({[ + {<<"error">>,<<"bad_request">>}, + {<<"reason">>,<<"Document numbers larger than expected">>}]}, + ResultJson), + + % Revs larger than expected + config:set("purge", "max_revisions_number", "1"), + {ok, Status2, _, Body5} = test_request:post(Url ++ "/_purge/", + [?CONTENT_JSON, ?AUTH], IdsRevs), + config:delete("purge", "max_revisions_number"), + ResultJson2 = ?JSON_DECODE(Body5), + ?assertEqual(400, Status2), + ?assertMatch({[ + {<<"error">>,<<"bad_request">>}, + {<<"reason">>,<<"Document revs larger than expected">>}]}, + ResultJson2) + end). + + test_exceed_limits_on_purge_infos(Url) -> ?_test(begin {ok, Status1, _, _} = test_request:put(Url ++ "/_purged_infos_limit/",