]> granicus.if.org Git - ejabberd/commitdiff
Process XML-RPC requests via p1_xml and ejabberd_http
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Fri, 3 Oct 2014 14:53:55 +0000 (18:53 +0400)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Sat, 4 Oct 2014 08:49:12 +0000 (12:49 +0400)
include/ejabberd_http.hrl
rebar.config.script
src/ejabberd_http.erl
src/ejabberd_listener.erl
src/ejabberd_xmlrpc.erl

index 73f5aa960fd3bdb8f8c0acfb36f8a59a91b22117..fd956f08e064bb87f50f87c95beca979477beda3 100644 (file)
@@ -31,5 +31,6 @@
         host = <<"">>     :: binary(),
         port = 5280       :: inet:port_number(),
         tp = http, %         :: protocol(),
+        opts = []         :: list(),
         headers = []      :: [{atom() | binary(), binary()}]}).
 
index e1186a03714cd513805cef7bb4e9ede66ff917a8..4e2d347ff66111d4924356d2a59f284ed8c9d961 100644 (file)
@@ -56,7 +56,7 @@ Deps = [{p1_cache_tab, ".*", {git, "git://github.com/processone/cache_tab"}},
        {esip, ".*", {git, "git://github.com/processone/p1_sip"}},
        {p1_stun, ".*", {git, "git://github.com/processone/stun"}},
         {p1_yaml, ".*", {git, "git://github.com/processone/p1_yaml"}},
-        {xmlrpc, ".*", {git, "git://github.com/rds13/xmlrpc"}},
+        {ehyperloglog, ".*", {git, "https://github.com/vaxelfel/eHyperLogLog.git"}},
         {p1_utils, ".*", {git, "git://github.com/processone/p1_utils"}}],
 
 ConfigureCmd = fun(Pkg, Flags) ->
index c5b5758aee7f45789f391750b58e41632d6cdd28..162d5ac7349c9a844a4849554ba2b384385b91bb 100644 (file)
@@ -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,
index d2dc0fb739f3bdf5f10e27cd7c1a4658414a8d8d..515cf73488764b99885f8bfd22723f1330c83d4c 100644 (file)
@@ -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},
index a289196a3442f0c92eb3f7765c2dd8540aceadcb..c393cbe4b9521abcd38b04123632d57ddd1b0d10 100644 (file)
 
 -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").
 %% -----------------------------
 
 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