]> granicus.if.org Git - ejabberd/commitdiff
* src/ejabberd_frontend_socket.erl: Support for frontend
authorAlexey Shchepin <alexey@process-one.net>
Sun, 1 Oct 2006 01:53:37 +0000 (01:53 +0000)
committerAlexey Shchepin <alexey@process-one.net>
Sun, 1 Oct 2006 01:53:37 +0000 (01:53 +0000)
connection manager
* src/ejabberd_c2s.erl: Likewise
* src/ejabberd_listener.erl: Likewise
* src/ejabberd_s2s_in.erl: Likewise
* src/ejabberd_service.erl: Likewise
* src/ejabberd_socket.erl: Likewise
* src/web/ejabberd_http_poll.erl: Likewise

SVN Revision: 657

ChangeLog
src/ejabberd_c2s.erl
src/ejabberd_frontend_socket.erl [new file with mode: 0644]
src/ejabberd_listener.erl
src/ejabberd_s2s_in.erl
src/ejabberd_service.erl
src/ejabberd_socket.erl
src/web/ejabberd_http_poll.erl

index a763bff4322a76946a53040537924584012f59e0..5f468dabc5c0f5b44bbc9e3a35a1eeefc08b3ab3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2006-10-01  Alexey Shchepin  <alexey@sevcom.net>
+
+       * src/ejabberd_frontend_socket.erl: Support for frontend
+       connection manager
+       * src/ejabberd_c2s.erl: Likewise
+       * src/ejabberd_listener.erl: Likewise
+       * src/ejabberd_s2s_in.erl: Likewise
+       * src/ejabberd_service.erl: Likewise
+       * src/ejabberd_socket.erl: Likewise
+       * src/web/ejabberd_http_poll.erl: Likewise
+
 2006-09-27  Mickael Remond  <mickael.remond@process-one.net>
 
        * doc/release_notes_1.1.2.txt: Minor fixes.
index a9e0d01ef1899ae24b2ccee4028c9c0c8141a621..5c05d863a1552f29e7b78ab16c83cf8de0607c03 100644 (file)
@@ -41,6 +41,7 @@
 -define(SETS, gb_sets).
 
 -record(state, {socket,
+               sockmod,
                streamid,
                sasl_state,
                access,
@@ -117,7 +118,7 @@ get_presence(FsmRef) ->
 %%          ignore                              |
 %%          {stop, StopReason}                   
 %%----------------------------------------------------------------------
-init([Socket, Opts]) ->
+init([{SockMod, Socket}, Opts]) ->
     Access = case lists:keysearch(access, 1, Opts) of
                 {value, {_, A}} -> A;
                 _ -> all
@@ -137,11 +138,12 @@ init([Socket, Opts]) ->
     Socket1 =
        if
            TLSEnabled ->
-               ejabberd_socket:starttls(Socket, TLSOpts);
+               SockMod:starttls(Socket, TLSOpts);
            true ->
                Socket
        end,
     {ok, wait_for_stream, #state{socket       = Socket1,
+                                sockmod      = SockMod,
                                 zlib         = Zlib,
                                 tls          = TLS,
                                 tls_required = StartTLSRequired,
@@ -198,8 +200,9 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
                                                      {xmlelement, "mechanism", [],
                                                       [{xmlcdata, S}]}
                                              end, cyrsasl:listmech(Server)),
-                                   SockMod = ejabberd_socket:get_sockmod(
-                                               StateData#state.socket),
+                                   SockMod =
+                                       (StateData#state.sockmod):get_sockmod(
+                                         StateData#state.socket),
                                    Zlib = StateData#state.zlib,
                                    CompressFeature =
                                        case Zlib andalso
@@ -453,7 +456,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
     TLS = StateData#state.tls,
     TLSEnabled = StateData#state.tls_enabled,
     TLSRequired = StateData#state.tls_required,
-    SockMod = ejabberd_socket:get_sockmod(StateData#state.socket),
+    SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket),
     case {xml:get_attr_s("xmlns", Attrs), Name} of
        {?NS_SASL, "auth"} when not ((SockMod == gen_tcp) and TLSRequired) ->
            Mech = xml:get_attr_s("mechanism", Attrs),
@@ -462,7 +465,8 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
                                      Mech,
                                      ClientIn) of
                {ok, Props} ->
-                   ejabberd_socket:reset_stream(StateData#state.socket),
+                   (StateData#state.sockmod):reset_stream(
+                     StateData#state.socket),
                    send_element(StateData,
                                 {xmlelement, "success",
                                  [{"xmlns", ?NS_SASL}], []}),
@@ -502,9 +506,10 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
                                 certfile, 1, StateData#state.tls_options)]
                      end,
            Socket = StateData#state.socket,
-           TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
-           send_element(StateData,
-                        {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
+           TLSSocket = (StateData#state.sockmod):starttls(
+                         Socket, TLSOpts,
+                         xml:element_to_string(
+                           {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []})),
            {next_state, wait_for_stream,
             StateData#state{socket = TLSSocket,
                             streamid = new_id(),
@@ -523,10 +528,11 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
                    case xml:get_tag_cdata(Method) of
                        "zlib" ->
                            Socket = StateData#state.socket,
-                           ZlibSocket = ejabberd_socket:compress(Socket),
-                           send_element(StateData,
-                                        {xmlelement, "compressed",
-                                         [{"xmlns", ?NS_COMPRESS}], []}),
+                           ZlibSocket = (StateData#state.sockmod):compress(
+                                          Socket,
+                                          xml:element_to_string(
+                                            {xmlelement, "compressed",
+                                             [{"xmlns", ?NS_COMPRESS}], []})),
                            {next_state, wait_for_stream,
                             StateData#state{socket = ZlibSocket,
                                             streamid = new_id()
@@ -575,7 +581,8 @@ wait_for_sasl_response({xmlstreamelement, El}, StateData) ->
            case cyrsasl:server_step(StateData#state.sasl_state,
                                     ClientIn) of
                {ok, Props} ->
-                   ejabberd_socket:reset_stream(StateData#state.socket),
+                   (StateData#state.sockmod):reset_stream(
+                     StateData#state.socket),
                    send_element(StateData,
                                 {xmlelement, "success",
                                  [{"xmlns", ?NS_SASL}], []}),
@@ -1167,7 +1174,7 @@ terminate(_Reason, StateName, StateData) ->
        _ ->
            ok
     end,
-    ejabberd_socket:close(StateData#state.socket),
+    (StateData#state.sockmod):close(StateData#state.socket),
     ok.
 
 %%%----------------------------------------------------------------------
@@ -1177,11 +1184,11 @@ terminate(_Reason, StateName, StateData) ->
 change_shaper(StateData, JID) ->
     Shaper = acl:match_rule(StateData#state.server,
                            StateData#state.shaper, JID),
-    ejabberd_socket:change_shaper(StateData#state.socket, Shaper).
+    (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
 
 send_text(StateData, Text) ->
     ?DEBUG("Send XML on stream = ~p", [lists:flatten(Text)]),
-    ejabberd_socket:send(StateData#state.socket, Text).
+    (StateData#state.sockmod):send(StateData#state.socket, Text).
 
 send_element(StateData, El) ->
     send_text(StateData, xml:element_to_string(El)).
diff --git a/src/ejabberd_frontend_socket.erl b/src/ejabberd_frontend_socket.erl
new file mode 100644 (file)
index 0000000..c69fac5
--- /dev/null
@@ -0,0 +1,249 @@
+%%%-------------------------------------------------------------------
+%%% File    : ejabberd_frontend_socket.erl
+%%% Author  : Alexey Shchepin <alexey@process-one.net>
+%%% Purpose : Frontend socket with zlib and TLS support library
+%%% Created : 23 Aug 2006 by Alexey Shchepin <alex@alex.sevcom.net>
+%%% Id      : $Id$
+%%%----------------------------------------------------------------------
+
+-module(ejabberd_frontend_socket).
+-author('alexey@process-one.net').
+
+-behaviour(gen_server).
+
+%% API
+-export([start/4,
+        start_link/4,
+        %connect/3,
+        starttls/2,
+        starttls/3,
+        compress/1,
+        compress/2,
+        reset_stream/1,
+        send/2,
+        change_shaper/2,
+        get_sockmod/1,
+        get_peer_certificate/1,
+        get_verify_result/1,
+        close/1]).
+
+%% gen_server callbacks
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
+        terminate/2, code_change/3]).
+
+-record(state, {sockmod, socket, receiver}).
+
+%%====================================================================
+%% API
+%%====================================================================
+%%--------------------------------------------------------------------
+%% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
+%% Description: Starts the server
+%%--------------------------------------------------------------------
+start_link(Module, SockMod, Socket, Opts) ->
+    gen_server:start_link(?MODULE,
+                         [Module, SockMod, Socket, Opts], []).
+
+start(Module, SockMod, Socket, Opts) ->
+    case Module:socket_type() of
+       xml_stream ->
+           MaxStanzaSize =
+               case lists:keysearch(max_stanza_size, 1, Opts) of
+                   {value, {_, Size}} -> Size;
+                   _ -> infinity
+               end,
+           Receiver = ejabberd_receiver:start(Socket, SockMod, none, MaxStanzaSize),
+           case SockMod:controlling_process(Socket, Receiver) of
+               ok ->
+                   ok;
+               {error, _Reason} ->
+                   SockMod:close(Socket)
+           end,
+           gen_server:start(?MODULE,
+                            [Module, SockMod, Socket, Opts, Receiver], []);
+       raw ->
+           %{ok, Pid} = Module:start({SockMod, Socket}, Opts),
+           %case SockMod:controlling_process(Socket, Pid) of
+           %    ok ->
+           %        ok;
+           %    {error, _Reason} ->
+           %        SockMod:close(Socket)
+           %end
+           todo
+    end.
+
+starttls(FsmRef, TLSOpts) ->
+    gen_server:call(FsmRef, {starttls, TLSOpts}),
+    FsmRef.
+
+starttls(FsmRef, TLSOpts, Data) ->
+    gen_server:call(FsmRef, {starttls, TLSOpts, Data}),
+    FsmRef.
+
+compress(FsmRef) ->
+    gen_server:call(FsmRef, compress),
+    FsmRef.
+
+compress(FsmRef, Data) ->
+    gen_server:call(FsmRef, {compress, Data}),
+    FsmRef.
+
+reset_stream(FsmRef) ->
+    gen_server:call(FsmRef, reset_stream).
+
+send(FsmRef, Data) ->
+    gen_server:call(FsmRef, {send, Data}).
+
+change_shaper(FsmRef, Shaper) ->
+    gen_server:call(FsmRef, {change_shaper, Shaper}).
+
+get_sockmod(FsmRef) ->
+    gen_server:call(FsmRef, get_sockmod).
+
+get_peer_certificate(FsmRef) ->
+    gen_server:call(FsmRef, get_peer_certificate).
+
+get_verify_result(FsmRef) ->
+    gen_server:call(FsmRef, get_verify_result).
+
+close(FsmRef) ->
+    gen_server:call(FsmRef, close).
+
+
+%%====================================================================
+%% gen_server callbacks
+%%====================================================================
+
+%%--------------------------------------------------------------------
+%% Function: init(Args) -> {ok, State} |
+%%                         {ok, State, Timeout} |
+%%                         ignore               |
+%%                         {stop, Reason}
+%% Description: Initiates the server
+%%--------------------------------------------------------------------
+init([Module, SockMod, Socket, Opts, Receiver]) ->
+    Nodes = mnesia:table_info(schema, disc_copies),
+    Node = lists:nth(erlang:phash(now(), length(Nodes)), Nodes),
+    {ok, Pid} =
+       rpc:call(Node, Module, start, [{?MODULE, self()}, Opts]),
+    ejabberd_receiver:become_controller(Receiver, Pid),
+    {ok, #state{sockmod = SockMod,
+               socket = Socket,
+               receiver = Receiver}}.
+
+%%--------------------------------------------------------------------
+%% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
+%%                                      {reply, Reply, State, Timeout} |
+%%                                      {noreply, State} |
+%%                                      {noreply, State, Timeout} |
+%%                                      {stop, Reason, Reply, State} |
+%%                                      {stop, Reason, State}
+%% Description: Handling call messages
+%%--------------------------------------------------------------------
+handle_call({starttls, TLSOpts}, _From, State) ->
+    {ok, TLSSocket} = tls:tcp_to_tls(State#state.socket, TLSOpts),
+    ejabberd_receiver:starttls(State#state.receiver, TLSSocket),
+    Reply = ok,
+    {reply, Reply, State#state{socket = TLSSocket, sockmod = tls}};
+
+handle_call({starttls, TLSOpts, Data}, _From, State) ->
+    {ok, TLSSocket} = tls:tcp_to_tls(State#state.socket, TLSOpts),
+    ejabberd_receiver:starttls(State#state.receiver, TLSSocket),
+    catch (State#state.sockmod):send(
+           State#state.socket, Data),
+    Reply = ok,
+    {reply, Reply, State#state{socket = TLSSocket, sockmod = tls}};
+
+handle_call(compress, _From, State) ->
+    {ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
+                        State#state.sockmod,
+                        State#state.socket),
+    ejabberd_receiver:compress(State#state.receiver, ZlibSocket),
+    Reply = ok,
+    {reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib}};
+
+handle_call({compress, Data}, _From, State) ->
+    {ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
+                        State#state.sockmod,
+                        State#state.socket),
+    ejabberd_receiver:compress(State#state.receiver, ZlibSocket),
+    catch (State#state.sockmod):send(
+           State#state.socket, Data),
+    Reply = ok,
+    {reply, Reply, State#state{socket = ZlibSocket, sockmod = ejabberd_zlib}};
+
+handle_call(reset_stream, _From, State) ->
+    ejabberd_receiver:reset_stream(State#state.receiver),
+    Reply = ok,
+    {reply, Reply, State};
+
+handle_call({send, Data}, _From, State) ->
+    catch (State#state.sockmod):send(
+           State#state.socket, Data),
+    Reply = ok,
+    {reply, Reply, State};
+
+handle_call({change_shaper, Shaper}, _From, State) ->
+    ejabberd_receiver:change_shaper(State#state.receiver, Shaper),
+    Reply = ok,
+    {reply, Reply, State};
+
+handle_call(get_sockmod, _From, State) ->
+    Reply = State#state.sockmod,
+    {reply, Reply, State};
+
+handle_call(get_peer_certificate, _From, State) ->
+    Reply = tls:get_peer_certificate(State#state.socket),
+    {reply, Reply, State};
+
+handle_call(get_verify_result, _From, State) ->
+    Reply = tls:get_verify_result(State#state.socket),
+    {reply, Reply, State};
+
+handle_call(close, _From, State) ->
+    ejabberd_receiver:close(State#state.receiver),
+    Reply = ok,
+    {stop, normal, Reply, State};
+
+handle_call(_Request, _From, State) ->
+    Reply = ok,
+    {reply, Reply, State}.
+
+%%--------------------------------------------------------------------
+%% Function: handle_cast(Msg, State) -> {noreply, State} |
+%%                                      {noreply, State, Timeout} |
+%%                                      {stop, Reason, State}
+%% Description: Handling cast messages
+%%--------------------------------------------------------------------
+handle_cast(_Msg, State) ->
+    {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% Function: handle_info(Info, State) -> {noreply, State} |
+%%                                       {noreply, State, Timeout} |
+%%                                       {stop, Reason, State}
+%% Description: Handling all non call/cast messages
+%%--------------------------------------------------------------------
+handle_info(_Info, State) ->
+    {noreply, State}.
+
+%%--------------------------------------------------------------------
+%% Function: terminate(Reason, State) -> void()
+%% Description: This function is called by a gen_server when it is about to
+%% terminate. It should be the opposite of Module:init/1 and do any necessary
+%% cleaning up. When it returns, the gen_server terminates with Reason.
+%% The return value is ignored.
+%%--------------------------------------------------------------------
+terminate(_Reason, _State) ->
+    ok.
+
+%%--------------------------------------------------------------------
+%% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
+%% Description: Convert process state when code is changed
+%%--------------------------------------------------------------------
+code_change(_OldVsn, State, _Extra) ->
+    {ok, State}.
+
+%%--------------------------------------------------------------------
+%%% Internal functions
+%%--------------------------------------------------------------------
index 8bc16842194f10428b3b0614aa813c7f52f61f13..4a4a39b476aed0a19e6c381d69ac91ee708a2dd7 100644 (file)
@@ -93,9 +93,8 @@ accept(ListenSocket, Module, Opts) ->
                    ok
            end,
            case Module of
-               ejabberd_http ->
-                   {ok, Pid} = Module:start({gen_tcp, Socket}, Opts),
-                   catch gen_tcp:controlling_process(Socket, Pid);
+               {frontend, Mod} ->
+                   ejabberd_frontend_socket:start(Mod, gen_tcp, Socket, Opts);
                _ ->
                    ejabberd_socket:start(Module, gen_tcp, Socket, Opts)
            end,
index 64a85fc1ca85d6f52a0b08ee369d04f9badcd390..b5f89c95b75e9df3d141b076dd20b0a09d6041ca 100644 (file)
@@ -37,6 +37,7 @@
 -define(DICT, dict).
 
 -record(state, {socket,
+               sockmod,
                streamid,
                shaper,
                tls = false,
@@ -99,7 +100,7 @@ socket_type() ->
 %%          ignore                              |
 %%          {stop, StopReason}                   
 %%----------------------------------------------------------------------
-init([Socket, Opts]) ->
+init([{SockMod, Socket}, Opts]) ->
     ?INFO_MSG("started: ~p", [Socket]),
     Shaper = case lists:keysearch(shaper, 1, Opts) of
                 {value, {_, S}} -> S;
@@ -120,6 +121,7 @@ init([Socket, Opts]) ->
     Timer = erlang:start_timer(?S2STIMEOUT, self(), []),
     {ok, wait_for_stream,
      #state{socket = Socket,
+           sockmod = SockMod,
            streamid = new_id(),
            shaper = Shaper,
            tls = StartTLS,
@@ -144,10 +146,10 @@ wait_for_stream({xmlstreamstart, _Name, Attrs}, StateData) ->
            SASL =
                if
                    StateData#state.tls_enabled ->
-                       case ejabberd_socket:get_peer_certificate(
+                       case (StateData#state.sockmod):get_peer_certificate(
                               StateData#state.socket) of
                            {ok, _Cert} ->
-                               case ejabberd_socket:get_verify_result(
+                               case (StateData#state.sockmod):get_verify_result(
                                       StateData#state.socket) of
                                    0 ->
                                        [{xmlelement, "mechanisms",
@@ -204,7 +206,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
     {xmlelement, Name, Attrs, Els} = El,
     TLS = StateData#state.tls,
     TLSEnabled = StateData#state.tls_enabled,
-    SockMod = ejabberd_socket:get_sockmod(StateData#state.socket),
+    SockMod = (StateData#state.sockmod):get_sockmod(StateData#state.socket),
     case {xml:get_attr_s("xmlns", Attrs), Name} of
        {?NS_TLS, "starttls"} when TLS == true,
                                   TLSEnabled == false,
@@ -212,9 +214,10 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
            ?INFO_MSG("starttls", []),
            Socket = StateData#state.socket,
            TLSOpts = StateData#state.tls_options,
-           TLSSocket = ejabberd_socket:starttls(Socket, TLSOpts),
-           send_element(StateData,
-                        {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []}),
+           TLSSocket = (StateData#state.sockmod):starttls(
+                         Socket, TLSOpts,
+                         xml:element_to_string(
+                           {xmlelement, "proceed", [{"xmlns", ?NS_TLS}], []})),
            {next_state, wait_for_stream,
             StateData#state{socket = TLSSocket,
                             streamid = new_id(),
@@ -227,10 +230,10 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
                    Auth = jlib:decode_base64(xml:get_cdata(Els)),
                    AuthDomain = jlib:nameprep(Auth),
                    AuthRes =
-                       case ejabberd_socket:get_peer_certificate(
+                       case (StateData#state.sockmod):get_peer_certificate(
                               StateData#state.socket) of
                            {ok, Cert} ->
-                               case ejabberd_socket:get_verify_result(
+                               case (StateData#state.sockmod):get_verify_result(
                                       StateData#state.socket) of
                                    0 ->
                                        case AuthDomain of
@@ -256,7 +259,7 @@ wait_for_feature_request({xmlstreamelement, El}, StateData) ->
                        end,
                    if
                        AuthRes ->
-                           ejabberd_socket:reset_stream(
+                           (StateData#state.sockmod):reset_stream(
                              StateData#state.socket),
                            send_element(StateData,
                                         {xmlelement, "success",
@@ -500,7 +503,7 @@ handle_info(_, StateName, StateData) ->
 %%----------------------------------------------------------------------
 terminate(Reason, _StateName, StateData) ->
     ?INFO_MSG("terminated: ~p", [Reason]),
-    ejabberd_socket:close(StateData#state.socket),
+    (StateData#state.sockmod):close(StateData#state.socket),
     ok.
 
 %%%----------------------------------------------------------------------
@@ -508,7 +511,7 @@ terminate(Reason, _StateName, StateData) ->
 %%%----------------------------------------------------------------------
 
 send_text(StateData, Text) ->
-    ejabberd_socket:send(StateData#state.socket, Text).
+    (StateData#state.sockmod):send(StateData#state.socket, Text).
 
 send_element(StateData, El) ->
     send_text(StateData, xml:element_to_string(El)).
@@ -516,7 +519,7 @@ send_element(StateData, El) ->
 
 change_shaper(StateData, Host, JID) ->
     Shaper = acl:match_rule(Host, StateData#state.shaper, JID),
-    ejabberd_socket:change_shaper(StateData#state.socket, Shaper).
+    (StateData#state.sockmod):change_shaper(StateData#state.socket, Shaper).
 
 
 new_id() ->
index 925915aa96a07984ad78c56a2e3b54a2d25debe4..dbc5c1682a2215aa7eaf23c9c48a574556ef2766 100644 (file)
@@ -33,7 +33,7 @@
 -include("ejabberd.hrl").
 -include("jlib.hrl").
 
--record(state, {socket, streamid,
+-record(state, {socket, sockmod, streamid,
                hosts, password, access}).
 
 %-define(DBGFSM, true).
@@ -93,7 +93,7 @@ socket_type() ->
 %%          ignore                              |
 %%          {stop, StopReason}                   
 %%----------------------------------------------------------------------
-init([Socket, Opts]) ->
+init([{SockMod, Socket}, Opts]) ->
     Access = case lists:keysearch(access, 1, Opts) of
                 {value, {_, A}} -> A;
                 _ -> all
@@ -124,6 +124,7 @@ init([Socket, Opts]) ->
                end
        end,
     {ok, wait_for_stream, #state{socket = Socket,
+                                sockmod = SockMod,
                                 streamid = new_id(),
                                 hosts = Hosts,
                                 password = Password,
@@ -319,7 +320,7 @@ terminate(Reason, StateName, StateData) ->
        _ ->
            ok
     end,
-    ejabberd_socket:close(StateData#state.socket),
+    (StateData#state.sockmod):close(StateData#state.socket),
     ok.
 
 %%%----------------------------------------------------------------------
@@ -327,7 +328,7 @@ terminate(Reason, StateName, StateData) ->
 %%%----------------------------------------------------------------------
 
 send_text(StateData, Text) ->
-    ejabberd_socket:send(StateData#state.socket, Text).
+    (StateData#state.sockmod):send(StateData#state.socket, Text).
 
 send_element(StateData, El) ->
     send_text(StateData, xml:element_to_string(El)).
index 9b02188030f8ec49db9fd2581760ae867919424b..ba7a24f604e2396a477553e6b639a1715939e42d 100644 (file)
@@ -13,7 +13,9 @@
 -export([start/4,
         connect/3,
         starttls/2,
+        starttls/3,
         compress/1,
+        compress/2,
         reset_stream/1,
         send/2,
         change_shaper/2,
@@ -43,7 +45,7 @@ start(Module, SockMod, Socket, Opts) ->
            SocketData = #socket_state{sockmod = SockMod,
                                       socket = Socket,
                                       receiver = Receiver},
-           {ok, Pid} = Module:start(SocketData, Opts),
+           {ok, Pid} = Module:start({?MODULE, SocketData}, Opts),
            case SockMod:controlling_process(Socket, Receiver) of
                ok ->
                    ok;
@@ -58,8 +60,7 @@ start(Module, SockMod, Socket, Opts) ->
                    ok;
                {error, _Reason} ->
                    SockMod:close(Socket)
-           end,
-           ejabberd_receiver:become_controller(Pid)
+           end
     end.
 
 connect(Addr, Port, Opts) ->
@@ -87,6 +88,12 @@ starttls(SocketData, TLSOpts) ->
     ejabberd_receiver:starttls(SocketData#socket_state.receiver, TLSSocket),
     SocketData#socket_state{socket = TLSSocket, sockmod = tls}.
 
+starttls(SocketData, TLSOpts, Data) ->
+    {ok, TLSSocket} = tls:tcp_to_tls(SocketData#socket_state.socket, TLSOpts),
+    ejabberd_receiver:starttls(SocketData#socket_state.receiver, TLSSocket),
+    send(SocketData, Data),
+    SocketData#socket_state{socket = TLSSocket, sockmod = tls}.
+
 compress(SocketData) ->
     {ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
                         SocketData#socket_state.sockmod,
@@ -94,6 +101,14 @@ compress(SocketData) ->
     ejabberd_receiver:compress(SocketData#socket_state.receiver, ZlibSocket),
     SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}.
 
+compress(SocketData, Data) ->
+    {ok, ZlibSocket} = ejabberd_zlib:enable_zlib(
+                        SocketData#socket_state.sockmod,
+                        SocketData#socket_state.socket),
+    ejabberd_receiver:compress(SocketData#socket_state.receiver, ZlibSocket),
+    send(SocketData, Data),
+    SocketData#socket_state{socket = ZlibSocket, sockmod = ejabberd_zlib}.
+
 reset_stream(SocketData) ->
     ejabberd_receiver:reset_stream(SocketData#socket_state.receiver).
 
index dcd04123509f678c12d544175d359e17d7e7d050..8bdebbdea150740673bd15f8f907605ed12b632a 100644 (file)
@@ -71,7 +71,7 @@ send({http_poll, FsmRef}, Packet) ->
 setopts({http_poll, FsmRef}, Opts) ->
     case lists:member({active, once}, Opts) of
        true ->
-           gen_fsm:sync_send_all_state_event(FsmRef, activate);
+           gen_fsm:send_all_state_event(FsmRef, {activate, self()});
        _ ->
            ok
     end.
@@ -148,8 +148,9 @@ process_request(_Request) ->
 init([ID, Key]) ->
     ?INFO_MSG("started: ~p", [{ID, Key}]),
     Opts = [], % TODO
-    {ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_poll, self()}}, Opts),
-    ejabberd_c2s:become_controller(C2SPid),
+    ejabberd_socket:start(ejabberd_c2s, ?MODULE, {http_poll, self()}, Opts),
+    %{ok, C2SPid} = ejabberd_c2s:start({?MODULE, {http_poll, self()}}, Opts),
+    %ejabberd_c2s:become_controller(C2SPid),
     Timer = erlang:start_timer(?HTTP_POLL_TIMEOUT, self(), []),
     {ok, loop, #state{id = ID,
                      key = Key,
@@ -182,6 +183,20 @@ init([ID, Key]) ->
 %%          {next_state, NextStateName, NextStateData, Timeout} |
 %%          {stop, Reason, NewStateData}                         
 %%----------------------------------------------------------------------
+handle_event({activate, From}, StateName, StateData) ->
+    case StateData#state.input of
+       "" ->
+           {next_state, StateName,
+            StateData#state{waiting_input = {From, ok}}};
+       Input ->
+            {Receiver, _Tag} = From,
+           Receiver ! {tcp, {http_poll, self()}, list_to_binary(Input)},
+           {next_state, StateName, StateData#state{input = "",
+                                                   waiting_input = false,
+                                                   last_receiver = From
+                                                  }}
+    end;
+
 handle_event(Event, StateName, StateData) ->
     {next_state, StateName, StateData}.
 
@@ -199,19 +214,6 @@ handle_sync_event({send, Packet}, From, StateName, StateData) ->
     Reply = ok,
     {reply, Reply, StateName, StateData#state{output = Output}};
 
-handle_sync_event(activate, From, StateName, StateData) ->
-    case StateData#state.input of
-       "" ->
-           {reply, ok, StateName, StateData#state{waiting_input = From}};
-       Input ->
-            {Receiver, _Tag} = From,
-           Receiver ! {tcp, {http_poll, self()}, list_to_binary(Input)},
-           {reply, ok, StateName, StateData#state{input = "",
-                                                  waiting_input = false,
-                                                  last_receiver = From
-                                                 }}
-    end;
-
 handle_sync_event(stop, From, StateName, StateData) ->
     Reply = ok,
     {stop, normal, Reply, StateData};