diff options
author | Loïc Hoguin <[email protected]> | 2012-09-26 14:11:53 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2012-09-26 14:20:29 +0200 |
commit | b2243aa54438dbea4137960c9dc6f54ac746f429 (patch) | |
tree | b7f3768cc6fea9bcc9d4363012a6cdf149178977 /src/cowboy_http.erl | |
parent | bfab8d4b22d858e7cffa97d04210a62fae56681c (diff) | |
download | cowboy-b2243aa54438dbea4137960c9dc6f54ac746f429.tar.gz cowboy-b2243aa54438dbea4137960c9dc6f54ac746f429.tar.bz2 cowboy-b2243aa54438dbea4137960c9dc6f54ac746f429.zip |
Optimize cowboy_protocol
* #state{} changes are avoided where possible
* #state{} is now smaller and use less memory
* the Req object is created only after the whole request is parsed
* parsing makes use of a single binary match context
* external calls are avoided in the critical path
* URL fragment is now extracted properly (retrieval API next commit)
* argument orders to local functions modified to avoid extra operations
* dispatching waits as long as possible before tokenizing host/path
* handler opts are no longer shown in the error messages except in init
The code may not look as beautiful as it was before. But it really
is, for parsing code. The parsing section of the file may be skipped
if your eyes start to burn.
Diffstat (limited to 'src/cowboy_http.erl')
-rw-r--r-- | src/cowboy_http.erl | 51 |
1 files changed, 0 insertions, 51 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl index a936e2c..c3bef2f 100644 --- a/src/cowboy_http.erl +++ b/src/cowboy_http.erl @@ -17,7 +17,6 @@ -module(cowboy_http). %% Parsing. --export([request_line/1]). -export([list/2]). -export([nonempty_list/2]). -export([content_type/1]). @@ -51,15 +50,10 @@ -export([urlencode/2]). -export([x_www_form_urlencoded/2]). --type uri() :: '*' | {absoluteURI, http | https, Host::binary(), - Port::integer() | undefined, Path::binary()} - | {scheme, Scheme::binary(), binary()} - | {abs_path, binary()} | binary(). -type version() :: {Major::non_neg_integer(), Minor::non_neg_integer()}. -type headers() :: [{binary(), iodata()}]. -type status() :: non_neg_integer() | binary(). --export_type([uri/0]). -export_type([version/0]). -export_type([headers/0]). -export_type([status/0]). @@ -70,51 +64,6 @@ %% Parsing. -%% @doc Parse a request-line. --spec request_line(binary()) - -> {binary(), binary(), version()} | {error, badarg}. -request_line(Data) -> - token(Data, - fun (Rest, Method) -> - whitespace(Rest, - fun (Rest2) -> - uri_to_abspath(Rest2, - fun (Rest3, AbsPath) -> - whitespace(Rest3, - fun (<< "HTTP/", Maj, ".", Min, _/binary >>) - when Maj >= $0, Maj =< $9, - Min >= $0, Min =< $9 -> - {Method, AbsPath, {Maj - $0, Min - $0}}; - (_) -> - {error, badarg} - end) - end) - end) - end). - -%% We just want to extract the path/qs and skip everything else. -%% We do not really parse the URI, nor do we need to. -uri_to_abspath(Data, Fun) -> - case binary:match(Data, <<" ">>) of - nomatch -> %% We require the HTTP version. - {error, badarg}; - {Pos1, _} -> - << URI:Pos1/binary, _:8, Rest/bits >> = Data, - case binary:match(URI, <<"://">>) of - nomatch -> %% Already is a path or "*". - Fun(Rest, URI); - {Pos2, _} -> - << _:Pos2/binary, _:24, NoScheme/bits >> = Rest, - case binary:match(NoScheme, <<"/">>) of - nomatch -> - Fun(Rest, <<"/">>); - {Pos3, _} -> - << _:Pos3/binary, _:8, NoHost/bits >> = NoScheme, - Fun(Rest, << "/", NoHost/binary >>) - end - end - end. - %% @doc Parse a non-empty list of the given type. -spec nonempty_list(binary(), fun()) -> [any(), ...] | {error, badarg}. nonempty_list(Data, Fun) -> |