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 <[email protected]>
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/",