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/",

Reply via email to