aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2014-10-03 18:53:55 +0400
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2014-10-04 12:49:12 +0400
commit1d782db84fd3a0a7351539315ab90e557b667dc1 (patch)
treefc8819dc9968ac22d8628ddf47632a18c5ef3a97 /src
parentMake directory creation more robust (diff)
Process XML-RPC requests via p1_xml and ejabberd_http
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_http.erl14
-rw-r--r--src/ejabberd_listener.erl6
-rw-r--r--src/ejabberd_xmlrpc.erl52
3 files changed, 44 insertions, 28 deletions
diff --git a/src/ejabberd_http.erl b/src/ejabberd_http.erl
index c5b5758ae..162d5ac73 100644
--- a/src/ejabberd_http.erl
+++ b/src/ejabberd_http.erl
@@ -65,6 +65,7 @@
request_tp,
request_headers = [],
end_of_request = false,
+ options = [],
default_host,
trail = <<>>
}).
@@ -133,6 +134,10 @@ init({SockMod, Socket}, Opts) ->
true -> [{[<<"http-poll">>], ejabberd_http_poll}];
false -> []
end,
+ XMLRPC = case proplists:get_bool(xmlrpc, Opts) of
+ true -> [{[], ejabberd_xmlrpc}];
+ false -> []
+ end,
DefinedHandlers = gen_mod:get_opt(
request_handlers, Opts,
fun(Hs) ->
@@ -141,7 +146,7 @@ init({SockMod, Socket}, Opts) ->
Mod} || {Path, Mod} <- Hs]
end, []),
RequestHandlers = DefinedHandlers ++ Captcha ++ Register ++
- Admin ++ Bind ++ Poll,
+ Admin ++ Bind ++ Poll ++ XMLRPC,
?DEBUG("S: ~p~n", [RequestHandlers]),
DefaultHost = gen_mod:get_opt(default_host, Opts, fun(A) -> A end, undefined),
@@ -150,6 +155,7 @@ init({SockMod, Socket}, Opts) ->
State = #state{sockmod = SockMod1,
socket = Socket1,
default_host = DefaultHost,
+ options = Opts,
request_handlers = RequestHandlers},
receive_headers(State).
@@ -359,7 +365,7 @@ process(Handlers, Request) ->
false -> process(HandlersLeft, Request)
end.
-process_request(#state{request_method = Method,
+process_request(#state{request_method = Method, options = Options,
request_path = {abs_path, Path}, request_auth = Auth,
request_lang = Lang, request_handlers = RequestHandlers,
request_host = Host, request_port = Port,
@@ -389,6 +395,7 @@ process_request(#state{request_method = Method,
IP = analyze_ip_xff(IPHere, XFF, Host),
Request = #request{method = Method,
path = LPath,
+ opts = Options,
q = LQuery,
auth = Auth,
lang = Lang,
@@ -413,7 +420,7 @@ process_request(#state{request_method = Method,
make_text_output(State, Status, Headers, Output)
end
end;
-process_request(#state{request_method = Method,
+process_request(#state{request_method = Method, options = Options,
request_path = {abs_path, Path}, request_auth = Auth,
request_content_length = Len, request_lang = Lang,
sockmod = SockMod, socket = Socket, request_host = Host,
@@ -450,6 +457,7 @@ process_request(#state{request_method = Method,
Request = #request{method = Method,
path = LPath,
q = LQuery,
+ opts = Options,
auth = Auth,
data = Data,
lang = Lang,
diff --git a/src/ejabberd_listener.erl b/src/ejabberd_listener.erl
index d2dc0fb73..515cf7348 100644
--- a/src/ejabberd_listener.erl
+++ b/src/ejabberd_listener.erl
@@ -201,11 +201,7 @@ listen_tcp(PortIP, Module, SockOpts, Port, IPS) ->
catch
_:_ -> []
end,
- DeliverAs = case Module of
- ejabberd_xmlrpc -> list;
- _ -> binary
- end,
- Res = gen_tcp:listen(Port, [DeliverAs,
+ Res = gen_tcp:listen(Port, [binary,
{packet, 0},
{active, false},
{reuseaddr, true},
diff --git a/src/ejabberd_xmlrpc.erl b/src/ejabberd_xmlrpc.erl
index a289196a3..c393cbe4b 100644
--- a/src/ejabberd_xmlrpc.erl
+++ b/src/ejabberd_xmlrpc.erl
@@ -17,11 +17,12 @@
-author('badlop@process-one.net').
--export([start/2, handler/2, socket_type/0, transform_listen_option/2]).
+-export([start/2, handler/2, process/2, socket_type/0,
+ transform_listen_option/2]).
-include("ejabberd.hrl").
-include("logger.hrl").
-
+-include("ejabberd_http.hrl").
-include("mod_roster.hrl").
-include("jlib.hrl").
@@ -170,12 +171,14 @@
%% -----------------------------
start({gen_tcp = _SockMod, Socket}, Opts) ->
- %MaxSessions = gen_mod:get_opt(maxsessions, Opts,
- % fun(I) when is_integer(I), I>0 -> I end,
- % 10),
- Timeout = gen_mod:get_opt(timeout, Opts,
- fun(I) when is_integer(I), I>0 -> I end,
- 5000),
+ ejabberd_http:start({gen_tcp, Socket}, [{xmlrpc, true}|Opts]).
+
+socket_type() -> raw.
+
+%% -----------------------------
+%% HTTP interface
+%% -----------------------------
+process(_, #request{method = 'POST', data = Data, opts = Opts}) ->
AccessCommandsOpts = gen_mod:get_opt(access_commands, Opts,
fun(L) when is_list(L) -> L end,
[]),
@@ -201,19 +204,28 @@ start({gen_tcp = _SockMod, Socket}, Opts) ->
[?MODULE, Wrong]),
[]
end, AccessCommandsOpts),
- GetAuth = case [ACom
- || {Ac, _, _} = ACom <- AccessCommands, Ac /= all]
- of
- [] -> false;
- _ -> true
+ GetAuth = case [ACom || {Ac, _, _} = ACom <- AccessCommands, Ac /= all] of
+ [] -> false;
+ _ -> true
end,
- Handler = {?MODULE, handler},
- State = #state{access_commands = AccessCommands,
- get_auth = GetAuth},
- Pid = proc_lib:spawn(xmlrpc_http, handler, [Socket, Timeout, Handler, State]),
- {ok, Pid}.
-
-socket_type() -> raw.
+ State = #state{access_commands = AccessCommands, get_auth = GetAuth},
+ case xmlrpc_decode:payload(Data) of
+ {error, _} = Err ->
+ ?ERROR_MSG("XML-RPC request ~s failed with reason: ~p",
+ [Data, Err]),
+ {400, [],
+ #xmlel{name = <<"h1">>, attrs = [],
+ children = [{xmlcdata, <<"Malformed Request">>}]}};
+ {ok, RPC} ->
+ ?DEBUG("got XML-RPC request: ~p", [RPC]),
+ {false, Result} = handler(State, RPC),
+ {ok, XML} = xmlrpc_encode:payload(Result),
+ {200, [], [{<<"Content-Type">>, <<"text/xml">>}], XML}
+ end;
+process(_, _) ->
+ {400, [],
+ #xmlel{name = <<"h1">>, attrs = [],
+ children = [{xmlcdata, <<"400 Bad Request">>}]}}.
%% -----------------------------
%% Access verification