Allow recbuf to be undefined If recbuf option is undefined, the operating system decides on the buffer size If no buffer size is speciefied, streaming will happen in the chunks of MaxChunkSize
Project: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/commit/42d37e68 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/tree/42d37e68 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/diff/42d37e68 Branch: refs/heads/upstream Commit: 42d37e68c93f9021e03d6e1ee4268e69f3924b94 Parents: c3fb6ae Author: Georg Göri <[email protected]> Authored: Thu Mar 5 23:01:35 2015 +0100 Committer: Georg Göri <[email protected]> Committed: Fri Mar 6 22:04:45 2015 +0100 ---------------------------------------------------------------------- src/mochiweb_http.erl | 2 +- src/mochiweb_request.erl | 20 ++++++++++---------- src/mochiweb_socket_server.erl | 15 ++++++++++++--- 3 files changed, 23 insertions(+), 14 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/42d37e68/src/mochiweb_http.erl ---------------------------------------------------------------------- diff --git a/src/mochiweb_http.erl b/src/mochiweb_http.erl index cfbe0b9..d83fdda 100644 --- a/src/mochiweb_http.erl +++ b/src/mochiweb_http.erl @@ -58,7 +58,7 @@ stop(Name) -> %% Option = {name, atom()} | {ip, string() | tuple()} | {backlog, integer()} %% | {nodelay, boolean()} | {acceptor_pool_size, integer()} %% | {ssl, boolean()} | {profile_fun, undefined | (Props) -> ok} -%% | {link, false} | {recbuf, non_negative_integer()} +%% | {link, false} | {recbuf, undefined | non_negative_integer()} %% @doc Start a mochiweb server. %% profile_fun is used to profile accept timing. %% After each accept, if defined, profile_fun is called with a proplist of a subset of the mochiweb_socket_server state and timing information. http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/42d37e68/src/mochiweb_request.erl ---------------------------------------------------------------------- diff --git a/src/mochiweb_request.erl b/src/mochiweb_request.erl index 3559395..d15d090 100644 --- a/src/mochiweb_request.erl +++ b/src/mochiweb_request.erl @@ -280,7 +280,7 @@ stream_body(MaxChunkSize, ChunkFun, FunState, MaxBodyLength, MaxBodyLength when is_integer(MaxBodyLength), MaxBodyLength < Length -> exit({body_too_large, content_length}); _ -> - stream_unchunked_body(Length, ChunkFun, FunState, THIS) + stream_unchunked_body(MaxChunkSize,Length, ChunkFun, FunState, THIS) end end. @@ -544,20 +544,20 @@ stream_chunked_body(MaxChunkSize, Fun, FunState, stream_chunked_body(MaxChunkSize, Fun, NewState, THIS) end. -stream_unchunked_body(0, Fun, FunState, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) -> +stream_unchunked_body(_MaxChunkSize, 0, Fun, FunState, {?MODULE, [_Socket, _Opts, _Method, _RawPath, _Version, _Headers]}) -> Fun({0, <<>>}, FunState); -stream_unchunked_body(Length, Fun, FunState, +stream_unchunked_body(MaxChunkSize, Length, Fun, FunState, {?MODULE, [_Socket, Opts, _Method, _RawPath, _Version, _Headers]}=THIS) when Length > 0 -> - RecBuf = mochilists:get_value(recbuf, Opts, ?RECBUF_SIZE), - PktSize = case Length > RecBuf of - true -> - RecBuf; - false -> - Length + RecBuf = case mochilists:get_value(recbuf, Opts, ?RECBUF_SIZE) of + undefined -> %os controlled buffer size + MaxChunkSize; + Val -> + Val end, + PktSize=min(Length,RecBuf), Bin = recv(PktSize, THIS), NewState = Fun({PktSize, Bin}, FunState), - stream_unchunked_body(Length - PktSize, Fun, NewState, THIS). + stream_unchunked_body(MaxChunkSize, Length - PktSize, Fun, NewState, THIS). %% @spec read_chunk_length(request()) -> integer() %% @doc Read the length of the next HTTP chunk. http://git-wip-us.apache.org/repos/asf/couchdb-mochiweb/blob/42d37e68/src/mochiweb_socket_server.erl ---------------------------------------------------------------------- diff --git a/src/mochiweb_socket_server.erl b/src/mochiweb_socket_server.erl index fd7ab03..fd5e382 100644 --- a/src/mochiweb_socket_server.erl +++ b/src/mochiweb_socket_server.erl @@ -117,7 +117,8 @@ parse_options([{backlog, Backlog} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{backlog=Backlog}); parse_options([{nodelay, NoDelay} | Rest], State) -> parse_options(Rest, State#mochiweb_socket_server{nodelay=NoDelay}); -parse_options([{recbuf, RecBuf} | Rest], State) when is_integer(RecBuf) -> +parse_options([{recbuf, RecBuf} | Rest], State) when is_integer(RecBuf) orelse + RecBuf == undefined -> %% XXX: `recbuf' value which is passed to `gen_tcp' %% and value reported by `inet:getopts(P, [recbuf])' may %% differ. They depends on underlying OS. From linux mans: @@ -127,6 +128,9 @@ parse_options([{recbuf, RecBuf} | Rest], State) when is_integer(RecBuf) -> %% and this doubled value is returned by getsockopt(2). %% %% See: man 7 socket | grep SO_RCVBUF + %% + %% In case undefined is passed instead of the default buffer + %% size ?RECBUF_SIZE, no size is set and the OS can control it dynamically parse_options(Rest, State#mochiweb_socket_server{recbuf=RecBuf}); parse_options([{acceptor_pool_size, Max} | Rest], State) -> MaxInt = ensure_int(Max), @@ -182,7 +186,6 @@ init(State=#mochiweb_socket_server{ip=Ip, port=Port, backlog=Backlog, {reuseaddr, true}, {packet, 0}, {backlog, Backlog}, - {recbuf, RecBuf}, {exit_on_close, false}, {active, false}, {nodelay, NoDelay}], @@ -197,7 +200,13 @@ init(State=#mochiweb_socket_server{ip=Ip, port=Port, backlog=Backlog, {_, _, _, _, _, _, _, _} -> % IPv6 [inet6, {ip, Ip} | BaseOpts] end, - listen(Port, Opts, State). + OptsBuf=case RecBuf of + undefined -> + Opts; + _ -> + [{recbuf, RecBuf}|Opts] + end, + listen(Port, OptsBuf, State). new_acceptor_pool(State=#mochiweb_socket_server{acceptor_pool_size=Size}) -> lists:foldl(fun (_, S) -> new_acceptor(S) end, State, lists:seq(1, Size)).
