aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_http.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2012-09-20 06:22:51 +0200
committerLoïc Hoguin <[email protected]>2012-09-21 08:54:57 +0200
commit8497c8bbcdcfd8754c500e65557ee09d9bd1bed0 (patch)
tree76abb26e328b916addb95db4778f0666a1a7d4fb /src/cowboy_http.erl
parentf6791b008ac8ccaa331bfbae9afb69af5bf36a7a (diff)
downloadcowboy-8497c8bbcdcfd8754c500e65557ee09d9bd1bed0.tar.gz
cowboy-8497c8bbcdcfd8754c500e65557ee09d9bd1bed0.tar.bz2
cowboy-8497c8bbcdcfd8754c500e65557ee09d9bd1bed0.zip
Don't use decode_packet/3 for parsing the request-line
First step in making all methods and header names binaries to get rid of many inconsistencies caused by decode_packet/3. Methods are all binary now. Note that since they are case sensitive, the usual methods become <<"GET">>, <<"POST">> and so on.
Diffstat (limited to 'src/cowboy_http.erl')
-rw-r--r--src/cowboy_http.erl44
1 files changed, 41 insertions, 3 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index f3457dc..83a67fe 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -17,6 +17,7 @@
-module(cowboy_http).
%% Parsing.
+-export([request_line/1]).
-export([list/2]).
-export([nonempty_list/2]).
-export([content_type/1]).
@@ -50,8 +51,6 @@
-export([urlencode/2]).
-export([x_www_form_urlencoded/2]).
--type method() :: 'OPTIONS' | 'GET' | 'HEAD'
- | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | binary().
-type uri() :: '*' | {absoluteURI, http | https, Host::binary(),
Port::integer() | undefined, Path::binary()}
| {scheme, Scheme::binary(), binary()}
@@ -73,7 +72,6 @@
-type headers() :: [{header(), iodata()}].
-type status() :: non_neg_integer() | binary().
--export_type([method/0]).
-export_type([uri/0]).
-export_type([version/0]).
-export_type([header/0]).
@@ -86,6 +84,46 @@
%% 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:split(Data, <<" ">>) of
+ [_] -> %% We require the HTTP version.
+ {error, badarg};
+ [URI, Rest] ->
+ case binary:split(URI, <<"://">>) of
+ [_] -> %% Already is a path or "*".
+ Fun(Rest, URI);
+ [_, NoScheme] ->
+ case binary:split(NoScheme, <<"/">>) of
+ [_] -> <<"/">>;
+ [_, NoHost] -> 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) ->