Merge 0.9->0.10
[prosody.git] / net / server_event.lua
index dc48e338b21e3997098b25c17a7d3e3c3685fa4f..756e9837b43c7ffa13de2c2ba1c6fe03916519f6 100644 (file)
@@ -115,10 +115,10 @@ end )( )
 local interface_mt
 do
        interface_mt = {}; interface_mt.__index = interface_mt;
-       
+
        local addevent = base.addevent
        local coroutine_wrap, coroutine_yield = coroutine.wrap,coroutine.yield
-       
+
        -- Private methods
        function interface_mt:_position(new_position)
                        self.position = new_position or self.position
@@ -127,7 +127,7 @@ do
        function interface_mt:_close()
                return self:_destroy();
        end
-       
+
        function interface_mt:_start_connection(plainssl) -- should be called from addclient
                        local callback = function( event )
                                if EV_TIMEOUT == event then  -- timeout during connection
@@ -268,12 +268,12 @@ do
                        interfacelist( "delete", self )
                        return true
        end
-       
+
        function interface_mt:_lock(nointerface, noreading, nowriting)  -- lock or unlock this interface or events
                        self.nointerface, self.noreading, self.nowriting = nointerface, noreading, nowriting
                        return nointerface, noreading, nowriting
        end
-       
+
        --TODO: Deprecate
        function interface_mt:lock_read(switch)
                if switch then
@@ -300,7 +300,7 @@ do
                end
                return self._connections
        end
-       
+
        -- Public methods
        function interface_mt:write(data)
                if self.nowriting then return nil, "locked" end
@@ -343,43 +343,44 @@ do
                        return true
                end
        end
-       
+
        function interface_mt:socket()
                return self.conn
        end
-       
+
        function interface_mt:server()
                return self._server or self;
        end
-       
+
        function interface_mt:port()
                return self._port
        end
-       
+
        function interface_mt:serverport()
                return self._serverport
        end
-       
+
        function interface_mt:ip()
                return self._ip
        end
-       
+
        function interface_mt:ssl()
                return self._usingssl
        end
+       interface_mt.clientport = interface_mt.port -- COMPAT server_select
 
        function interface_mt:type()
                return self._type or "client"
        end
-       
+
        function interface_mt:connections()
                return self._connections
        end
-       
+
        function interface_mt:address()
                return self.addr
        end
-       
+
        function interface_mt:set_sslctx(sslctx)
                self._sslctx = sslctx;
                if sslctx then
@@ -395,11 +396,11 @@ do
                end
                return self._pattern;
        end
-       
+
        function interface_mt:set_send(new_send)
                -- No-op, we always use the underlying connection's send
        end
-       
+
        function interface_mt:starttls(sslctx, call_onconnect)
                debug( "try to start ssl at client id:", self.id )
                local err
@@ -428,18 +429,20 @@ do
                self.starttls = false;
                return true
        end
-       
+
        function interface_mt:setoption(option, value)
                if self.conn.setoption then
                        return self.conn:setoption(option, value);
                end
                return false, "setoption not implemented";
        end
-       
+
        function interface_mt:setlistener(listener)
-               self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onreadtimeout, self.onstatus
-                       = listener.onconnect, listener.ondisconnect, listener.onincoming,
-                         listener.ontimeout, listener.onreadtimeout, listener.onstatus;
+               self:ondetach(); -- Notify listener that it is no longer responsible for this connection
+               self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout,
+               self.onreadtimeout, self.onstatus, self.ondetach
+                       = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout,
+                         listener.onreadtimeout, listener.onstatus, listener.ondetach;
        end
 
        -- Stub handlers
@@ -459,6 +462,8 @@ do
        end
        function interface_mt:ondrain()
        end
+       function interface_mt:ondetach()
+       end
        function interface_mt:onstatus()
        end
 end
@@ -485,6 +490,8 @@ do
                        onincoming = listener.onincoming;  -- will be called when client sends data
                        ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs
                        onreadtimeout = listener.onreadtimeout; -- called when socket inactivity timeout occurs
+                       ondrain = listener.ondrain; -- called when writebuffer is empty
+                       ondetach = listener.ondetach; -- called when disassociating this listener from this connection
                        onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS)
                        eventread = false, eventwrite = false, eventclose = false,
                        eventhandshake = false, eventstarthandshake = false;  -- event handler
@@ -498,7 +505,7 @@ do
                        noreading = false, nowriting = false;  -- locks of the read/writecallback
                        startsslcallback = false;  -- starting handshake callback
                        position = false;  -- position of client in interfacelist
-                       
+
                        -- Properties
                        _ip = ip, _port = port, _server = server, _pattern = pattern,
                        _serverport = (server and server:port() or nil),
@@ -574,7 +581,7 @@ do
                                end
                        end
                end
-               
+
                interface.readcallback = function( event )  -- called on read events
                        --vdebug( "new client read event, id/ip/port:", tostring(interface.id), tostring(ip), tostring(port) )
                        if interface.noreading or interface.fatalerror then  -- leave this event
@@ -647,7 +654,7 @@ do
                debug "creating server interface..."
                local interface = {
                        _connections = 0;
-                       
+
                        conn = server;
                        onconnect = listener.onconnect;  -- will be called when new client connected
                        eventread = false;  -- read event handler
@@ -655,7 +662,7 @@ do
                        readcallback = false; -- read event callback
                        fatalerror = false; -- error message
                        nointerface = true;  -- lock/unlock parameter
-                       
+
                        _ip = addr, _port = port, _pattern = pattern,
                        _sslctx = sslctx;
                }
@@ -694,12 +701,12 @@ do
                                        clientinterface:_start_session( true )
                                end
                                debug( "accepted incoming client connection from:", client_ip or "<unknown IP>", client_port or "<unknown port>", "to", port or "<unknown port>");
-                               
+
                                client, err = server:accept()    -- try to accept again
                        end
                        return EV_READ
                end
-               
+
                server:settimeout( 0 )
                setmetatable(interface, interface_mt)
                interfacelist( "add", interface )
@@ -742,7 +749,7 @@ do
                return interface, client
                --function handleclient( client, ip, port, server, pattern, listener, _, sslctx )  -- creates an client interface
        end
-       
+
        function addclient( addr, serverport, listener, pattern, localaddr, localport, sslcfg, startssl )
                local client, err = socket.tcp()  -- creating new socket
                if not client then
@@ -833,14 +840,14 @@ end
 
 local function link(sender, receiver, buffersize)
        local sender_locked;
-       
+
        function receiver:ondrain()
                if sender_locked then
                        sender:resume();
                        sender_locked = nil;
                end
        end
-       
+
        function sender:onincoming(data)
                receiver:write(data);
                if receiver.writebufferlen >= buffersize then
@@ -848,6 +855,7 @@ local function link(sender, receiver, buffersize)
                        sender:pause();
                end
        end
+       sender:set_mode("*a");
 end
 
 return {