This is an automated email from the ASF dual-hosted git repository.
bessbd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new 94df4bb Fix PUT of multipart/related attachments support for
Transfer-Encoding: chunked (#3360)
94df4bb is described below
commit 94df4bb2379eac40c9888a2ca8fb295242d023d6
Author: Bessenyei Balázs Donát <[email protected]>
AuthorDate: Wed Feb 3 10:54:22 2021 +0100
Fix PUT of multipart/related attachments support for Transfer-Encoding:
chunked (#3360)
Transfer-Encoding: chunked causes the server to wait indefinitely, then
issue a a 500 error when the client finally hangs up, when PUTing a
multipart/related document + attachments.
This commit fixes that issue by adding proper handling for chunked
multipart/related requests.
---
src/chttpd/src/chttpd_db.erl | 9 +++++++++
src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl | 12 +++++++++++-
src/couch/src/couch_httpd.erl | 3 ++-
3 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/src/chttpd/src/chttpd_db.erl b/src/chttpd/src/chttpd_db.erl
index 3ca0824..7b4fdef 100644
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@ -1407,6 +1407,15 @@ bulk_get_multipart_boundary() ->
receive_request_data(Req) ->
receive_request_data(Req, chttpd:body_length(Req)).
+receive_request_data(Req, Len) when Len == chunked ->
+ Ref = make_ref(),
+ ChunkFun = fun({_Length, Binary}, _State) ->
+ self() ! {chunk, Ref, Binary}
+ end,
+ couch_httpd:recv_chunked(Req, 4096, ChunkFun, ok),
+ GetChunk = fun GC() -> receive {chunk, Ref, Binary} -> {Binary, GC} end
end,
+ {receive {chunk, Ref, Binary} -> Binary end, GetChunk};
+
receive_request_data(Req, LenLeft) when LenLeft > 0 ->
Len = erlang:min(4096, LenLeft),
Data = chttpd:recv(Req, Len),
diff --git a/src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl
b/src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl
index 0ab08dd..227b29c 100644
--- a/src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl
@@ -56,7 +56,8 @@ attachment_size_test_() ->
fun put_inline/1,
fun put_simple/1,
fun put_simple_chunked/1,
- fun put_mp_related/1
+ fun put_mp_related/1,
+ fun put_chunked_mp_related/1
]
}
}
@@ -111,6 +112,15 @@ put_mp_related(Url) ->
end).
+put_chunked_mp_related(Url) ->
+ ?_test(begin
+ Headers = [?CONTENT_MULTI_RELATED],
+ Body = mp_body(50),
+ Status = put_req_chunked(Url ++ "/doc4", Headers, Body),
+ ?assert(Status =:= 201 orelse Status =:= 202)
+ end).
+
+
% Helper functions
create_db(Url) ->
diff --git a/src/couch/src/couch_httpd.erl b/src/couch/src/couch_httpd.erl
index fb03bac..d89c749 100644
--- a/src/couch/src/couch_httpd.erl
+++ b/src/couch/src/couch_httpd.erl
@@ -589,7 +589,8 @@ recv_chunked(#httpd{mochi_req=MochiReq}, MaxChunkSize,
ChunkFun, InitState) ->
% Fun is called once with each chunk
% Fun({Length, Binary}, State)
% called with Length == 0 on the last time.
- MochiReq:stream_body(MaxChunkSize, ChunkFun, InitState).
+ MochiReq:stream_body(MaxChunkSize, ChunkFun, InitState,
+ config:get_integer("httpd", "max_http_request_size", 4294967296)).
body_length(#httpd{mochi_req=MochiReq}) ->
MochiReq:get(body_length).