mirror of
https://github.com/processone/ejabberd.git
synced 2024-10-05 14:51:05 +02:00
[TECH-1151] websockets are properly detected.
This commit is contained in:
parent
77136bccdf
commit
cccbf7de12
@ -378,17 +378,24 @@ process_request(#state{request_method = Method,
|
|||||||
%% ejabberd_web:process_get, now passes it to a local
|
%% ejabberd_web:process_get, now passes it to a local
|
||||||
%% procedure (process) that handles dispatching based on
|
%% procedure (process) that handles dispatching based on
|
||||||
%% URL path prefix.
|
%% URL path prefix.
|
||||||
case process(RequestHandlers, Request) of
|
case ejabberd_websocket:check(Path, RequestHeaders) of
|
||||||
El when element(1, El) == xmlelement ->
|
{true, _VSN} ->
|
||||||
make_xhtml_output(State, 200, [], El);
|
?DEBUG("It is a websocket version : ~p",[_VSN]);
|
||||||
{Status, Headers, El} when
|
|
||||||
element(1, El) == xmlelement ->
|
false ->
|
||||||
make_xhtml_output(State, Status, Headers, El);
|
?DEBUG("It is not a websocket.",[]),
|
||||||
Output when is_list(Output) or is_binary(Output) ->
|
case process(RequestHandlers, Request) of
|
||||||
make_text_output(State, 200, [], Output);
|
El when element(1, El) == xmlelement ->
|
||||||
{Status, Headers, Output} when is_list(Output) or is_binary(Output) ->
|
make_xhtml_output(State, 200, [], El);
|
||||||
make_text_output(State, Status, Headers, Output)
|
{Status, Headers, El} when
|
||||||
end
|
element(1, El) == xmlelement ->
|
||||||
|
make_xhtml_output(State, Status, Headers, El);
|
||||||
|
Output when is_list(Output) or is_binary(Output) ->
|
||||||
|
make_text_output(State, 200, [], Output);
|
||||||
|
{Status, Headers, Output} when is_list(Output) or is_binary(Output) ->
|
||||||
|
make_text_output(State, Status, Headers, Output)
|
||||||
|
end
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
process_request(#state{request_method = Method,
|
process_request(#state{request_method = Method,
|
||||||
|
@ -39,11 +39,11 @@
|
|||||||
-module (ejabberd_websocket).
|
-module (ejabberd_websocket).
|
||||||
-author('ecestari@process-one.net').
|
-author('ecestari@process-one.net').
|
||||||
-compile(export_all).
|
-compile(export_all).
|
||||||
|
-include("ejabberd.hrl").
|
||||||
|
-include("jlib.hrl").
|
||||||
-include ("ejabberd_http.hrl").
|
-include ("ejabberd_http.hrl").
|
||||||
-include ("ejabberd.hrl").
|
|
||||||
|
|
||||||
check(Headers)->
|
check(_Path, Headers)->
|
||||||
?DEBUG("testing for a websocket request path: ~p headers: ~p", [_Path, Headers]),
|
?DEBUG("testing for a websocket request path: ~p headers: ~p", [_Path, Headers]),
|
||||||
% set supported websocket protocols, order does matter
|
% set supported websocket protocols, order does matter
|
||||||
VsnSupported = [{'draft-hixie', 76}, {'draft-hixie', 68}],
|
VsnSupported = [{'draft-hixie', 76}, {'draft-hixie', 68}],
|
||||||
@ -63,8 +63,8 @@ check_websocket({'draft-hixie', 76} = Vsn, Headers) ->
|
|||||||
?DEBUG("testing for websocket protocol ~p", [Vsn]),
|
?DEBUG("testing for websocket protocol ~p", [Vsn]),
|
||||||
% set required headers
|
% set required headers
|
||||||
RequiredHeaders = [
|
RequiredHeaders = [
|
||||||
{'Upgrade', "WebSocket"}, {'Connection', "Upgrade"}, {'Host', ignore}, {'Origin', ignore},
|
{'Upgrade', "WebSocket"}, {'Connection', "Upgrade"}, {'Host', ignore}, {"Origin", ignore},
|
||||||
{'Sec-WebSocket-Key1', ignore}, {'Sec-WebSocket-Key2', ignore}
|
{"Sec-WebSocket-Key1", ignore}, {"Sec-WebSocket-Key2", ignore}
|
||||||
],
|
],
|
||||||
% check for headers existance
|
% check for headers existance
|
||||||
case check_headers(Headers, RequiredHeaders) of
|
case check_headers(Headers, RequiredHeaders) of
|
||||||
@ -72,20 +72,20 @@ check_websocket({'draft-hixie', 76} = Vsn, Headers) ->
|
|||||||
% return
|
% return
|
||||||
{true, Vsn};
|
{true, Vsn};
|
||||||
_RemainingHeaders ->
|
_RemainingHeaders ->
|
||||||
?LOG_DEBUG("not protocol ~p, remaining headers: ~p", [Vsn, _RemainingHeaders]),
|
?DEBUG("not protocol ~p, remaining headers: ~p", [Vsn, _RemainingHeaders]),
|
||||||
false
|
false
|
||||||
end;
|
end;
|
||||||
check_websocket({'draft-hixie', 68} = Vsn, Headers) ->
|
check_websocket({'draft-hixie', 68} = Vsn, Headers) ->
|
||||||
?DEBUG("testing for websocket protocol ~p", [Vsn]),
|
?DEBUG("testing for websocket protocol ~p", [Vsn]),
|
||||||
% set required headers
|
% set required headers
|
||||||
RequiredHeaders = [
|
RequiredHeaders = [
|
||||||
{'Upgrade', "WebSocket"}, {'Connection', "Upgrade"}, {'Host', ignore}, {'Origin', ignore}
|
{'Upgrade', "WebSocket"}, {'Connection', "Upgrade"}, {'Host', ignore}, {"Origin", ignore}
|
||||||
],
|
],
|
||||||
% check for headers existance
|
% check for headers existance
|
||||||
case check_headers(Headers, RequiredHeaders) of
|
case check_headers(Headers, RequiredHeaders) of
|
||||||
true -> {true, Vsn};
|
true -> {true, Vsn};
|
||||||
_RemainingHeaders ->
|
_RemainingHeaders ->
|
||||||
?LOG_DEBUG("not protocol ~p, remaining headers: ~p", [Vsn, _RemainingHeaders]),
|
?DEBUG("not protocol ~p, remaining headers: ~p", [Vsn, _RemainingHeaders]),
|
||||||
false
|
false
|
||||||
end;
|
end;
|
||||||
check_websocket(_Vsn, _Headers) -> false. % not implemented
|
check_websocket(_Vsn, _Headers) -> false. % not implemented
|
||||||
@ -97,7 +97,7 @@ check_headers(Headers, RequiredHeaders) ->
|
|||||||
% see if the required Tag is in the Headers
|
% see if the required Tag is in the Headers
|
||||||
case lists:keysearch(Tag, 1, Headers) of
|
case lists:keysearch(Tag, 1, Headers) of
|
||||||
false -> true; % header not found, keep in list
|
false -> true; % header not found, keep in list
|
||||||
HVal ->
|
{value, {Tag, HVal}} ->
|
||||||
case Val of
|
case Val of
|
||||||
ignore -> false; % ignore value -> ok, remove from list
|
ignore -> false; % ignore value -> ok, remove from list
|
||||||
HVal -> false; % expected val -> ok, remove from list
|
HVal -> false; % expected val -> ok, remove from list
|
||||||
@ -112,13 +112,13 @@ check_headers(Headers, RequiredHeaders) ->
|
|||||||
|
|
||||||
% Function: List
|
% Function: List
|
||||||
% Description: Builds the server handshake response.
|
% Description: Builds the server handshake response.
|
||||||
handshake({'draft-hixie', 76}, #req{socket = Sock, socket_mode = SocketMode}, Headers, {Path, Origin, Host}) ->
|
handshake({'draft-hixie', 76}, Sock,SocketMod, Headers, {Path, Origin, Host}) ->
|
||||||
% build data
|
% build data
|
||||||
Key1 = lists:keysearch('Sec-WebSocket-Key1',1, Headers),
|
Key1 = lists:keysearch("Sec-WebSocket-Key1",1, Headers),
|
||||||
Key2 = lists:keysearch('Sec-WebSocket-Key2',1, Headers),
|
Key2 = lists:keysearch("Sec-WebSocket-Key2",1, Headers),
|
||||||
% handshake needs body of the request, still need to read it [TODO: default recv timeout hard set, will be exported when WS protocol is final]
|
% handshake needs body of the request, still need to read it [TODO: default recv timeout hard set, will be exported when WS protocol is final]
|
||||||
misultin_socket:setopts(Sock, [{packet, raw}, {active, false}], SocketMode),
|
SocketMod:setopts(Sock, [{packet, raw}, {active, false}]),
|
||||||
Body = case misultin_socket:recv(Sock, 8, 30*1000, SocketMode) of
|
Body = case SocketMod:recv(Sock, 8, 30*1000) of
|
||||||
{ok, Bin} -> Bin;
|
{ok, Bin} -> Bin;
|
||||||
{error, timeout} ->
|
{error, timeout} ->
|
||||||
?WARNING_MSG("timeout in reading websocket body", []),
|
?WARNING_MSG("timeout in reading websocket body", []),
|
||||||
@ -136,7 +136,7 @@ handshake({'draft-hixie', 76}, #req{socket = Sock, socket_mode = SocketMode}, He
|
|||||||
"Sec-WebSocket-Location: ws://", lists:concat([Host, Path]), "\r\n\r\n",
|
"Sec-WebSocket-Location: ws://", lists:concat([Host, Path]), "\r\n\r\n",
|
||||||
build_challenge({'draft-hixie', 76}, {Key1, Key2, Body})
|
build_challenge({'draft-hixie', 76}, {Key1, Key2, Body})
|
||||||
];
|
];
|
||||||
handshake({'draft-hixie', 68}, _Req, _Headers, {Path, Origin, Host}) ->
|
handshake({'draft-hixie', 68}, _Sock,_SocketMod, _Headers, {Path, Origin, Host}) ->
|
||||||
% prepare handhsake response
|
% prepare handhsake response
|
||||||
["HTTP/1.1 101 Web Socket Protocol Handshake\r\n",
|
["HTTP/1.1 101 Web Socket Protocol Handshake\r\n",
|
||||||
"Upgrade: WebSocket\r\n",
|
"Upgrade: WebSocket\r\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user