diff options
author | Loïc Hoguin <[email protected]> | 2011-03-17 22:02:47 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2011-03-17 22:02:47 +0100 |
commit | 786a05a129d9aeff7f88deaf6d9e4f06b935b665 (patch) | |
tree | 1030d9eeb2904d68ece316c797a155b989638e5d | |
parent | da7225594010d0df20779a0915474ccedd25d7cf (diff) | |
download | cowboy-786a05a129d9aeff7f88deaf6d9e4f06b935b665.tar.gz cowboy-786a05a129d9aeff7f88deaf6d9e4f06b935b665.tar.bz2 cowboy-786a05a129d9aeff7f88deaf6d9e4f06b935b665.zip |
Run the dispatcher as early as possible to quickly dismiss 404 errors.
-rw-r--r-- | src/cowboy_http_protocol.erl | 36 |
1 files changed, 19 insertions, 17 deletions
diff --git a/src/cowboy_http_protocol.erl b/src/cowboy_http_protocol.erl index 726f33c..3a8aac7 100644 --- a/src/cowboy_http_protocol.erl +++ b/src/cowboy_http_protocol.erl @@ -23,6 +23,7 @@ socket :: socket(), transport :: module(), dispatch :: dispatch(), + handler :: {Handler::module(), Opts::term()}, timeout :: timeout(), connection = keepalive :: keepalive | close }). @@ -81,12 +82,19 @@ wait_header(Req, State=#state{socket=Socket, -spec header({http_header, I::integer(), Field::http_header(), R::term(), Value::string()} | http_eoh, Req::#http_req{}, State::#state{}) -> ok. -header({http_header, _I, 'Host', _R, Value}, Req, State) -> +header({http_header, _I, 'Host', _R, Value}, Req=#http_req{path=Path}, + State=#state{dispatch=Dispatch}) -> Host = cowboy_dispatcher:split_host(Value), - %% @todo We have Host and Path at this point, dispatch right away and - %% error_terminate(404) early if it fails. - wait_header(Req#http_req{host=Host, - headers=[{'Host', Value}|Req#http_req.headers]}, State); + %% @todo We probably want to filter the Host and Path here to allow + %% things like url rewriting. + case cowboy_dispatcher:match(Host, Path, Dispatch) of + {ok, Handler, Opts, Binds} -> + wait_header(Req#http_req{host=Host, bindings=Binds, + headers=[{'Host', Value}|Req#http_req.headers]}, + State#state{handler={Handler, Opts}}); + {error, notfound} -> + error_terminate(404, State) + end; header({http_header, _I, 'Connection', _R, Connection}, Req, State) -> wait_header(Req#http_req{ headers=[{'Connection', Connection}|Req#http_req.headers]}, @@ -97,22 +105,16 @@ header({http_header, _I, Field, _R, Value}, Req, State) -> %% The Host header is required. header(http_eoh, #http_req{host=undefined}, State) -> error_terminate(400, State); -header(http_eoh, Req=#http_req{host=Host, path=Path}, - State=#state{dispatch=Dispatch}) -> - %% @todo We probably want to filter the Host and Patch here to allow - %% things like url rewriting. - dispatch(cowboy_dispatcher:match(Host, Path, Dispatch), Req, State). +header(http_eoh, Req, State) -> + handler_loop(Req, State). --spec dispatch({ok, Handler::module(), Opts::term(), Binds::bindings()} - | {error, notfound}, Req::#http_req{}, State::#state{}) -> ok. -dispatch({ok, Handler, Opts, Binds}, Req, State) -> - case Handler:handle(Opts, Req#http_req{bindings=Binds}) of +-spec handler_loop(Req::#http_req{}, State::#state{}) -> ok. +handler_loop(Req, State=#state{handler={Handler, Opts}}) -> + case Handler:handle(Opts, Req) of {reply, RCode, RHeaders, RBody} -> reply(RCode, RHeaders, RBody, State) %% @todo stream_reply, request_body, stream_request_body... - end; -dispatch({error, notfound}, _Req, State) -> - error_terminate(404, State). + end. -spec error_terminate(Code::http_status(), State::#state{}) -> ok. error_terminate(Code, State) -> |