24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-07-06 23:22:36 +02:00

[TECH-1151] Origin and Protocol parameters are configurable and set.

This commit is contained in:
Eric Cestari 2010-09-17 14:23:34 +02:00
parent a45ecb70ff
commit ff4f052bb1
3 changed files with 49 additions and 5 deletions

View File

@ -155,7 +155,7 @@ socket_type() ->
raw. raw.
send_text(State, none) -> send_text(_State, none) ->
exit(normal); exit(normal);
send_text(State, Text) -> send_text(State, Text) ->
case catch (State#state.sockmod):send(State#state.socket, Text) of case catch (State#state.sockmod):send(State#state.socket, Text) of
@ -298,6 +298,11 @@ process_header(State, Data) ->
add_header(Name, Value, State) -> add_header(Name, Value, State) ->
[{Name, Value} | State#state.request_headers]. [{Name, Value} | State#state.request_headers].
-define(GETOPT(Param, Opts),
case lists:keysearch(Param, 1, Opts) of
{value, {Param, V}} -> V;
false -> undefined
end).
%% @spec (SockMod, HostPort) -> {Host::string(), Port::integer(), TP} %% @spec (SockMod, HostPort) -> {Host::string(), Port::integer(), TP}
%% where %% where
%% SockMod = gen_tcp | tls %% SockMod = gen_tcp | tls
@ -322,17 +327,34 @@ get_transfer_protocol(SockMod, HostPort) ->
%% XXX bard: search through request handlers looking for one that %% XXX bard: search through request handlers looking for one that
%% matches the requested URL path, and pass control to it. If none is %% matches the requested URL path, and pass control to it. If none is
%% found, answer with HTTP 404. %% found, answer with HTTP 404.
process([], _) -> process([], _) ->
ejabberd_web:error(not_found); ejabberd_web:error(not_found);
process(Handlers, #ws{} = Ws)-> process(Handlers, #ws{} = Ws)->
[{HandlerPathPrefix, HandlerModule} | HandlersLeft] = Handlers, [{HandlerPathPrefix, HandlerModule, HandlerOpts} | HandlersLeft] = Handlers,
case (lists:prefix(HandlerPathPrefix, Ws#ws.path) or case (lists:prefix(HandlerPathPrefix, Ws#ws.path) or
(HandlerPathPrefix==Ws#ws.path)) of (HandlerPathPrefix==Ws#ws.path)) of
true -> true ->
?DEBUG("~p matches ~p", [Ws#ws.path, HandlerPathPrefix]), ?DEBUG("~p matches ~p", [Ws#ws.path, HandlerPathPrefix]),
LocalPath = lists:nthtail(length(HandlerPathPrefix), Ws#ws.path), LocalPath = lists:nthtail(length(HandlerPathPrefix), Ws#ws.path),
ejabberd_hooks:run(ws_debug, [{LocalPath, Ws}]), ejabberd_hooks:run(ws_debug, [{LocalPath, Ws}]),
ejabberd_websocket:connect(Ws#ws{local_path = LocalPath}, HandlerModule); Protocol = case lists:keysearch(protocol, 1, HandlerOpts) of
{value, {protocol, P}} -> P;
false -> undefined
end,
Origins = case lists:keysearch(origins, 1, HandlerOpts) of
{value, {origins, O}} -> O;
false -> []
end,
WS2 = Ws#ws{local_path = LocalPath,
protocol=Protocol,
acceptable_origins=Origins},
case ejabberd_websocket:is_acceptable(WS2) of
true ->
ejabberd_websocket:connect(WS2, HandlerModule);
false ->
process(HandlersLeft, Ws)
end;
false -> false ->
?DEBUG("HandlersLeft : ~p ", [HandlersLeft]), ?DEBUG("HandlersLeft : ~p ", [HandlersLeft]),
process(HandlersLeft, Ws) process(HandlersLeft, Ws)

View File

@ -48,5 +48,7 @@
port, port,
path, % the websocket GET request path path, % the websocket GET request path
headers, % [{Tag, Val}] headers, % [{Tag, Val}]
local_path local_path,
protocol,
acceptable_origins
}). }).

View File

@ -38,7 +38,7 @@
-module (ejabberd_websocket). -module (ejabberd_websocket).
-author('ecestari@process-one.net'). -author('ecestari@process-one.net').
-compile(export_all). -export([connect/2, check/2, is_acceptable/1]).
-include("ejabberd.hrl"). -include("ejabberd.hrl").
-include("jlib.hrl"). -include("jlib.hrl").
-include("ejabberd_http.hrl"). -include("ejabberd_http.hrl").
@ -49,6 +49,26 @@ check(_Path, Headers)->
% checks % checks
check_websockets(VsnSupported, Headers). check_websockets(VsnSupported, Headers).
% Checks if websocket can be access by client
% If origins are set in configuration, check if it belongs
% If origins not set, access is open.
is_acceptable(#ws{origin=Origin, protocol=Protocol,
headers = Headers, acceptable_origins = Origins})->
ClientProtocol = lists:keyfind("Sec-WebSocket-Protocol",1, Headers),
case {Origin == [] or lists:member(Origin, Origins), ClientProtocol, Protocol } of
{false, _, _} ->
?DEBUG("client does not come from authorized origin", []),
false;
{_, false, _} ->
?DEBUG("Client did not ask for protocol", []),
true;
{_, {_, P}, P} ->
?DEBUG("Protocoles are matching", []),
true;
_ -> false
end.
% Connect and handshake with Websocket. % Connect and handshake with Websocket.
connect(#ws{vsn = Vsn, socket = Socket, origin=Origin, host=Host, port=Port, sockmod = SockMod, path = Path, headers = Headers, ws_autoexit = WsAutoExit} = Ws, WsLoop) -> connect(#ws{vsn = Vsn, socket = Socket, origin=Origin, host=Host, port=Port, sockmod = SockMod, path = Path, headers = Headers, ws_autoexit = WsAutoExit} = Ws, WsLoop) ->
% build handshake % build handshake