You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by to...@apache.org on 2016/04/22 08:02:17 UTC
[1/5] chttpd commit: updated refs/heads/2992-limit-doc-size to 1ac365d
Repository: couchdb-chttpd
Updated Branches:
refs/heads/2992-limit-doc-size f7affd0d2 -> 1ac365dd8
Move max_document_size logic to update only
COUCHDB-2992
Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/03fdcde5
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/03fdcde5
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/03fdcde5
Branch: refs/heads/2992-limit-doc-size
Commit: 03fdcde571585f17c2077a3a0313bc8703e32197
Parents: f7affd0
Author: Tony Sun <to...@cloudant.com>
Authored: Tue Apr 19 18:41:32 2016 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Tue Apr 19 18:41:32 2016 -0700
----------------------------------------------------------------------
include/chttpd.hrl | 3 ++
src/chttpd.erl | 9 ++---
src/chttpd_db.erl | 65 ++++++++++++++++++++---------------
src/chttpd_external.erl | 4 +--
test/chttpd_db_doc_size_test.erl | 6 ++--
5 files changed, 50 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/03fdcde5/include/chttpd.hrl
----------------------------------------------------------------------
diff --git a/include/chttpd.hrl b/include/chttpd.hrl
index a7f9aaa..d26a2ee 100644
--- a/include/chttpd.hrl
+++ b/include/chttpd.hrl
@@ -26,3 +26,6 @@
(C >= $a andalso C =< $f) orelse
(C >= $A andalso C =< $F)
)).
+
+% For any PUT/POST request, max size will be 4 GB (semi-unlimited)
+-define(DEFAULT_RECV_BODY, 4294967296).
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/03fdcde5/src/chttpd.erl
----------------------------------------------------------------------
diff --git a/src/chttpd.erl b/src/chttpd.erl
index 1f8c160..ef1c140 100644
--- a/src/chttpd.erl
+++ b/src/chttpd.erl
@@ -599,12 +599,9 @@ body_length(#httpd{mochi_req=MochiReq}) ->
body(#httpd{mochi_req=MochiReq, req_body=ReqBody}) ->
case ReqBody of
undefined ->
- % Maximum size of document PUT request body (4GB)
- MaxSize = list_to_integer(
- config:get("couchdb", "max_document_size", "4294967296")),
Begin = os:timestamp(),
try
- MochiReq:recv_body(MaxSize)
+ MochiReq:recv_body(?DEFAULT_RECV_BODY)
after
T = timer:now_diff(os:timestamp(), Begin) div 1000,
put(body_time, T)
@@ -858,9 +855,9 @@ error_info({error, {database_name_too_long, DbName}}) ->
<<"At least one path segment of `", DbName/binary, "` is too long.">>};
error_info({missing_stub, Reason}) ->
{412, <<"missing_stub">>, Reason};
-error_info({single_doc_too_large, MaxSize}) ->
+error_info({request_entity_too_large, MaxSize}) ->
SizeBin = list_to_binary(integer_to_list(MaxSize)),
- {413, <<"too_large">>, <<"Document exceeded single_max_doc_size:",
+ {413, <<"too_large">>, <<"Document exceeded max_document_size:",
SizeBin/binary>>};
error_info(request_entity_too_large) ->
{413, <<"too_large">>, <<"the request entity is too large">>};
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/03fdcde5/src/chttpd_db.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_db.erl b/src/chttpd_db.erl
index 2a3fe1b..fdfd03d 100644
--- a/src/chttpd_db.erl
+++ b/src/chttpd_db.erl
@@ -13,6 +13,7 @@
-module(chttpd_db).
-include_lib("couch/include/couch_db.hrl").
-include_lib("couch_mrview/include/couch_mrview.hrl").
+-include_lib("chttpd/include/chttpd.hrl").
-export([handle_request/1, handle_compact_req/2, handle_design_req/2,
db_req/2, couch_doc_open/4,handle_changes_req/2,
@@ -309,7 +310,7 @@ db_req(#httpd{method='POST', path_parts=[DbName], user_ctx=Ctx}=Req, Db) ->
Options = [{user_ctx,Ctx}, {w,W}],
Body = chttpd:json_body(Req),
- ok = verify_doc_size(Body),
+ ok = maybe_verify_body_size(Body),
Doc = couch_doc:from_json_obj(Body),
Doc2 = case Doc#doc.id of
@@ -377,7 +378,7 @@ db_req(#httpd{method='POST',path_parts=[_,<<"_bulk_docs">>], user_ctx=Ctx}=Req,
DocsArray0 ->
DocsArray0
end,
- {ExceedErrs, DocsArray1} = remove_exceed_docs(DocsArray),
+ {ExceedErrs, DocsArray1} = maybe_remove_exceed_docs(DocsArray),
couch_stats:update_histogram([couchdb, httpd, bulk_docs], length(DocsArray)),
W = case couch_util:get_value(<<"w">>, JsonProps) of
Value when is_integer(Value) ->
@@ -769,7 +770,7 @@ db_doc_req(#httpd{method='PUT', user_ctx=Ctx}=Req, Db, DocId) ->
"ok" ->
% batch
Body = chttpd:json_body(Req),
- ok = verify_doc_size(Body),
+ ok = maybe_verify_body_size(Body),
Doc = couch_doc_from_req(Req, DocId, Body),
spawn(fun() ->
@@ -787,7 +788,7 @@ db_doc_req(#httpd{method='PUT', user_ctx=Ctx}=Req, Db, DocId) ->
_Normal ->
% normal
Body = chttpd:json_body(Req),
- ok = verify_doc_size(Body),
+ ok = maybe_verify_body_size(Body),
Doc = couch_doc_from_req(Req, DocId, Body),
send_updated_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType)
end
@@ -1634,33 +1635,43 @@ bulk_get_open_doc_revs1(Db, Props, _, {DocId, Revs, Options}) ->
{DocId, Results, Options}
end.
-remove_exceed_docs(DocArray0) ->
- MaxSize = list_to_integer(config:get("couchdb",
- "single_max_doc_size", "1048576")),
- {ExceedDocs, DocsArray} = lists:splitwith(fun (Doc) ->
- exceed_doc_size(Doc, MaxSize)
- end, DocArray0),
- ExceedErrs = lists:map (fun ({Doc}) ->
- DocId = case couch_util:get_value(<<"_id">>, Doc) of
- undefined -> couch_uuids:new();
- Id0 -> Id0
- end,
- Reason = lists:concat(["Document exceeded single_max_doc_size:",
- " of ", MaxSize, " bytes"]),
- {[{id, DocId}, {error, <<"too_large">>},
- {reason, ?l2b(Reason)}]}
- end, ExceedDocs),
- {ExceedErrs, DocsArray}.
+maybe_remove_exceed_docs(DocArray0) ->
+ case config:get_boolean("couchdb", "use_max_document_size", false) of
+ true ->
+ Max = config:get_integer("couchdb", "max_document_size",
+ 16777216),
+ {ExceedDocs, DocsArray} = lists:splitwith(fun (Doc) ->
+ exceed_doc_size(Doc, Max)
+ end, DocArray0),
+ ExceedErrs = lists:map (fun ({Doc}) ->
+ DocId = case couch_util:get_value(<<"_id">>, Doc) of
+ undefined -> <<"no id generated since update failed">>;
+ Id0 -> Id0
+ end,
+ Reason = lists:concat(["Document exceeded max_document_size:",
+ " of ", Max, " bytes"]),
+ {[{id, DocId}, {error, <<"request_entity_too_large">>},
+ {reason, ?l2b(Reason)}]}
+ end, ExceedDocs),
+ {ExceedErrs, DocsArray};
+ false ->
+ {[], DocArray0}
+ end.
exceed_doc_size(JsonBody, MaxSize) ->
size(term_to_binary(JsonBody)) > MaxSize.
-verify_doc_size(JsonBody) ->
- SMaxSize = list_to_integer(config:get("couchdb",
- "single_max_doc_size", "1048576")),
- case exceed_doc_size(JsonBody, SMaxSize) of
- true -> throw({single_doc_too_large, SMaxSize});
- false -> ok
+maybe_verify_body_size(JsonBody) ->
+ case config:get_boolean("couchdb", "use_max_document_size", false) of
+ true ->
+ Max = config:get_integer("couchdb", "max_document_size",
+ 16777216),
+ case exceed_doc_size(JsonBody, Max) of
+ true -> throw({request_entity_too_large, Max});
+ false -> ok
+ end;
+ false ->
+ ok
end.
parse_field(<<"id">>, undefined) ->
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/03fdcde5/src/chttpd_external.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_external.erl b/src/chttpd_external.erl
index f9bebed..e8efff2 100644
--- a/src/chttpd_external.erl
+++ b/src/chttpd_external.erl
@@ -20,6 +20,7 @@
-import(chttpd,[send_error/4]).
-include_lib("couch/include/couch_db.hrl").
+-include_lib("chttpd/include/chttpd.hrl").
% handle_external_req/2
% for the old type of config usage:
@@ -93,8 +94,7 @@ json_req_obj_field(<<"headers">>, #httpd{mochi_req=Req}, _Db, _DocId) ->
Hlist = mochiweb_headers:to_list(Headers),
to_json_terms(Hlist);
json_req_obj_field(<<"body">>, #httpd{req_body=undefined, mochi_req=Req}, _Db, _DocId) ->
- MaxSize = config:get_integer("couchdb", "max_document_size", 4294967296),
- Req:recv_body(MaxSize);
+ Req:recv_body(?DEFAULT_RECV_BODY);
json_req_obj_field(<<"body">>, #httpd{req_body=Body}, _Db, _DocId) ->
Body;
json_req_obj_field(<<"peer">>, #httpd{mochi_req=Req}, _Db, _DocId) ->
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/03fdcde5/test/chttpd_db_doc_size_test.erl
----------------------------------------------------------------------
diff --git a/test/chttpd_db_doc_size_test.erl b/test/chttpd_db_doc_size_test.erl
index 02ae3cd..ce29c17 100644
--- a/test/chttpd_db_doc_size_test.erl
+++ b/test/chttpd_db_doc_size_test.erl
@@ -22,7 +22,8 @@
setup() ->
ok = config:set("admins", ?USER, ?PASS, _Persist=false),
- ok = config:set("couchdb", "single_max_doc_size", "50"),
+ ok = config:set("couchdb", "max_document_size", "50"),
+ ok = config:set("couchdb", "use_max_document_size", "true"),
TmpDb = ?tempdb(),
Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(chttpd, port),
@@ -33,7 +34,8 @@ setup() ->
teardown(Url) ->
delete_db(Url),
ok = config:delete("admins", ?USER, _Persist=false),
- ok = config:delete("couchdb", "single_max_doc_size").
+ ok = config:delete("couchdb", "max_document_size"),
+ ok = config:delete("couchdb", "use_max_document_size").
create_db(Url) ->
{ok, Status, _, _} = test_request:put(Url, [?CONTENT_JSON, ?AUTH], "{}"),
[3/5] chttpd commit: updated refs/heads/2992-limit-doc-size to 1ac365d
Posted by to...@apache.org.
Add in check for body size in multi_part requests
COUCHDB-2992
Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/8ddb1ce7
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/8ddb1ce7
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/8ddb1ce7
Branch: refs/heads/2992-limit-doc-size
Commit: 8ddb1ce7c6bd01511daea3e0d05c5d2edf9610ba
Parents: b0e5493
Author: Tony Sun <to...@cloudant.com>
Authored: Thu Apr 21 18:42:51 2016 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Thu Apr 21 18:42:51 2016 -0700
----------------------------------------------------------------------
src/chttpd_db.erl | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/8ddb1ce7/src/chttpd_db.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_db.erl b/src/chttpd_db.erl
index d30a89b..2f6e0c0 100644
--- a/src/chttpd_db.erl
+++ b/src/chttpd_db.erl
@@ -698,7 +698,8 @@ db_doc_req(#httpd{method='POST', user_ctx=Ctx}=Req, Db, DocId) ->
case proplists:is_defined("_doc", Form) of
true ->
Json = ?JSON_DECODE(couch_util:get_value("_doc", Form)),
- Doc = couch_doc_from_req(Req, DocId, Json);
+ Doc = couch_doc_from_req(Req, DocId, Json),
+ ok = maybe_verify_body_size(Doc#doc.body);
false ->
Rev = couch_doc:parse_rev(list_to_binary(couch_util:get_value("_rev", Form))),
{ok, [{ok, Doc}]} = fabric:open_revs(Db, DocId, [Rev], [])
@@ -754,6 +755,7 @@ db_doc_req(#httpd{method='PUT', user_ctx=Ctx}=Req, Db, DocId) ->
{ok, Doc0, WaitFun, Parser} = couch_doc:doc_from_multi_part_stream(ContentType,
fun() -> receive_request_data(Req) end),
Doc = couch_doc_from_req(Req, DocId, Doc0),
+ ok = maybe_verify_body_size(Doc#doc.body),
try
Result = send_updated_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType),
WaitFun(),
[4/5] chttpd commit: updated refs/heads/2992-limit-doc-size to 1ac365d
Posted by to...@apache.org.
Add check for _update handlers
COUCHDB-2992
Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/0b0a3aca
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/0b0a3aca
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/0b0a3aca
Branch: refs/heads/2992-limit-doc-size
Commit: 0b0a3acaad204d00ea024f15c21dbdf2f01bae38
Parents: 8ddb1ce
Author: Tony Sun <to...@cloudant.com>
Authored: Thu Apr 21 18:46:07 2016 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Thu Apr 21 18:46:07 2016 -0700
----------------------------------------------------------------------
src/chttpd_db.erl | 2 +-
src/chttpd_show.erl | 1 +
2 files changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/0b0a3aca/src/chttpd_db.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_db.erl b/src/chttpd_db.erl
index 2f6e0c0..03a0b65 100644
--- a/src/chttpd_db.erl
+++ b/src/chttpd_db.erl
@@ -19,7 +19,7 @@
db_req/2, couch_doc_open/4,handle_changes_req/2,
update_doc_result_to_json/1, update_doc_result_to_json/2,
handle_design_info_req/3, handle_view_cleanup_req/2,
- update_doc/4, http_code_from_status/1]).
+ update_doc/4, http_code_from_status/1, maybe_verify_body_size/1]).
-import(chttpd,
[send_json/2,send_json/3,send_json/4,send_method_not_allowed/2,
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/0b0a3aca/src/chttpd_show.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_show.erl b/src/chttpd_show.erl
index 787df16..4bb9335 100644
--- a/src/chttpd_show.erl
+++ b/src/chttpd_show.erl
@@ -130,6 +130,7 @@ send_doc_update_response(Req, Db, DDoc, UpdateName, Doc, DocId) ->
Options = [{user_ctx, Req#httpd.user_ctx}, {w, W}]
end,
NewDoc = couch_doc:from_json_obj({NewJsonDoc}),
+ ok = chttpd_db:maybe_verify_body_size(NewDoc#doc.body),
couch_doc:validate_docid(NewDoc#doc.id),
{UpdateResult, NewRev} = fabric:update_doc(Db, NewDoc, Options),
NewRevStr = couch_doc:rev_to_str(NewRev),
[2/5] chttpd commit: updated refs/heads/2992-limit-doc-size to 1ac365d
Posted by to...@apache.org.
Use doc body after parsing
We use the #doc.body because we only care about the json body. Inline
attachments are already stripped away
COUCHDB-2992
Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/b0e54930
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/b0e54930
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/b0e54930
Branch: refs/heads/2992-limit-doc-size
Commit: b0e54930ad341b7385f48d8f06a9455372115e98
Parents: 03fdcde
Author: Tony Sun <to...@cloudant.com>
Authored: Wed Apr 20 15:38:49 2016 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Wed Apr 20 15:38:49 2016 -0700
----------------------------------------------------------------------
src/chttpd_db.erl | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/b0e54930/src/chttpd_db.erl
----------------------------------------------------------------------
diff --git a/src/chttpd_db.erl b/src/chttpd_db.erl
index fdfd03d..d30a89b 100644
--- a/src/chttpd_db.erl
+++ b/src/chttpd_db.erl
@@ -309,10 +309,8 @@ db_req(#httpd{method='POST', path_parts=[DbName], user_ctx=Ctx}=Req, Db) ->
W = chttpd:qs_value(Req, "w", integer_to_list(mem3:quorum(Db))),
Options = [{user_ctx,Ctx}, {w,W}],
- Body = chttpd:json_body(Req),
- ok = maybe_verify_body_size(Body),
-
- Doc = couch_doc:from_json_obj(Body),
+ Doc = couch_doc:from_json_obj(chttpd:json_body(Req)),
+ ok = maybe_verify_body_size(Doc#doc.body),
Doc2 = case Doc#doc.id of
<<"">> ->
Doc#doc{id=couch_uuids:new(), revs={0, []}};
@@ -769,10 +767,8 @@ db_doc_req(#httpd{method='PUT', user_ctx=Ctx}=Req, Db, DocId) ->
case chttpd:qs_value(Req, "batch") of
"ok" ->
% batch
- Body = chttpd:json_body(Req),
- ok = maybe_verify_body_size(Body),
- Doc = couch_doc_from_req(Req, DocId, Body),
-
+ Doc = couch_doc_from_req(Req, DocId, chttpd:json_body(Req)),
+ ok = maybe_verify_body_size(Doc#doc.body),
spawn(fun() ->
case catch(fabric:update_doc(Db, Doc, Options)) of
{ok, _} -> ok;
@@ -788,8 +784,8 @@ db_doc_req(#httpd{method='PUT', user_ctx=Ctx}=Req, Db, DocId) ->
_Normal ->
% normal
Body = chttpd:json_body(Req),
- ok = maybe_verify_body_size(Body),
Doc = couch_doc_from_req(Req, DocId, Body),
+ ok = maybe_verify_body_size(Doc#doc.body),
send_updated_doc(Req, Db, DocId, Doc, RespHeaders, UpdateType)
end
end;
[5/5] chttpd commit: updated refs/heads/2992-limit-doc-size to 1ac365d
Posted by to...@apache.org.
Add more tests
COUCHDB-2992
Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/1ac365dd
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/1ac365dd
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/1ac365dd
Branch: refs/heads/2992-limit-doc-size
Commit: 1ac365dd88d5c953ea739b5b11ebb857038fc7d5
Parents: 0b0a3ac
Author: Tony Sun <to...@cloudant.com>
Authored: Thu Apr 21 23:03:01 2016 -0700
Committer: Tony Sun <to...@cloudant.com>
Committed: Thu Apr 21 23:03:01 2016 -0700
----------------------------------------------------------------------
test/chttpd_db_doc_size_test.erl | 84 ++++++++++++++++++++++++++++++++++-
1 file changed, 82 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/1ac365dd/test/chttpd_db_doc_size_test.erl
----------------------------------------------------------------------
diff --git a/test/chttpd_db_doc_size_test.erl b/test/chttpd_db_doc_size_test.erl
index ce29c17..a0fa76e 100644
--- a/test/chttpd_db_doc_size_test.erl
+++ b/test/chttpd_db_doc_size_test.erl
@@ -19,6 +19,11 @@
-define(PASS, "pass").
-define(AUTH, {basic_auth, {?USER, ?PASS}}).
-define(CONTENT_JSON, {"Content-Type", "application/json"}).
+-define(CONTENT_MULTI_RELATED, {"Content-Type",
+ "multipart/related;boundary=\"bound\""}).
+-define(CONTENT_MULTI_FORM, {"Content-Type",
+ "multipart/form-data;boundary=\"bound\""}).
+
setup() ->
ok = config:set("admins", ?USER, ?PASS, _Persist=false),
@@ -46,7 +51,7 @@ delete_db(Url) ->
all_test_() ->
{
- "chttpd db single doc max size test",
+ "chttpd db max_document_size tests",
{
setup,
fun chttpd_test_util:start_couch/0, fun chttpd_test_util:stop_couch/1,
@@ -56,7 +61,10 @@ all_test_() ->
[
fun post_single_doc/1,
fun put_single_doc/1,
- fun bulk_doc/1
+ fun bulk_doc/1,
+ fun put_post_doc_attach_inline/1,
+ fun put_multi_part_related/1,
+ fun post_multi_part_form/1
]
}
}
@@ -96,3 +104,75 @@ bulk_doc(Url) ->
Msg = couch_util:get_value(<<"error">>, InnerJson2),
?_assertEqual(<<"too_large">>, Error),
?_assertEqual(undefined, Msg).
+
+put_post_doc_attach_inline(Url) ->
+ Body1 = "{\"body\":\"This is a body.\",",
+ Body2 = lists:concat(["{\"body\":\"This is a body it should fail",
+ "because there are too many characters.\","]),
+ DocRest = lists:concat(["\"_attachments\":{\"foo.txt\":{",
+ "\"content_type\":\"text/plain\",",
+ "\"data\": \"VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=\"}}}"]),
+ Doc1 = lists:concat([Body1, DocRest]),
+ Doc2 = lists:concat([Body2, DocRest]),
+
+ {ok, _, _, ResultBody} = test_request:post(Url,
+ [?CONTENT_JSON, ?AUTH], Doc1),
+ {Msg} = ?JSON_DECODE(ResultBody),
+ ?_assertEqual({<<"ok">>, true}, lists:nth(1, Msg)),
+ {ok, _, _, ResultBody1} = test_request:post(Url,
+ [?CONTENT_JSON, ?AUTH], Doc2),
+ {Msg1} = ?JSON_DECODE(ResultBody1),
+ ?_assertEqual({<<"error">>, <<"too_large">>}, lists:nth(1, Msg1)),
+
+ {ok, _, _, ResultBody2} = test_request:put(Url ++ "/" ++ "accept",
+ [?CONTENT_JSON, ?AUTH], Doc1),
+ {Msg2} = ?JSON_DECODE(ResultBody2),
+ ?_assertEqual({<<"ok">>, true}, lists:nth(1, Msg2)),
+ {ok, _, _, ResultBody3} = test_request:put(Url ++ "/" ++ "fail",
+ [?CONTENT_JSON, ?AUTH], Doc2),
+ {Msg3} = ?JSON_DECODE(ResultBody3),
+ ?_assertEqual({<<"error">>, <<"too_large">>}, lists:nth(1, Msg3)).
+
+put_multi_part_related(Url) ->
+ Body1 = "{\"body\":\"This is a body.\",",
+ Body2 = lists:concat(["{\"body\":\"This is a body it should fail",
+ "because there are too many characters.\","]),
+ DocBeg = "--bound\r\nContent-Type: application/json\r\n\r\n",
+ DocRest = lists:concat(["\"_attachments\":{\"foo.txt\":{\"follows\":true,",
+ "\"content_type\":\"text/plain\",\"length\":21},\"bar.txt\":",
+ "{\"follows\":true,\"content_type\":\"text/plain\",",
+ "\"length\":20}}}\r\n--bound\r\n\r\nthis is 21 chars long",
+ "\r\n--bound\r\n\r\nthis is 20 chars lon\r\n--bound--epilogue"]),
+ Doc1 = lists:concat([DocBeg, Body1, DocRest]),
+ Doc2 = lists:concat([DocBeg, Body2, DocRest]),
+ {ok, _, _, ResultBody} = test_request:put(Url ++ "/" ++ "accept",
+ [?CONTENT_MULTI_RELATED, ?AUTH], Doc1),
+ {Msg} = ?JSON_DECODE(ResultBody),
+ ?_assertEqual({<<"ok">>, true}, lists:nth(1, Msg)),
+ {ok, _, _, ResultBody1} = test_request:put(Url ++ "/" ++ "faildoc",
+ [?CONTENT_MULTI_RELATED, ?AUTH], Doc2),
+ {Msg1} = ?JSON_DECODE(ResultBody1),
+ ?_assertEqual({<<"error">>, <<"too_large">>}, lists:nth(1, Msg1)).
+
+post_multi_part_form(Url) ->
+ Port = mochiweb_socket_server:get(chttpd, port),
+ Host = lists:concat([ "http://127.0.0.1:", Port]),
+ Referer = {"Referer", Host},
+ Body1 = "{\"body\":\"This is a body.\"}",
+ Body2 = lists:concat(["{\"body\":\"This is a body it should fail",
+ "because there are too many characters.\"}"]),
+ DocBeg = "--bound\r\nContent-Disposition: form-data; name=\"_doc\"\r\n\r\n",
+ DocRest = lists:concat(["\r\n--bound\r\nContent-Disposition:",
+ "form-data; name=\"_attachments\"; filename=\"file.txt\"\r\n",
+ "Content-Type: text/plain\r\n\r\ncontents of file.txt\r\n\r\n",
+ "--bound--"]),
+ Doc1 = lists:concat([DocBeg, Body1, DocRest]),
+ Doc2 = lists:concat([DocBeg, Body2, DocRest]),
+ {ok, _, _, ResultBody} = test_request:post(Url ++ "/" ++ "accept",
+ [?CONTENT_MULTI_FORM, ?AUTH, Referer], Doc1),
+ {Msg} = ?JSON_DECODE(ResultBody),
+ ?_assertEqual({<<"ok">>, true}, lists:nth(1, Msg)),
+ {ok, _, _, ResultBody1} = test_request:post(Url ++ "/" ++ "fail",
+ [?CONTENT_MULTI_FORM, ?AUTH, Referer], Doc2),
+ {Msg1} = ?JSON_DECODE(ResultBody1),
+ ?_assertEqual({<<"error">>, <<"too_large">>}, lists:nth(1, Msg1)).