From a4f8bb65739b8a3b102c244a5ef7e5aa6a9f38e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= <essen@dev-extend.eu>
Date: Sat, 19 Mar 2011 18:53:59 +0100
Subject: Add support for the '*' path.

Mostly used by the following request: OPTIONS * HTTP/1.1
---
 include/types.hrl            | 4 ++--
 src/cowboy_dispatcher.erl    | 8 ++++++--
 src/cowboy_http_protocol.erl | 5 +++++
 3 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/include/types.hrl b/include/types.hrl
index 17882cc..1940a14 100644
--- a/include/types.hrl
+++ b/include/types.hrl
@@ -25,8 +25,8 @@
 -type port_number() :: 0..65535.
 
 -type bindings() :: list({Key::atom(), Value::string()}).
--type path_tokens() :: list(string()).
--type match() :: '_' | list(string() | '_' | atom()).
+-type path_tokens() :: '*' | list(string()).
+-type match() :: '_' | '*' | list(string() | '_' | atom()).
 
 -type dispatch_rules() :: {Host::match(), list({Path::match(),
 	Handler::module(), Opts::term()})}.
diff --git a/src/cowboy_dispatcher.erl b/src/cowboy_dispatcher.erl
index 755a398..d66caf0 100644
--- a/src/cowboy_dispatcher.erl
+++ b/src/cowboy_dispatcher.erl
@@ -25,6 +25,8 @@ split_host(Host) ->
 	string:tokens(Host, ".").
 
 -spec split_path(Path::string()) -> {Tokens::path_tokens(), Qs::string()}.
+split_path('*') ->
+	{'*', []};
 split_path(Path) ->
 	case string:chr(Path, $?) of
 		0 ->
@@ -57,6 +59,8 @@ match_path(_Path, [], _HostBinds) ->
 	{error, notfound, path};
 match_path(_Path, [{'_', Handler, Opts}|_Tail], HostBinds) ->
 	{ok, Handler, Opts, HostBinds};
+match_path('*', [{'*', Handler, Opts}|_Tail], HostBinds) ->
+	{ok, Handler, Opts, HostBinds};
 match_path(Path, [{PathMatch, Handler, Opts}|Tail], HostBinds) ->
 	case try_match(path, Path, PathMatch) of
 		false ->
@@ -120,7 +124,6 @@ split_path_test_() ->
 	Tests = [
 		{"?", [], []},
 		{"???", [], "??"},
-		{"*", ["*"], []},
 		{"/", [], []},
 		{"/users", ["users"], []},
 		{"/users?", ["users"], []},
@@ -128,7 +131,8 @@ split_path_test_() ->
 		{"/users/42/friends?a=b&c=d&e=notsure?whatever",
 			["users", "42", "friends"], "a=b&c=d&e=notsure?whatever"}
 	],
-	[{P, fun() -> {R, Qs} = split_path(P) end} || {P, R, Qs} <- Tests].
+	[{"atom '*'", fun() -> {'*', []} = split_path('*') end}]
+		++ [{P, fun() -> {R, Qs} = split_path(P) end} || {P, R, Qs} <- Tests].
 
 match_test_() ->
 	Dispatch = [
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl
index 82cf733..b25c2f4 100644
--- a/src/cowboy_http_protocol.erl
+++ b/src/cowboy_http_protocol.erl
@@ -68,6 +68,11 @@ request({http_request, Method, {abs_path, AbsPath}, Version},
 	{ok, Peer} = Transport:peername(Socket),
 	wait_header(#http_req{socket=Socket, transport=Transport, method=Method,
 		version=Version, peer=Peer, path=Path, raw_qs=Qs}, State);
+request({http_request, Method, '*', Version},
+		State=#state{socket=Socket, transport=Transport}) ->
+	{ok, Peer} = Transport:peername(Socket),
+	wait_header(#http_req{socket=Socket, transport=Transport, method=Method,
+		version=Version, peer=Peer, path='*', raw_qs=[]}, State);
 request({http_request, _Method, _URI, _Version}, State) ->
 	error_terminate(501, State);
 request({http_error, "\r\n"}, State) ->
-- 
cgit v1.2.3