Skip to content

Commit

Permalink
Allow recbuf to be undefined
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jgrnt committed Mar 6, 2015
1 parent c3fb6ae commit 42d37e6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/mochiweb_http.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
20 changes: 10 additions & 10 deletions src/mochiweb_request.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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.
Expand Down
15 changes: 12 additions & 3 deletions src/mochiweb_socket_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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),
Expand Down Expand Up @@ -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}],
Expand All @@ -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)).
Expand Down

0 comments on commit 42d37e6

Please sign in to comment.