HANDSHAKE_TIMEOUT = 60, -- timeout in seconds per handshake attempt
MAX_READ_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes allowed to read from sockets
MAX_SEND_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes size of write buffer (for writing on sockets)
+ ACCEPT_QUEUE = 128, -- might influence the length of the pending sockets queue
ACCEPT_DELAY = 10, -- seconds to wait until the next attempt of a full server to accept
READ_TIMEOUT = 60 * 60 * 6, -- timeout in seconds for read data from socket
WRITE_TIMEOUT = 180, -- timeout in seconds for write data on socket
local coroutine = use "coroutine"
local setmetatable = use "setmetatable"
+local t_insert = table.insert
+local t_concat = table.concat
+
local ssl = use "ssl"
local socket = use "socket" or require "socket"
self.position = new_position or self.position
return self.position;
end
- function interface_mt:_close() -- regs event to start self:_destroy()
- local callback = function( )
- self:_destroy();
- self.eventclose = nil
- return -1
- end
- self.eventclose = addevent( base, nil, EV_TIMEOUT, callback, 0 )
- return true
+ function interface_mt:_close()
+ return self:_destroy();
end
function interface_mt:_start_connection(plainssl) -- should be called from addclient
function interface_mt:resume()
self:_lock(self.nointerface, false, self.nowriting);
- if not self.eventread then
+ if self.readcallback and not self.eventread then
self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback
+ return true;
end
end
debug( "error:", err ) -- to much, check your app
return nil, err
end
- self.writebuffer = self.writebuffer .. data -- new buffer
+ t_insert(self.writebuffer, data) -- new buffer
self.writebufferlen = total
if not self.eventwrite then -- register new write event
--vdebug( "register new write event" )
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:setlistener(listener)
- self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onstatus
- = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout, listener.onstatus;
+ self:ondetach(); -- Notify listener that it is no longer responsible for this connection
+ self.onconnect, self.ondisconnect, self.onincoming,
+ self.ontimeout, self.onstatus, self.ondetach
+ = listener.onconnect, listener.ondisconnect, listener.onincoming,
+ listener.ontimeout, listener.onstatus, listener.ondetach;
end
-- Stub handlers
end
function interface_mt:ondrain()
end
+ function interface_mt:ondetach()
+ end
function interface_mt:onstatus()
end
end
local handleclient;
do
local string_sub = string.sub -- caching table lookups
- local string_len = string.len
local addevent = base.addevent
local socket_gettime = socket.gettime
function handleclient( client, ip, port, server, pattern, listener, sslctx ) -- creates an client interface
type = "client";
conn = client;
currenttime = socket_gettime( ); -- safe the origin
- writebuffer = ""; -- writebuffer
+ writebuffer = {}; -- writebuffer
writebufferlen = 0; -- length of writebuffer
send = client.send; -- caching table lookups
receive = client.receive;
ondisconnect = listener.ondisconnect; -- will be called when client disconnects
onincoming = listener.onincoming; -- will be called when client sends data
ontimeout = listener.ontimeout; -- called when fatal socket 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
interface.eventwritetimeout = false
end
end
- local succ, err, byte = interface.conn:send( interface.writebuffer, 1, interface.writebufferlen )
+ interface.writebuffer = { t_concat(interface.writebuffer) }
+ local succ, err, byte = interface.conn:send( interface.writebuffer[1], 1, interface.writebufferlen )
--vdebug( "write data:", interface.writebuffer, "error:", err, "part:", byte )
if succ then -- writing succesful
- interface.writebuffer = ""
+ interface.writebuffer[1] = nil
interface.writebufferlen = 0
interface:ondrain();
if interface.fatalerror then
elseif interface.startsslcallback then -- start ssl connection if needed
debug "starting ssl handshake after writing"
interface.eventstarthandshake = addevent( base, nil, EV_TIMEOUT, interface.startsslcallback, 0 )
+ elseif interface.writebufferlen ~= 0 then
+ -- data possibly written from ondrain
+ return EV_WRITE, cfg.WRITE_TIMEOUT
elseif interface.eventreadtimeout then
- return EV_WRITE, EV_TIMEOUT
+ return EV_WRITE, cfg.WRITE_TIMEOUT
end
interface.eventwrite = nil
return -1
elseif byte and (err == "timeout" or err == "wantwrite") then -- want write again
--vdebug( "writebuffer is not empty:", err )
- interface.writebuffer = string_sub( interface.writebuffer, byte + 1, interface.writebufferlen ) -- new buffer
+ interface.writebuffer[1] = string_sub( interface.writebuffer[1], byte + 1, interface.writebufferlen ) -- new buffer
interface.writebufferlen = interface.writebufferlen - byte
if "wantread" == err then -- happens only with luasec
local callback = function( )
sender:pause();
end
end
+ sender:set_mode("*a");
end
return {