couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject [06/13] couch commit: updated refs/heads/COUCHDB-3288-remove-public-db-record to b424a88
Date Tue, 21 Feb 2017 17:45:55 GMT
Allow limiting length of document ID

Previously it was not possibly to define a maxum document ID size. That meant
large document ID would hit various limitations and corner cases. For example,
large document IDs could be inserted via a _bulk_docs endpoint but then trying
to insert the same document via a single HTTP method like PUT would fail
because of a limitation in Mochiweb's HTTP parser.

Let operators specify a maxium document ID length via the

```
couchdb.max_document_id_length = infinity | Integer
```

configuration.

The default value of `infinity` keeps the current behavior where document
ID length is not checked.

COUCHDB-3293


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

Branch: refs/heads/COUCHDB-3288-remove-public-db-record
Commit: 2a263f84db62e4849a41322b92588c6893169198
Parents: bbbd532
Author: Nick Vatamaniuc <vatamane@apache.org>
Authored: Thu Feb 9 10:13:42 2017 -0500
Committer: Nick Vatamaniuc <vatamane@apache.org>
Committed: Thu Feb 9 10:13:42 2017 -0500

----------------------------------------------------------------------
 src/couch_doc.erl             |  8 ++++++++
 test/couch_doc_json_tests.erl |  7 +++++++
 test/couch_doc_tests.erl      | 20 +++++++++++++++++++-
 3 files changed, 34 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/2a263f84/src/couch_doc.erl
----------------------------------------------------------------------
diff --git a/src/couch_doc.erl b/src/couch_doc.erl
index af14038..a913eee 100644
--- a/src/couch_doc.erl
+++ b/src/couch_doc.erl
@@ -174,6 +174,14 @@ validate_docid(<<"_design/">>) ->
 validate_docid(<<"_local/">>) ->
     throw({illegal_docid, <<"Illegal document id `_local/`">>});
 validate_docid(Id) when is_binary(Id) ->
+    MaxLen = case config:get("couchdb", "max_document_id_length", "infinity") of
+        "infinity" -> infinity;
+        IntegerVal -> list_to_integer(IntegerVal)
+    end,
+    case MaxLen > 0 andalso byte_size(Id) > MaxLen of
+        true -> throw({illegal_docid, <<"Document id is too long">>});
+        false -> ok
+    end,
     case couch_util:validate_utf8(Id) of
         false -> throw({illegal_docid, <<"Document id must be valid UTF-8">>});
         true -> ok

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/2a263f84/test/couch_doc_json_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_doc_json_tests.erl b/test/couch_doc_json_tests.erl
index ae4d73c..9003d06 100644
--- a/test/couch_doc_json_tests.erl
+++ b/test/couch_doc_json_tests.erl
@@ -18,11 +18,13 @@
 
 setup() ->
     mock(couch_log),
+    mock(config),
     mock(couch_db_plugin),
     ok.
 
 teardown(_) ->
     meck:unload(couch_log),
+    meck:unload(config),
     meck:unload(couch_db_plugin),
     ok.
 
@@ -33,6 +35,11 @@ mock(couch_db_plugin) ->
 mock(couch_log) ->
     ok = meck:new(couch_log, [passthrough]),
     ok = meck:expect(couch_log, debug, fun(_, _) -> ok end),
+    ok;
+mock(config) ->
+    meck:new(config, [passthrough]),
+    meck:expect(config, get, fun(_, _) -> undefined end),
+    meck:expect(config, get, fun(_, _, Default) -> Default end),
     ok.
 
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/2a263f84/test/couch_doc_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_doc_tests.erl b/test/couch_doc_tests.erl
index fce4ff7..d24cd67 100644
--- a/test/couch_doc_tests.erl
+++ b/test/couch_doc_tests.erl
@@ -29,8 +29,10 @@ doc_from_multi_part_stream_test() ->
     ContentType = "multipart/related;boundary=multipart_related_boundary~~~~~~~~~~~~~~~~~~~~",
     DataFun = fun() -> request(start) end,
 
+    mock_config_max_document_id_length(),
     {ok, #doc{id = <<"doc0">>, atts = [_]}, _Fun, _Parser} =
         couch_doc:doc_from_multi_part_stream(ContentType, DataFun),
+    meck:unload(config),
     ok.
 
 doc_to_multi_part_stream_test() ->
@@ -75,16 +77,19 @@ len_doc_to_multi_part_stream_test() ->
 validate_docid_test_() ->
     {setup,
         fun() ->
+            mock_config_max_document_id_length(),
             ok = meck:new(couch_db_plugin, [passthrough]),
             meck:expect(couch_db_plugin, validate_docid, fun(_) -> false end)
         end,
         fun(_) ->
+            meck:unload(config),
             meck:unload(couch_db_plugin)
         end,
         [
             ?_assertEqual(ok, couch_doc:validate_docid(<<"idx">>)),
             ?_assertEqual(ok, couch_doc:validate_docid(<<"_design/idx">>)),
             ?_assertEqual(ok, couch_doc:validate_docid(<<"_local/idx">>)),
+            ?_assertEqual(ok, couch_doc:validate_docid(large_id(1024))),
             ?_assertThrow({illegal_docid, _},
                 couch_doc:validate_docid(<<>>)),
             ?_assertThrow({illegal_docid, _},
@@ -96,10 +101,15 @@ validate_docid_test_() ->
             ?_assertThrow({illegal_docid, _},
                 couch_doc:validate_docid(<<"_design/">>)),
             ?_assertThrow({illegal_docid, _},
-                couch_doc:validate_docid(<<"_local/">>))
+                couch_doc:validate_docid(<<"_local/">>)),
+            ?_assertThrow({illegal_docid, _},
+                couch_doc:validate_docid(large_id(1025)))
         ]
     }.
 
+large_id(N) ->
+    << <<"x">> || _ <- lists:seq(1, N) >>.
+
 request(start) ->
     {ok, Doc} = file:read_file(?REQUEST_FIXTURE),
     {Doc, fun() -> request(stop) end};
@@ -116,3 +126,11 @@ send(Data, Acc) ->
 collected() ->
     B = binary:replace(iolist_to_binary(get(data)), <<"\r\n">>, <<0>>,
[global]),
     binary:split(B, [<<0>>], [global]).
+
+mock_config_max_document_id_length() ->
+    ok = meck:new(config, [passthrough]),
+    meck:expect(config, get,
+        fun("couchdb", "max_document_id_length", "infinity") -> "1024";
+            (Key, Val, Default) -> meck:passthrough([Key, Val, Default])
+        end
+    ).


Mime
View raw message