summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/couchdb/couch_httpd.erl13
-rw-r--r--src/couchdb/couch_httpd_db.erl12
2 files changed, 22 insertions, 3 deletions
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index 66fc1062..2dc53b80 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -15,7 +15,7 @@
-export([start_link/0, stop/0, handle_request/5]).
--export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1,absolute_uri/2]).
+-export([header_value/2,header_value/3,qs_value/2,qs_value/3,qs/1,path/1,absolute_uri/2,body_length/1]).
-export([verify_is_server_admin/1,unquote/1,quote/1,recv/2,recv_chunked/4,error_info/1]).
-export([parse_form/1,json_body/1,json_body_obj/1,body/1,doc_etag/1, make_etag/1, etag_respond/3]).
-export([primary_header_value/2,partition/1,serve_file/3, server_header/0]).
@@ -281,6 +281,17 @@ recv_chunked(#httpd{mochi_req=MochiReq}, MaxChunkSize, ChunkFun, InitState) ->
% Fun({Length, Binary}, State)
% called with Length == 0 on the last time.
MochiReq:stream_body(MaxChunkSize, ChunkFun, InitState).
+
+body_length(Req) ->
+ case header_value(Req, "Transfer-Encoding") of
+ undefined ->
+ case header_value(Req, "Content-Length") of
+ undefined -> undefined;
+ Length -> list_to_integer(Length)
+ end;
+ "chunked" -> chunked;
+ Unknown -> {unknown_transfer_encoding, Unknown}
+ end.
body(#httpd{mochi_req=MochiReq, req_body=ReqBody}) ->
case ReqBody of
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index 0d1e4569..084dd946 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -858,14 +858,22 @@ db_attachment_req(#httpd{method=Method}=Req, Db, DocId, FileNameParts)
CType ->
list_to_binary(CType)
end,
- data = case couch_httpd:header_value(Req,"Content-Length") of
+ data = case couch_httpd:body_length(Req) of
undefined ->
+ undefined;
+ {unknown_transfer_encoding, Unknown} ->
+ exit({unknown_transfer_encoding, Unknown});
+ chunked ->
fun(MaxChunkSize, ChunkFun, InitState) ->
couch_httpd:recv_chunked(Req, MaxChunkSize,
ChunkFun, InitState)
end;
+ 0 ->
+ <<>>;
+ Length when is_integer(Length) ->
+ fun() -> couch_httpd:recv(Req, 0) end;
Length ->
- fun() -> couch_httpd:recv(Req, 0) end
+ exit({length_not_integer, Length})
end,
len = case couch_httpd:header_value(Req,"Content-Length") of
undefined ->