From 8e10516c29598fac76181c338e878cc5de7258aa Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Fri, 8 Feb 2013 00:18:40 +0500 Subject: net.http.parser: Fix traceback on invalid URL in status line. --- net/http/parser.lua | 1 + 1 file changed, 1 insertion(+) (limited to 'net') diff --git a/net/http/parser.lua b/net/http/parser.lua index 64cf38c0..9fd707d1 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -99,6 +99,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) parsed_url = { path = _path, query = _query }; else parsed_url = url_parse(path); + if not parsed_url then error = true; return error_cb("invalid-url"); end end path = preprocess_path(parsed_url.path); headers.host = parsed_url.host or headers.host; -- cgit v1.2.3 From 49a6c240739e97e0ffe59cabefb481c5225959bf Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Fri, 8 Feb 2013 00:27:59 +0500 Subject: net.http.parser: Ensure full URL in status line contains a path. --- net/http/parser.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/http/parser.lua b/net/http/parser.lua index 9fd707d1..2545b5ac 100644 --- a/net/http/parser.lua +++ b/net/http/parser.lua @@ -99,7 +99,7 @@ function httpstream.new(success_cb, error_cb, parser_type, options_cb) parsed_url = { path = _path, query = _query }; else parsed_url = url_parse(path); - if not parsed_url then error = true; return error_cb("invalid-url"); end + if not(parsed_url and parsed_url.path) then error = true; return error_cb("invalid-url"); end end path = preprocess_path(parsed_url.path); headers.host = parsed_url.host or headers.host; -- cgit v1.2.3 From 4f6cb9d1c644fdd8d7254e4ae38e7dc96f971ba3 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 12 Feb 2013 03:24:30 +0100 Subject: net.server_select: Be less aggressive about server pause --- net/server_select.lua | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'net') diff --git a/net/server_select.lua b/net/server_select.lua index 0852d444..36cb1265 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -201,20 +201,23 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxco --mem_free( ) out_put "server.lua: closed server handler and removed sockets from list" end - handler.pause = function() + handler.pause = function( hard ) if not handler.paused then - socket:close( ) - _sendlistlen = removesocket( _sendlist, socket, _sendlistlen ) _readlistlen = removesocket( _readlist, socket, _readlistlen ) - _socketlist[ socket ] = nil - socket = nil; + if hard then + _socketlist[ socket ] = nil + socket:close( ) + socket = nil; + end handler.paused = true; end end - handler.resume = function() + handler.resume = function( ) if handler.paused then - socket = socket_bind( ip, serverport ); - socket:settimeout( 0 ) + if not socket then + socket = socket_bind( ip, serverport ); + socket:settimeout( 0 ) + end _readlistlen = addsocket(_readlist, socket, _readlistlen) _socketlist[ socket ] = handler handler.paused = false; -- cgit v1.2.3 From a003acb3851806e0e1682333f5d572eb566208a0 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 12 Feb 2013 03:24:41 +0100 Subject: net.server_select: Limit global number of sockets passed to select. --- net/server_select.lua | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/net/server_select.lua b/net/server_select.lua index 36cb1265..250438c3 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -122,7 +122,8 @@ local _cleanqueue local _timer -local _maxclientsperserver +local _maxselectlen +local _maxfd local _maxsslhandshake @@ -156,15 +157,20 @@ _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs _cleanqueue = false -- clean bufferqueue after using -_maxclientsperserver = 1000 +_maxfd = luasocket._SETSIZE or 1024 -- We should ignore this on Windows. Perhaps by simply setting it to math.huge or something. +_maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows _maxsslhandshake = 30 -- max handshake round-trips ----------------------------------// PRIVATE //-- -wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections ) -- this function wraps a server +wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd - maxconnections = maxconnections or _maxclientsperserver + if socket:getfd() >= _maxfd then + out_error("server.lua: Disallowed FD number: "..socket:getfd()) + socket:close() + return nil, "fd-too-large" + end local connections = 0 @@ -233,7 +239,7 @@ wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxco return socket end handler.readbuffer = function( ) - if connections > maxconnections then + if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then handler.pause( ) out_put( "server.lua: refused new client connection: server full" ) return false @@ -261,6 +267,12 @@ end wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object + if socket:getfd() >= _maxfd then + out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent + socket:close( ) -- Should we send some kind of error here? + server.pause( ) + return nil, nil, "fd-too-large" + end socket:settimeout( 0 ) --// local import of socket methods //-- @@ -724,7 +736,7 @@ addserver = function( addr, port, listeners, pattern, sslctx ) -- this function out_error( "server.lua, [", addr, "]:", port, ": ", err ) return nil, err end - local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket + local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket if not handler then server:close( ) return nil, err @@ -768,7 +780,7 @@ closeall = function( ) end getsettings = function( ) - return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxclientsperserver, _maxsslhandshake + return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxselectlen, _maxsslhandshake, _maxfd end changesettings = function( new ) @@ -783,8 +795,9 @@ changesettings = function( new ) _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout _readtimeout = tonumber( new.read_timeout ) or _readtimeout _cleanqueue = new.select_clean_queue - _maxclientsperserver = new.max_connections or _maxclientsperserver + _maxselectlen = new.max_connections or _maxselectlen _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake + _maxfd = new.highest_allowed_fd or _maxfd return true end @@ -865,7 +878,8 @@ end --// EXPERIMENTAL //-- local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) - local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) + local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) + if not handler then return nil, err end _socketlist[ socket ] = handler if not sslctx then _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) -- cgit v1.2.3 From b9e7f08143c34747247b7f122b3ff1137f7f567d Mon Sep 17 00:00:00 2001 From: Waqas Hussain Date: Tue, 26 Feb 2013 19:41:52 +0500 Subject: net.http.server: Ensure HTTP callbacks are never called recursively for pipelined requests. --- net/http/server.lua | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'net') diff --git a/net/http/server.lua b/net/http/server.lua index 7cf25009..87d82418 100644 --- a/net/http/server.lua +++ b/net/http/server.lua @@ -89,29 +89,30 @@ function listener.onconnect(conn) local pending = {}; local waiting = false; local function process_next() - --if waiting then log("debug", "can't process_next, waiting"); return; end - if sessions[conn] and #pending > 0 then + if waiting then log("debug", "can't process_next, waiting"); return; end + waiting = true; + while sessions[conn] and #pending > 0 do local request = t_remove(pending); --log("debug", "process_next: %s", request.path); - waiting = true; --handle_request(conn, request, process_next); _1, _2, _3 = conn, request, process_next; if not xpcall(_handle_request, _traceback_handler) then conn:write("HTTP/1.0 500 Internal Server Error\r\n\r\n"..events.fire_event("http-error", { code = 500, private_message = last_err })); conn:close(); end - else - --log("debug", "ready for more"); - waiting = false; end + --log("debug", "ready for more"); + waiting = false; end local function success_cb(request) --log("debug", "success_cb: %s", request.path); + if waiting then + log("error", "http connection handler is not reentrant: %s", request.path); + assert(false, "http connection handler is not reentrant"); + end request.secure = secure; t_insert(pending, request); - if not waiting then - process_next(); - end + process_next(); end local function error_cb(err) log("debug", "error_cb: %s", err or ""); -- cgit v1.2.3 From e89b805d067713044d8362b952342048b2d7267c Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 1 Mar 2013 11:11:05 +0100 Subject: net.server_select: Use # operator instead of string.len --- net/server_select.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'net') diff --git a/net/server_select.lua b/net/server_select.lua index 250438c3..4d959a26 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -47,7 +47,6 @@ local os_difftime = os.difftime local math_min = math.min local math_huge = math.huge local table_concat = table.concat -local string_len = string.len local string_sub = string.sub local coroutine_wrap = coroutine.wrap local coroutine_yield = coroutine.yield @@ -406,7 +405,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport return clientport end local write = function( self, data ) - bufferlen = bufferlen + string_len( data ) + bufferlen = bufferlen + #data if bufferlen > maxsendlen then _closelist[ handler ] = "send buffer exceeded" -- cannot close the client at the moment, have to wait to the end of the cycle handler.write = idfalse -- dont write anymore @@ -488,7 +487,7 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport local buffer, err, part = receive( socket, pattern ) -- receive buffer with "pattern" if not err or (err == "wantread" or err == "timeout") then -- received something local buffer = buffer or part or "" - local len = string_len( buffer ) + local len = #buffer if len > maxreadlen then handler:close( "receive buffer exceeded" ) return false -- cgit v1.2.3 From 2df2e726b4765c5e739288437b9b555b802b96ea Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 1 Mar 2013 11:41:26 +0100 Subject: net.server_select: Optimization, clean bufferqueue when it makes sense. --- net/server_select.lua | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) (limited to 'net') diff --git a/net/server_select.lua b/net/server_select.lua index 4d959a26..63a94b7e 100644 --- a/net/server_select.lua +++ b/net/server_select.lua @@ -10,11 +10,6 @@ local use = function( what ) return _G[ what ] end -local clean = function( tbl ) - for i, k in pairs( tbl ) do - tbl[ i ] = nil - end -end local log, table_concat = require ("util.logger").init("socket"), table.concat; local out_put = function (...) return log("debug", table_concat{...}); end @@ -117,8 +112,6 @@ local _checkinterval local _sendtimeout local _readtimeout -local _cleanqueue - local _timer local _maxselectlen @@ -154,8 +147,6 @@ _checkinterval = 1200000 -- interval in secs to check idle clients _sendtimeout = 60000 -- allowed send idle time in secs _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs -_cleanqueue = false -- clean bufferqueue after using - _maxfd = luasocket._SETSIZE or 1024 -- We should ignore this on Windows. Perhaps by simply setting it to math.huge or something. _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows @@ -349,9 +340,6 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport 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); @@ -513,7 +501,9 @@ wrapconnection = function( server, listeners, socket, ip, serverport, clientport count = ( succ or byte or 0 ) * STAT_UNIT sendtraffic = sendtraffic + count _sendtraffic = _sendtraffic + count - _ = _cleanqueue and clean( bufferqueue ) + for i = bufferqueuelen,1,-1 do + bufferqueue[ i ] = nil + end --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, "unexpected close", 0; @@ -779,7 +769,7 @@ closeall = function( ) end getsettings = function( ) - return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxselectlen, _maxsslhandshake, _maxfd + return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, nil, _maxselectlen, _maxsslhandshake, _maxfd end changesettings = function( new ) @@ -793,7 +783,6 @@ changesettings = function( new ) _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout _readtimeout = tonumber( new.read_timeout ) or _readtimeout - _cleanqueue = new.select_clean_queue _maxselectlen = new.max_connections or _maxselectlen _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake _maxfd = new.highest_allowed_fd or _maxfd @@ -846,8 +835,8 @@ loop = function(once) -- this is the main loop of the program for handler, err in pairs( _closelist ) do handler.disconnect( )( handler, err ) handler:force_close() -- forced disconnect + _closelist[ handler ] = nil; end - clean( _closelist ) _currenttime = luasocket_gettime( ) if _currenttime - _timer >= math_min(next_timer_time, 1) then next_timer_time = math_huge; -- cgit v1.2.3 From 4cf76d88d4cf2b2db3e704812561f229d4524058 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Fri, 1 Mar 2013 14:15:38 +0100 Subject: net.server_event: Remove unused local --- net/server_event.lua | 1 - 1 file changed, 1 deletion(-) (limited to 'net') diff --git a/net/server_event.lua b/net/server_event.lua index 08926939..b34845d6 100644 --- a/net/server_event.lua +++ b/net/server_event.lua @@ -460,7 +460,6 @@ 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 -- cgit v1.2.3 From 38b1fed51e1f2ea4174870f01ba815e0c32a5225 Mon Sep 17 00:00:00 2001 From: Kim Alvefur Date: Tue, 5 Mar 2013 10:04:31 +0100 Subject: net.dns: Make sure argument to math.randomseed does not overflow a 32 bit unsigned int. Closes #320 --- net/dns.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/dns.lua b/net/dns.lua index a134eceb..c9c51fe8 100644 --- a/net/dns.lua +++ b/net/dns.lua @@ -223,7 +223,7 @@ end function dns.random(...) -- - - - - - - - - - - - - - - - - - - dns.random - math.randomseed(math.floor(10000*socket.gettime())); + math.randomseed(math.floor(10000*socket.gettime()) % 0x100000000); dns.random = math.random; return dns.random(...); end -- cgit v1.2.3