Repository: couchdb-chttpd Updated Branches: refs/heads/master abe9aee7b -> 56cf6412a
Discard request body after request If a client sends a request body for a request that fails because the database does not exist, they receive a 404 response but the request body is not read. This prevents the next request on the same socket being handled correctly. Ensure the request body is consumed for every request. Project: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/commit/56cf6412 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/tree/56cf6412 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/diff/56cf6412 Branch: refs/heads/master Commit: 56cf6412ad3572b5d07a281c5a25ec511af0530c Parents: abe9aee Author: Robert Newson <[email protected]> Authored: Mon Jun 1 15:12:21 2015 +0100 Committer: Robert Newson <[email protected]> Committed: Fri Jun 19 11:28:01 2015 +0100 ---------------------------------------------------------------------- src/chttpd.erl | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-chttpd/blob/56cf6412/src/chttpd.erl ---------------------------------------------------------------------- diff --git a/src/chttpd.erl b/src/chttpd.erl index 5bec88f..7062813 100644 --- a/src/chttpd.erl +++ b/src/chttpd.erl @@ -245,6 +245,8 @@ handle_request(MochiReq0) -> _Else -> send_error(HttpReq, {Error, nil, Stack}) end + after + maybe_discard_body(HttpReq) end, RequestTime = timer:now_diff(os:timestamp(), Begin)/1000, @@ -536,6 +538,55 @@ json_body_obj(Httpd) -> end. +maybe_discard_body(#httpd{mochi_req=MochiReq}=Req) -> + case erlang:get(mochiweb_request_body) of + undefined -> + Expect = case MochiReq:get_header_value("expect") of + undefined -> + undefined; + Value when is_list(Value) -> + string:to_lower(Value) + end, + case Expect of + "100-continue" -> + ok; + _Else -> + discard_body(Req) + end; + _Body -> + ok % already consumed. + end. + + +discard_body(#httpd{}=Req) -> + case body_length(Req) of + undefined -> + ok; + {unknown_transfer_encoding, Unknown} -> + exit({unknown_transfer_encoding, Unknown}); + chunked -> + discard(Req); + 0 -> + ok; + Length when is_integer(Length) -> + discard(Req); + Length -> + exit({length_not_integer, Length}) + end. + +discard(#httpd{mochi_req=MochiReq}) -> + Discarded = MochiReq:stream_body(8192, + fun ({Len, _}, Acc) -> Len + Acc end, 0), + case Discarded of + undefined -> + ok; + Length when is_integer(Length) -> + couch_log:notice("Discarded ~B bytes of request body.", + [Discarded]) + end, + ok. + + doc_etag(#doc{revs={Start, [DiskRev|_]}}) -> "\"" ++ ?b2l(couch_doc:rev_to_str({Start, DiskRev})) ++ "\"".
