mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-16 05:00:24 +00:00
Use binary:match/2 instead of binary:split/2
The former is a BIF while the latter is not.
This commit is contained in:
parent
981ea359ba
commit
8a6baac9ad
1 changed files with 32 additions and 21 deletions
|
@ -127,23 +127,26 @@ wait_request(State=#state{socket=Socket, transport=Transport,
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
-spec parse_request(#state{}) -> ok.
|
-spec parse_request(#state{}) -> ok.
|
||||||
|
%% Empty lines must be using \r\n.
|
||||||
|
parse_request(State=#state{buffer= << "\n", _/binary >>}) ->
|
||||||
|
error_terminate(400, State);
|
||||||
%% We limit the length of the Request-line to MaxLength to avoid endlessly
|
%% We limit the length of the Request-line to MaxLength to avoid endlessly
|
||||||
%% reading from the socket and eventually crashing.
|
%% reading from the socket and eventually crashing.
|
||||||
parse_request(State=#state{buffer=Buffer, max_request_line_length=MaxLength,
|
parse_request(State=#state{buffer=Buffer, max_request_line_length=MaxLength,
|
||||||
req_empty_lines=ReqEmpty, max_empty_lines=MaxEmpty}) ->
|
req_empty_lines=ReqEmpty, max_empty_lines=MaxEmpty}) ->
|
||||||
case binary:split(Buffer, <<"\r\n">>) of
|
case binary:match(Buffer, <<"\r\n">>) of
|
||||||
[_] when byte_size(Buffer) > MaxLength ->
|
nomatch when byte_size(Buffer) > MaxLength ->
|
||||||
error_terminate(413, State);
|
error_terminate(413, State);
|
||||||
[<< "\n", _/binary >>] ->
|
nomatch ->
|
||||||
error_terminate(400, State);
|
|
||||||
[_] ->
|
|
||||||
wait_request(State);
|
wait_request(State);
|
||||||
[<<>>, _] when ReqEmpty =:= MaxEmpty ->
|
{0, _} when ReqEmpty =:= MaxEmpty ->
|
||||||
error_terminate(400, State);
|
error_terminate(400, State);
|
||||||
[<<>>, Rest] ->
|
{0, _} ->
|
||||||
|
<< _:16, Rest/binary >> = Buffer,
|
||||||
parse_request(State#state{
|
parse_request(State#state{
|
||||||
buffer=Rest, req_empty_lines=ReqEmpty + 1});
|
buffer=Rest, req_empty_lines=ReqEmpty + 1});
|
||||||
[RequestLine, Rest] ->
|
{Pos, _} ->
|
||||||
|
<< RequestLine:Pos/binary, _:16, Rest/binary >> = Buffer,
|
||||||
case cowboy_http:request_line(RequestLine) of
|
case cowboy_http:request_line(RequestLine) of
|
||||||
{Method, AbsPath, Version} ->
|
{Method, AbsPath, Version} ->
|
||||||
request(State#state{buffer=Rest}, Method, AbsPath, Version);
|
request(State#state{buffer=Rest}, Method, AbsPath, Version);
|
||||||
|
@ -178,12 +181,13 @@ parse_header(State=#state{buffer= << "\r\n", Rest/binary >>}, Req) ->
|
||||||
header_end(State#state{buffer=Rest}, Req);
|
header_end(State#state{buffer=Rest}, Req);
|
||||||
parse_header(State=#state{buffer=Buffer,
|
parse_header(State=#state{buffer=Buffer,
|
||||||
max_header_name_length=MaxLength}, Req) ->
|
max_header_name_length=MaxLength}, Req) ->
|
||||||
case binary:split(Buffer, <<":">>) of
|
case binary:match(Buffer, <<":">>) of
|
||||||
[_] when byte_size(Buffer) > MaxLength ->
|
nomatch when byte_size(Buffer) > MaxLength ->
|
||||||
error_terminate(413, State);
|
error_terminate(413, State);
|
||||||
[_] ->
|
nomatch ->
|
||||||
wait_header(State, Req, fun parse_header/2);
|
wait_header(State, Req, fun parse_header/2);
|
||||||
[Name, Rest] ->
|
{Pos, _} ->
|
||||||
|
<< Name:Pos/binary, _:8, Rest/binary >> = Buffer,
|
||||||
Name2 = cowboy_bstr:to_lower(Name),
|
Name2 = cowboy_bstr:to_lower(Name),
|
||||||
Rest2 = cowboy_http:whitespace(Rest, fun(D) -> D end),
|
Rest2 = cowboy_http:whitespace(Rest, fun(D) -> D end),
|
||||||
parse_header_value(State#state{buffer=Rest2}, Req, Name2, <<>>)
|
parse_header_value(State#state{buffer=Rest2}, Req, Name2, <<>>)
|
||||||
|
@ -191,18 +195,25 @@ parse_header(State=#state{buffer=Buffer,
|
||||||
|
|
||||||
parse_header_value(State=#state{buffer=Buffer,
|
parse_header_value(State=#state{buffer=Buffer,
|
||||||
max_header_value_length=MaxLength}, Req, Name, SoFar) ->
|
max_header_value_length=MaxLength}, Req, Name, SoFar) ->
|
||||||
case binary:split(Buffer, <<"\r\n">>) of
|
case binary:match(Buffer, <<"\r\n">>) of
|
||||||
[_] when byte_size(Buffer) + byte_size(SoFar) > MaxLength ->
|
nomatch when byte_size(Buffer) + byte_size(SoFar) > MaxLength ->
|
||||||
error_terminate(413, State);
|
error_terminate(413, State);
|
||||||
[_] ->
|
nomatch ->
|
||||||
wait_header(State, Req,
|
wait_header(State, Req,
|
||||||
fun(S, R) -> parse_header_value(S, R, Name, SoFar) end);
|
fun(S, R) -> parse_header_value(S, R, Name, SoFar) end);
|
||||||
[Value, << C, Rest/binary >>] when C =:= $\s; C =:= $\t ->
|
{Pos, _} when Pos + 2 =:= byte_size(Buffer) ->
|
||||||
parse_header_value(State#state{buffer=Rest}, Req, Name,
|
wait_header(State, Req,
|
||||||
<< SoFar/binary, Value/binary >>);
|
fun(S, R) -> parse_header_value(S, R, Name, SoFar) end);
|
||||||
[Value, Rest] ->
|
{Pos, _} ->
|
||||||
header(State#state{buffer=Rest}, Req, Name,
|
<< Value:Pos/binary, _:16, Rest/binary >> = Buffer,
|
||||||
<< SoFar/binary, Value/binary >>)
|
case binary:at(Buffer, Pos + 2) of
|
||||||
|
C when C =:= $\s; C =:= $\t ->
|
||||||
|
parse_header_value(State#state{buffer=Rest}, Req, Name,
|
||||||
|
<< SoFar/binary, Value/binary >>);
|
||||||
|
_ ->
|
||||||
|
header(State#state{buffer=Rest}, Req, Name,
|
||||||
|
<< SoFar/binary, Value/binary >>)
|
||||||
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec wait_header(#state{}, cowboy_req:req(), fun()) -> ok.
|
-spec wait_header(#state{}, cowboy_req:req(), fun()) -> ok.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue