couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vatam...@apache.org
Subject [1/2] couch commit: updated refs/heads/master to c50a8cd
Date Thu, 16 Mar 2017 02:34:55 GMT
Repository: couchdb-couch
Updated Branches:
  refs/heads/master 2d984b59e -> c50a8cda6


Allow limiting maximum document body size

Configuration is via the `couchdb.max_document_size`. In the past that
was implemented as a maximum http request body size and this finally implements
it by actually checking a document's body size.

COUCHDB-2992


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch/commit/7e48bda4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch/tree/7e48bda4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch/diff/7e48bda4

Branch: refs/heads/master
Commit: 7e48bda4459cc8e4dbb8bd86966792f533571d83
Parents: 2d984b5
Author: Nick Vatamaniuc <vatamane@apache.org>
Authored: Mon Mar 13 02:33:57 2017 -0400
Committer: Nick Vatamaniuc <vatamane@apache.org>
Committed: Wed Mar 15 22:33:22 2017 -0400

----------------------------------------------------------------------
 src/couch_doc.erl             | 14 ++++++++++++--
 src/couch_httpd_db.erl        |  8 ++++----
 test/couch_doc_json_tests.erl | 21 ++++++++++++++++++---
 3 files changed, 34 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/7e48bda4/src/couch_doc.erl
----------------------------------------------------------------------
diff --git a/src/couch_doc.erl b/src/couch_doc.erl
index a913eee..381ad4b 100644
--- a/src/couch_doc.erl
+++ b/src/couch_doc.erl
@@ -13,7 +13,7 @@
 -module(couch_doc).
 
 -export([to_doc_info/1,to_doc_info_path/1,parse_rev/1,parse_revs/1,rev_to_str/1,revs_to_strs/1]).
--export([from_json_obj/1,to_json_obj/2,has_stubs/1, merge_stubs/2]).
+-export([from_json_obj/1, from_json_obj_validate/1, to_json_obj/2,has_stubs/1, merge_stubs/2]).
 -export([validate_docid/1, get_validate_doc_fun/1]).
 -export([doc_from_multi_part_stream/2, doc_from_multi_part_stream/3]).
 -export([doc_to_multi_part_stream/5, len_doc_to_multi_part_stream/4]).
@@ -124,6 +124,16 @@ doc_to_json_obj(#doc{id=Id,deleted=Del,body=Body,revs={Start, RevIds},
         ++ to_json_attachments(Doc#doc.atts, Options)
     }.
 
+from_json_obj_validate(EJson) ->
+    MaxSize = config:get_integer("couchdb", "max_document_size", 4294967296),
+    Doc = from_json_obj(EJson),
+    case erlang:external_size(Doc#doc.body) =< MaxSize of
+        true ->
+             Doc;
+        false ->
+            throw({request_entity_too_large, Doc#doc.id})
+    end.
+
 from_json_obj({Props}) ->
     transfer_fields(Props, #doc{body=[]});
 
@@ -414,7 +424,7 @@ doc_from_multi_part_stream(ContentType, DataFun, Ref) ->
     {{started_open_doc_revs, NewRef}, Parser, _ParserRef} ->
         restart_open_doc_revs(Parser, Ref, NewRef);
     {{doc_bytes, Ref, DocBytes}, Parser, ParserRef} ->
-        Doc = from_json_obj(?JSON_DECODE(DocBytes)),
+        Doc = from_json_obj_validate(?JSON_DECODE(DocBytes)),
         erlang:put(mochiweb_request_recv, true),
         % we'll send the Parser process ID to the remote nodes so they can
         % retrieve their own copies of the attachment data

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/7e48bda4/src/couch_httpd_db.erl
----------------------------------------------------------------------
diff --git a/src/couch_httpd_db.erl b/src/couch_httpd_db.erl
index 3793a06..e1af1bf 100644
--- a/src/couch_httpd_db.erl
+++ b/src/couch_httpd_db.erl
@@ -256,7 +256,7 @@ db_req(#httpd{method='GET',path_parts=[_DbName]}=Req, Db) ->
 
 db_req(#httpd{method='POST',path_parts=[_DbName]}=Req, Db) ->
     couch_httpd:validate_ctype(Req, "application/json"),
-    Doc = couch_doc:from_json_obj(couch_httpd:json_body(Req)),
+    Doc = couch_doc:from_json_obj_validate(couch_httpd:json_body(Req)),
     validate_attachment_names(Doc),
     Doc2 = case Doc#doc.id of
         <<"">> ->
@@ -319,7 +319,7 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>]}=Req,
Db) ->
         true ->
             Docs = lists:map(
                 fun({ObjProps} = JsonObj) ->
-                    Doc = couch_doc:from_json_obj(JsonObj),
+                    Doc = couch_doc:from_json_obj_validate(JsonObj),
                     validate_attachment_names(Doc),
                     Id = case Doc#doc.id of
                         <<>> -> couch_uuids:new();
@@ -353,7 +353,7 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>]}=Req,
Db) ->
             end;
         false ->
             Docs = lists:map(fun(JsonObj) ->
-                    Doc = couch_doc:from_json_obj(JsonObj),
+                    Doc = couch_doc:from_json_obj_validate(JsonObj),
                     validate_attachment_names(Doc),
                     Doc
                 end, DocsArray),
@@ -809,7 +809,7 @@ couch_doc_from_req(Req, DocId, #doc{revs=Revs}=Doc) ->
     end,
     Doc#doc{id=DocId, revs=Revs2};
 couch_doc_from_req(Req, DocId, Json) ->
-    couch_doc_from_req(Req, DocId, couch_doc:from_json_obj(Json)).
+    couch_doc_from_req(Req, DocId, couch_doc:from_json_obj_validate(Json)).
 
 % Useful for debugging
 % couch_doc_open(Db, DocId) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/7e48bda4/test/couch_doc_json_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_doc_json_tests.erl b/test/couch_doc_json_tests.erl
index 9003d06..ce099d1 100644
--- a/test/couch_doc_json_tests.erl
+++ b/test/couch_doc_json_tests.erl
@@ -38,6 +38,8 @@ mock(couch_log) ->
     ok;
 mock(config) ->
     meck:new(config, [passthrough]),
+    meck:expect(config, get_integer,
+        fun("couchdb", "max_document_size", 4294967296) -> 1024 end),
     meck:expect(config, get, fun(_, _) -> undefined end),
     meck:expect(config, get, fun(_, _, Default) -> Default end),
     ok.
@@ -165,7 +167,7 @@ from_json_success_cases() ->
     ],
     lists:map(
         fun({EJson, Expect, Msg}) ->
-            {Msg, ?_assertMatch(Expect, couch_doc:from_json_obj(EJson))}
+            {Msg, ?_assertMatch(Expect, couch_doc:from_json_obj_validate(EJson))}
         end,
         Cases).
 
@@ -230,16 +232,29 @@ from_json_error_cases() ->
             {[{<<"_something">>, 5}]},
             {doc_validation, <<"Bad special document member: _something">>},
             "Underscore prefix fields are reserved."
+        },
+        {
+            fun() ->
+                {[
+                    {<<"_id">>, <<"large_doc">>},
+                    {<<"x">> , << <<"x">> || _ <- lists:seq(1,1025)
>>}
+                ]}
+            end,
+            {request_entity_too_large, <<"large_doc">>},
+            "Document too large."
         }
     ],
 
     lists:map(fun
+        ({Fun, Expect, Msg}) when is_function(Fun, 0) ->
+            Error = (catch couch_doc:from_json_obj_validate(Fun())),
+            {Msg, ?_assertMatch(Expect, Error)};
         ({EJson, Expect, Msg}) ->
-            Error = (catch couch_doc:from_json_obj(EJson)),
+            Error = (catch couch_doc:from_json_obj_validate(EJson)),
             {Msg, ?_assertMatch(Expect, Error)};
         ({EJson, Msg}) ->
             try
-                couch_doc:from_json_obj(EJson),
+                couch_doc:from_json_obj_validate(EJson),
                 {"Conversion failed to raise an exception", ?_assert(false)}
             catch
                 _:_ -> {Msg, ?_assert(true)}


Mime
View raw message