aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMatthew Wild <mwild1@gmail.com>2012-07-28 01:14:31 +0100
committerMatthew Wild <mwild1@gmail.com>2012-07-28 01:14:31 +0100
commit81bef2c93b53e006cbeebdffc80040af6b4daf68 (patch)
tree2732225257e7b8ade28695dad7c0df3f7cea00b1 /net
parent8eec29745633bd84c2d325d42dbeeb4afd37d516 (diff)
parent47619af14cd24fcb48b4d2b4c4653f72b882087e (diff)
downloadprosody-81bef2c93b53e006cbeebdffc80040af6b4daf68.tar.gz
prosody-81bef2c93b53e006cbeebdffc80040af6b4daf68.zip
Merge with Florob
Diffstat (limited to 'net')
-rw-r--r--net/http.lua5
-rw-r--r--net/server_event.lua37
-rw-r--r--net/server_select.lua59
3 files changed, 44 insertions, 57 deletions
diff --git a/net/http.lua b/net/http.lua
index f2061e00..273eee09 100644
--- a/net/http.lua
+++ b/net/http.lua
@@ -7,7 +7,7 @@
--
local socket = require "socket"
-local mime = require "mime"
+local b64 = require "util.encodings".base64.encode;
local url = require "socket.url"
local httpstream_new = require "util.httpstream".new;
@@ -154,7 +154,7 @@ function request(u, ex, callback)
};
if req.userinfo then
- headers["Authorization"] = "Basic "..mime.b64(req.userinfo);
+ headers["Authorization"] = "Basic "..b64(req.userinfo);
end
if ex then
@@ -203,7 +203,6 @@ function destroy_request(request)
if request.conn then
request.conn = nil;
request.handler:close()
- listener.ondisconnect(request.handler, "closed");
end
end
diff --git a/net/server_event.lua b/net/server_event.lua
index 03a7708c..f2626f5f 100644
--- a/net/server_event.lua
+++ b/net/server_event.lua
@@ -33,8 +33,6 @@ local cfg = {
}
local function use(x) return rawget(_G, x); end
-local print = use "print"
-local pcall = use "pcall"
local ipairs = use "ipairs"
local string = use "string"
local select = use "select"
@@ -117,7 +115,6 @@ do
local addevent = base.addevent
local coroutine_wrap, coroutine_yield = coroutine.wrap,coroutine.yield
- local string_len = string.len
-- Private methods
function interface_mt:_position(new_position)
@@ -212,7 +209,6 @@ do
self:_lock( false, false, false ) -- unlock the interface; sending, closing etc allowed
self.send = self.conn.send -- caching table lookups with new client object
self.receive = self.conn.receive
- local onsomething
if not call_onconnect then -- trigger listener
self:onstatus("ssl-handshake-complete");
end
@@ -249,7 +245,7 @@ do
return true
end
function interface_mt:_destroy() -- close this interface + events and call last listener
- debug( "closing client with id:", self.id )
+ debug( "closing client with id:", self.id, self.fatalerror )
self:_lock( true, true, true ) -- first of all, lock the interface to avoid further actions
local _
_ = self.eventread and self.eventread:close( ) -- close events; this must be called outside of the event callbacks!
@@ -313,7 +309,7 @@ do
if self.nowriting then return nil, "locked" end
--vdebug( "try to send data to client, id/data:", self.id, data )
data = tostring( data )
- local len = string_len( data )
+ local len = #data
local total = len + self.writebufferlen
if total > cfg.MAX_SEND_LENGTH then -- check buffer length
local err = "send buffer exceeded"
@@ -328,22 +324,22 @@ do
end
return true
end
- function interface_mt:close(now)
+ function interface_mt:close()
if self.nointerface then return nil, "locked"; end
debug( "try to close client connection with id:", self.id )
if self.type == "client" then
self.fatalerror = "client to close"
- if ( not self.eventwrite ) or now then -- try to close immediately
- self:_lock( true, true, true )
- self:_close()
- return true
- else -- wait for incomplete write request
+ if self.eventwrite then -- wait for incomplete write request
self:_lock( true, true, false )
debug "closing delayed until writebuffer is empty"
return nil, "writebuffer not empty, waiting"
+ else -- close now
+ self:_lock( true, true, true )
+ self:_close()
+ return true
end
else
- debug( "try to close server with id:", tostring(self.id), "args:", tostring(now) )
+ debug( "try to close server with id:", tostring(self.id))
self.fatalerror = "server to close"
self:_lock( true )
self:_close( 0 ) -- add new event to remove the server interface
@@ -470,9 +466,7 @@ do
local string_sub = string.sub -- caching table lookups
local string_len = string.len
local addevent = base.addevent
- local coroutine_wrap = coroutine.wrap
local socket_gettime = socket.gettime
- local coroutine_yield = coroutine.yield
function handleclient( client, ip, port, server, pattern, listener, sslctx ) -- creates an client interface
--vdebug("creating client interfacce...")
local interface = {
@@ -602,16 +596,14 @@ do
end
local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern"
--vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) )
- buffer = buffer or part or ""
- local len = string_len( buffer )
- if len > cfg.MAX_READ_LENGTH then -- check buffer length
+ buffer = buffer or part
+ if buffer and #buffer > cfg.MAX_READ_LENGTH then -- check buffer length
interface.fatalerror = "receive buffer exceeded"
debug( "fatal error:", interface.fatalerror )
interface:_close()
interface.eventread = nil
return -1
end
- interface.onincoming( interface, buffer, err ) -- send new data to listener
if err and ( err ~= "timeout" and err ~= "wantread" ) then
if "wantwrite" == err then -- need to read on write event
if not interface.eventwrite then -- register new write event if needed
@@ -631,6 +623,8 @@ do
interface.eventread = nil
return -1
end
+ else
+ interface.onincoming( interface, buffer, err ) -- send new data to listener
end
if interface.noreading then
interface.eventread = nil;
@@ -742,7 +736,7 @@ end )( )
local addclient, wrapclient
do
- function wrapclient( client, ip, port, listeners, pattern, sslctx, startssl )
+ function wrapclient( client, ip, port, listeners, pattern, sslctx )
local interface = handleclient( client, ip, port, nil, pattern, listeners, sslctx )
interface:_start_connection(sslctx)
return interface, client
@@ -778,9 +772,6 @@ do
local res, err = client:connect( addr, serverport ) -- connect
if res or ( err == "timeout" ) then
local ip, port = client:getsockname( )
- local server = function( )
- return nil, "this is a dummy server interface"
- end
local interface = wrapclient( client, ip, serverport, listener, pattern, sslctx, startssl )
interface:_start_connection( startssl )
debug( "new connection id:", interface.id )
diff --git a/net/server_select.lua b/net/server_select.lua
index de637f70..9104dace 100644
--- a/net/server_select.lua
+++ b/net/server_select.lua
@@ -19,7 +19,6 @@ end
local log, table_concat = require ("util.logger").init("socket"), table.concat;
local out_put = function (...) return log("debug", table_concat{...}); end
local out_error = function (...) return log("warn", table_concat{...}); end
-local mem_free = collectgarbage
----------------------------------// DECLARATION //--
@@ -34,7 +33,6 @@ local pairs = use "pairs"
local ipairs = use "ipairs"
local tonumber = use "tonumber"
local tostring = use "tostring"
-local collectgarbage = use "collectgarbage"
--// lua libs //--
@@ -49,7 +47,6 @@ local os_difftime = os.difftime
local math_min = math.min
local math_huge = math.huge
local table_concat = table.concat
-local table_remove = table.remove
local string_len = string.len
local string_sub = string.sub
local coroutine_wrap = coroutine.wrap
@@ -67,7 +64,6 @@ local ssl_wrap = ( luasec and luasec.wrap )
local socket_bind = luasocket.bind
local socket_sleep = luasocket.sleep
local socket_select = luasocket.select
-local ssl_newcontext = ( luasec and luasec.newcontext )
--// functions //--
@@ -84,7 +80,6 @@ local getsettings
local closesocket
local removesocket
local removeserver
-local changetimeout
local wrapconnection
local changesettings
@@ -314,22 +309,28 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
end
return false, "setoption not implemented";
end
- handler.close = function( self, forced )
+ handler.force_close = function ( self, err )
+ if bufferqueuelen ~= 0 then
+ out_put("server.lua: discarding unwritten data for ", tostring(ip), ":", tostring(clientport))
+ for i = bufferqueuelen, 1, -1 do
+ bufferqueue[i] = nil;
+ end
+ bufferqueuelen = 0;
+ end
+ return self:close(err);
+ end
+ handler.close = function( self, err )
if not handler then return true; end
_readlistlen = removesocket( _readlist, socket, _readlistlen )
_readtimes[ handler ] = nil
if bufferqueuelen ~= 0 then
- if not ( forced or fatalerror ) then
- handler.sendbuffer( )
- if bufferqueuelen ~= 0 then -- try again...
- if handler then
- handler.write = nil -- ... but no further writing allowed
- end
- toclose = true
- return false
+ handler.sendbuffer() -- Try now to send any outstanding data
+ if bufferqueuelen ~= 0 then -- Still not empty, so we'll try again later
+ if handler then
+ handler.write = nil -- ... but no further writing allowed
end
- else
- send( socket, table_concat( bufferqueue, "", 1, bufferqueuelen ), 1, bufferlen ) -- forced send
+ toclose = true
+ return false
end
end
if socket then
@@ -347,7 +348,8 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
local _handler = handler;
handler = nil
if disconnect then
- disconnect(_handler, "closed");
+ disconnect(_handler, err or false);
+ disconnect = nil
end
end
if server then
@@ -450,8 +452,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
local buffer = buffer or part or ""
local len = string_len( buffer )
if len > maxreadlen then
- disconnect( handler, "receive buffer exceeded" )
- handler:close( true )
+ handler:close( "receive buffer exceeded" )
return false
end
local count = len * STAT_UNIT
@@ -463,14 +464,12 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
else -- connections was closed or fatal error
out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
fatalerror = true
- disconnect( handler, err )
- _ = handler and handler:close( )
+ _ = handler and handler:force_close( err )
return false
end
end
local _sendbuffer = function( ) -- this function sends data
local succ, err, byte, buffer, count;
- local count;
if socket then
buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
succ, err, byte = send( socket, buffer, 1, bufferlen )
@@ -480,7 +479,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
_ = _cleanqueue and clean( bufferqueue )
--out_put( "server.lua: sended '", buffer, "', bytes: ", tostring(succ), ", error: ", tostring(err), ", part: ", tostring(byte), ", to: ", tostring(ip), ":", tostring(clientport) )
else
- succ, err, count = false, "closed", 0;
+ succ, err, count = false, "unexpected close", 0;
end
if succ then -- sending succesful
bufferqueuelen = 0
@@ -491,7 +490,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
drain(handler)
end
_ = needtls and handler:starttls(nil)
- _ = toclose and handler:close( )
+ _ = toclose and handler:force_close( )
return true
elseif byte and ( err == "timeout" or err == "wantwrite" ) then -- want write
buffer = string_sub( buffer, byte + 1, bufferlen ) -- new buffer
@@ -503,8 +502,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
else -- connection was closed during sending or fatal error
out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " write error: ", tostring(err) )
fatalerror = true
- disconnect( handler, err )
- _ = handler and handler:close( )
+ _ = handler and handler:force_close( err )
return false
end
end
@@ -546,9 +544,8 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport
end
end
out_put( "server.lua: ssl handshake error: ", tostring(err or "handshake too long") )
- disconnect( handler, "ssl handshake failed" )
- _ = handler and handler:close( true ) -- forced disconnect
- return false, err -- handshake failed
+ _ = handler and handler:force_close("ssl handshake failed")
+ return false, err -- handshake failed
end
)
end
@@ -810,7 +807,7 @@ loop = function(once) -- this is the main loop of the program
end
for handler, err in pairs( _closelist ) do
handler.disconnect( )( handler, err )
- handler:close( true ) -- forced disconnect
+ handler:force_close() -- forced disconnect
end
clean( _closelist )
_currenttime = luasocket_gettime( )
@@ -896,7 +893,7 @@ addtimer( function( )
if os_difftime( _currenttime - timestamp ) > _sendtimeout then
--_writetimes[ handler ] = nil
handler.disconnect( )( handler, "send timeout" )
- handler:close( true ) -- forced disconnect
+ handler:force_close() -- forced disconnect
end
end
for handler, timestamp in pairs( _readtimes ) do