diff options
-rw-r--r-- | src/couchdb/couch_httpd.erl | 13 | ||||
-rw-r--r-- | src/couchdb/couch_httpd_db.erl | 12 |
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 -> |