You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2021/11/08 19:29:43 UTC

[couchdb] branch 3.x updated: Using _bulk_docs with new_edits false and without _rev should responds 400 Bad Request

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch 3.x
in repository https://gitbox.apache.org/repos/asf/couchdb.git


The following commit(s) were added to refs/heads/3.x by this push:
     new 990b494  Using _bulk_docs with new_edits false and without _rev should responds 400 Bad Request
990b494 is described below

commit 990b4944f50ab9c6a50a3c05ffa6cf41a07745da
Author: jiahuili <Ji...@ibm.com>
AuthorDate: Tue Nov 2 23:42:39 2021 -0500

    Using _bulk_docs with new_edits false and without _rev should responds 400 Bad Request
---
 src/chttpd/src/chttpd_db.erl             | 12 +++++++++++-
 src/chttpd/test/eunit/chttpd_db_test.erl | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 95457ff..8d45eb7 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -535,15 +535,17 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>], user_ctx=Ctx}=Req,
     _ ->
         Options = [{user_ctx,Ctx}, {w,W}]
     end,
+    NewEdits = couch_util:get_value(<<"new_edits">>, JsonProps, true),
     Docs = lists:map(fun(JsonObj) ->
         Doc = couch_db:doc_from_json_obj_validate(Db, JsonObj),
+        validate_revs(Doc, NewEdits),
         validate_attachment_names(Doc),
         case Doc#doc.id of
             <<>> -> Doc#doc{id = couch_uuids:new()};
             _ -> Doc
         end
     end, DocsArray),
-    case couch_util:get_value(<<"new_edits">>, JsonProps, true) of
+    case NewEdits of
     true ->
         Options2 =
         case couch_util:get_value(<<"all_or_nothing">>, JsonProps) of
@@ -1960,6 +1962,14 @@ validate_security_can_be_edited(DbName) ->
         {_,_} -> ok
     end.
 
+validate_revs(_Doc, true) ->
+    ok;
+validate_revs(#doc{revs = {0, []}}, false) ->
+    throw({bad_request, ?l2b("When `new_edits: false`, " ++
+        "the document needs `_rev` or `_revisions` specified")});
+validate_revs(_Doc, false) ->
+    ok.
+
 validate_attachment_names(Doc) ->
     lists:foreach(fun(Att) ->
         Name = couch_att:fetch(name, Att),
diff --git a/src/chttpd/test/eunit/chttpd_db_test.erl b/src/chttpd/test/eunit/chttpd_db_test.erl
index 6ae5ad0..15e7539 100644
--- a/src/chttpd/test/eunit/chttpd_db_test.erl
+++ b/src/chttpd/test/eunit/chttpd_db_test.erl
@@ -62,6 +62,8 @@ all_test_() ->
                 fun setup/0, fun teardown/1,
                 [
                     fun should_return_ok_true_on_bulk_update/1,
+                    fun should_return_201_new_edits_false_with_revs_on_bulk_update/1,
+                    fun should_return_400_new_edits_false_no_revs_on_bulk_update/1,
                     fun should_return_ok_true_on_ensure_full_commit/1,
                     fun should_return_404_for_ensure_full_commit_on_no_db/1,
                     fun should_accept_live_as_an_alias_for_continuous/1,
@@ -106,6 +108,36 @@ should_return_ok_true_on_bulk_update(Url) ->
         end)}.
 
 
+should_return_201_new_edits_false_with_revs_on_bulk_update(Url) ->
+    {timeout, ?TIMEOUT, ?_test(
+        begin
+            {ok, _, _, Body} = create_doc(Url, "dochasrev"),
+            {Json} = ?JSON_DECODE(Body),
+            Ref = couch_util:get_value(<<"rev">>, Json, undefined),
+            NewDoc = "{\"docs\": [{\"_rev\": \"" ++ ?b2l(Ref) ++
+                "\", \"_id\": \"dochasrev\"}], \"new_edits\": false}",
+            {ok, Status, _, ResultBody} = test_request:post(Url ++
+                "/_bulk_docs/", [?CONTENT_JSON, ?AUTH], NewDoc),
+            ?assertEqual(201, Status),
+            ?assertEqual([], ?JSON_DECODE(ResultBody))
+        end)}.
+
+
+should_return_400_new_edits_false_no_revs_on_bulk_update(Url) ->
+    {timeout, ?TIMEOUT, ?_test(
+        begin
+            {ok, _, _, _} = create_doc(Url, "docnorev"),
+            NewDoc = "{\"docs\": [{\"_id\": \"docnorev\"}], "
+                ++ "\"new_edits\": false}",
+            {ok, Status, _, ResultBody} = test_request:post(Url ++
+                "/_bulk_docs/", [?CONTENT_JSON, ?AUTH], NewDoc),
+            {ResultJson} = ?JSON_DECODE(ResultBody),
+            ?assertEqual(400, Status),
+            ?assertEqual(<<"bad_request">>,
+                couch_util:get_value(<<"error">>, ResultJson))
+        end)}.
+
+
 should_return_ok_true_on_ensure_full_commit(Url0) ->
     {timeout, ?TIMEOUT, ?_test(begin
         Url = Url0 ++ "/_ensure_full_commit",