24
1
mirror of https://github.com/processone/ejabberd.git synced 2024-07-04 23:15:31 +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.
send_text(State, none) ->
send_text(_State, none) ->
exit(normal);
send_text(State, Text) ->
case catch (State#state.sockmod):send(State#state.socket, Text) of
@ -298,6 +298,11 @@ process_header(State, Data) ->
add_header(Name, Value, State) ->
[{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}
%% where
%% SockMod = gen_tcp | tls
@ -322,17 +327,34 @@ get_transfer_protocol(SockMod, HostPort) ->
%% XXX bard: search through request handlers looking for one that
%% matches the requested URL path, and pass control to it. If none is
%% found, answer with HTTP 404.
process([], _) ->
ejabberd_web:error(not_found);
process(Handlers, #ws{} = Ws)->
[{HandlerPathPrefix, HandlerModule} | HandlersLeft] = Handlers,
[{HandlerPathPrefix, HandlerModule, HandlerOpts} | HandlersLeft] = Handlers,
case (lists:prefix(HandlerPathPrefix, Ws#ws.path) or
(HandlerPathPrefix==Ws#ws.path)) of
true ->
?DEBUG("~p matches ~p", [Ws#ws.path, HandlerPathPrefix]),
LocalPath = lists:nthtail(length(HandlerPathPrefix), Ws#ws.path),
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 ->
?DEBUG("HandlersLeft : ~p ", [HandlersLeft]),
process(HandlersLeft, Ws)

View File

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

View File

@ -38,7 +38,7 @@
-module (ejabberd_websocket).
-author('ecestari@process-one.net').
-compile(export_all).
-export([connect/2, check/2, is_acceptable/1]).
-include("ejabberd.hrl").
-include("jlib.hrl").
-include("ejabberd_http.hrl").
@ -49,6 +49,26 @@ check(_Path, Headers)->
% checks
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(#ws{vsn = Vsn, socket = Socket, origin=Origin, host=Host, port=Port, sockmod = SockMod, path = Path, headers = Headers, ws_autoexit = WsAutoExit} = Ws, WsLoop) ->
% build handshake