diff options
author | Loïc Hoguin <[email protected]> | 2012-09-15 22:03:00 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2012-09-15 22:03:00 +0200 |
commit | 27d591180ca3dd8b0d3c63c1293da5a3c4f4321f (patch) | |
tree | 271f0e533b210799c442ff28542146e56b8b15ee | |
parent | cd54214deff03d5ed4a487f9976c3db14f579961 (diff) | |
download | cowboy-27d591180ca3dd8b0d3c63c1293da5a3c4f4321f.tar.gz cowboy-27d591180ca3dd8b0d3c63c1293da5a3c4f4321f.tar.bz2 cowboy-27d591180ca3dd8b0d3c63c1293da5a3c4f4321f.zip |
Add cowboy_req:url/1 to return the full request URL
Use it in cowboy_websocket for hixie76, replacing http by ws.
-rw-r--r-- | src/cowboy_req.erl | 55 | ||||
-rw-r--r-- | src/cowboy_websocket.erl | 56 |
2 files changed, 59 insertions, 52 deletions
diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl index c7bb64b..51b1874 100644 --- a/src/cowboy_req.erl +++ b/src/cowboy_req.erl @@ -35,6 +35,7 @@ -export([qs_val/3]). -export([qs_vals/1]). -export([raw_qs/1]). +-export([url/1]). -export([binding/2]). -export([binding/3]). -export([bindings/1]). @@ -82,6 +83,7 @@ -export([transport/1]). -include("http.hrl"). +-include_lib("eunit/include/eunit.hrl"). -type req() :: #http_req{}. -export_type([req/0]). @@ -195,6 +197,29 @@ qs_vals(Req=#http_req{qs_vals=QsVals}) -> raw_qs(Req) -> {Req#http_req.raw_qs, Req}. +%% @doc Return the full request URL as a binary. +%% +%% The URL includes the scheme, host, port, path and query string. +-spec url(Req) -> {binary(), Req} when Req::req(). +url(Req=#http_req{transport=Transport, host=Host, port=Port, + path=Path, raw_qs=QS}) -> + TransportName = Transport:name(), + Secure = case TransportName of + ssl -> <<"s">>; + _ -> <<>> + end, + PortBin = case {TransportName, Port} of + {ssl, 443} -> <<>>; + {tcp, 80} -> <<>>; + _ -> << ":", (list_to_binary(integer_to_list(Port)))/binary >> + end, + QS2 = case QS of + <<>> -> <<>>; + _ -> << "?", QS/binary >> + end, + {<< "http", Secure/binary, "://", Host/binary, PortBin/binary, + Path/binary, QS2/binary >>, Req}. + %% @equiv binding(Name, Req, undefined) -spec binding(atom(), Req) -> {binary() | undefined, Req} when Req::req(). binding(Name, Req) when is_atom(Name) -> @@ -1026,3 +1051,33 @@ header_to_binary('Cookie') -> <<"Cookie">>; header_to_binary('Keep-Alive') -> <<"Keep-Alive">>; header_to_binary('Proxy-Connection') -> <<"Proxy-Connection">>; header_to_binary(B) when is_binary(B) -> B. + +%% Tests. + +-ifdef(TEST). + +url_test() -> + {<<"http://localhost/path">>, _ } = + url(#http_req{transport=ranch_tcp, host= <<"localhost">>, port=80, + path= <<"/path">>, raw_qs= <<>>, pid=self()}), + {<<"http://localhost:443/path">>, _} = + url(#http_req{transport=ranch_tcp, host= <<"localhost">>, port=443, + path= <<"/path">>, raw_qs= <<>>, pid=self()}), + {<<"http://localhost:8080/path">>, _} = + url(#http_req{transport=ranch_tcp, host= <<"localhost">>, port=8080, + path= <<"/path">>, raw_qs= <<>>, pid=self()}), + {<<"http://localhost:8080/path?dummy=2785">>, _} = + url(#http_req{transport=ranch_tcp, host= <<"localhost">>, port=8080, + path= <<"/path">>, raw_qs= <<"dummy=2785">>, pid=self()}), + {<<"https://localhost/path">>, _} = + url(#http_req{transport=ranch_ssl, host= <<"localhost">>, port=443, + path= <<"/path">>, raw_qs= <<>>, pid=self()}), + {<<"https://localhost:8443/path">>, _} = + url(#http_req{transport=ranch_ssl, host= <<"localhost">>, port=8443, + path= <<"/path">>, raw_qs= <<>>, pid=self()}), + {<<"https://localhost:8443/path?dummy=2785">>, _} = + url(#http_req{transport=ranch_ssl, host= <<"localhost">>, port=8443, + path= <<"/path">>, raw_qs= <<"dummy=2785">>, pid=self()}), + ok. + +-endif. diff --git a/src/cowboy_websocket.erl b/src/cowboy_websocket.erl index 04082e1..2db0faa 100644 --- a/src/cowboy_websocket.erl +++ b/src/cowboy_websocket.erl @@ -26,7 +26,6 @@ -export([handler_loop/4]). -include("http.hrl"). --include_lib("eunit/include/eunit.hrl"). -type opcode() :: 0 | 1 | 2 | 8 | 9 | 10. -type mask_key() :: 0..16#ffffffff. @@ -164,15 +163,14 @@ upgrade_denied(#http_req{socket=Socket, transport=Transport, -spec websocket_handshake(#state{}, cowboy_req:req(), any()) -> closed. websocket_handshake(State=#state{socket=Socket, transport=Transport, version=0, origin=Origin, challenge={Key1, Key2}}, - Req=#http_req{host=Host, port=Port, path=Path, raw_qs=QS}, - HandlerState) -> - Location = hixie76_location(Transport:name(), Host, Port, Path, QS), + Req, HandlerState) -> + {<< "http", Location/binary >>, Req1} = cowboy_req:url(Req), {ok, Req2} = cowboy_req:upgrade_reply( <<"101 WebSocket Protocol Handshake">>, [{<<"Upgrade">>, <<"WebSocket">>}, - {<<"Sec-Websocket-Location">>, Location}, + {<<"Sec-Websocket-Location">>, << "ws", Location/binary >>}, {<<"Sec-Websocket-Origin">>, Origin}], - Req), + Req1), %% Flush the resp_sent message before moving on. receive {cowboy_req, resp_sent} -> ok after 0 -> ok end, %% We replied with a proper response. Proxies should be happy enough, @@ -554,29 +552,6 @@ hixie76_key_to_integer(Key) -> Spaces = length([C || << C >> <= Key, C =:= 32]), Number div Spaces. --spec hixie76_location(atom(), binary(), inet:port_number(), - binary(), binary()) -> binary(). -hixie76_location(Protocol, Host, Port, Path, <<>>) -> - << (hixie76_location_protocol(Protocol))/binary, "://", Host/binary, - (hixie76_location_port(Protocol, Port))/binary, Path/binary>>; -hixie76_location(Protocol, Host, Port, Path, QS) -> - << (hixie76_location_protocol(Protocol))/binary, "://", Host/binary, - (hixie76_location_port(Protocol, Port))/binary, Path/binary, "?", QS/binary >>. - --spec hixie76_location_protocol(atom()) -> binary(). -hixie76_location_protocol(ssl) -> <<"wss">>; -hixie76_location_protocol(_) -> <<"ws">>. - -%% @todo We should add a secure/0 function to transports -%% instead of relying on their name. --spec hixie76_location_port(atom(), inet:port_number()) -> binary(). -hixie76_location_port(ssl, 443) -> - <<>>; -hixie76_location_port(tcp, 80) -> - <<>>; -hixie76_location_port(_, Port) -> - <<":", (list_to_binary(integer_to_list(Port)))/binary>>. - %% hybi specific. -spec hybi_challenge(binary()) -> binary(). @@ -592,26 +567,3 @@ hybi_payload_length(N) -> N when N =< 16#ffff -> << 126:7, N:16 >>; N when N =< 16#7fffffffffffffff -> << 127:7, N:64 >> end. - -%% Tests. - --ifdef(TEST). - -hixie76_location_test() -> - ?assertEqual(<<"ws://localhost/path">>, - hixie76_location(tcp, <<"localhost">>, 80, <<"/path">>, <<>>)), - ?assertEqual(<<"ws://localhost:443/path">>, - hixie76_location(tcp, <<"localhost">>, 443, <<"/path">>, <<>>)), - ?assertEqual(<<"ws://localhost:8080/path">>, - hixie76_location(tcp, <<"localhost">>, 8080, <<"/path">>, <<>>)), - ?assertEqual(<<"ws://localhost:8080/path?dummy=2785">>, - hixie76_location(tcp, <<"localhost">>, 8080, <<"/path">>, <<"dummy=2785">>)), - ?assertEqual(<<"wss://localhost/path">>, - hixie76_location(ssl, <<"localhost">>, 443, <<"/path">>, <<>>)), - ?assertEqual(<<"wss://localhost:8443/path">>, - hixie76_location(ssl, <<"localhost">>, 8443, <<"/path">>, <<>>)), - ?assertEqual(<<"wss://localhost:8443/path?dummy=2785">>, - hixie76_location(ssl, <<"localhost">>, 8443, <<"/path">>, <<"dummy=2785">>)), - ok. - --endif. |