You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2015/06/19 12:28:10 UTC

chttpd commit: updated refs/heads/master to 56cf641

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 <rn...@apache.org>
Authored: Mon Jun 1 15:12:21 2015 +0100
Committer: Robert Newson <rn...@apache.org>
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})) ++ "\"".