Changeset

10851:6cf16abd0976

net.server_select: Ensure onconnect is always called before onincoming This changes the code to call onconnect when the first data is sucessfully read or written, instead of simply when the socket first becomes writable. A writable socket can mean a connection error, and if the client already sent some data it may get passed to onincoming before processing writable sockets. This fixes the issue.
author Matthew Wild <mwild1@gmail.com>
date Mon, 01 Jun 2020 13:38:47 +0100
parents 10850:bd2814f900dd
children 10852:2e48aebdb915
files net/server_select.lua
diffstat 1 files changed, 18 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/net/server_select.lua	Sun May 31 22:39:34 2020 +0200
+++ b/net/server_select.lua	Mon Jun 01 13:38:47 2020 +0100
@@ -289,6 +289,8 @@
 
 	local ssl
 
+	local pending
+
 	local dispatch = listeners.onincoming
 	local status = listeners.onstatus
 	local disconnect = listeners.ondisconnect
@@ -343,6 +345,9 @@
 			listeners.onattach(self, data)
 		end
 	end
+	handler._setpending = function( )
+		pending = true
+	end
 	handler.getstats = function( )
 		return readtraffic, sendtraffic
 	end
@@ -525,6 +530,12 @@
 			_readtraffic = _readtraffic + count
 			_readtimes[ handler ] = _currenttime
 			--out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
+			if pending then -- connection established
+				pending = nil
+				if listeners.onconnect then
+					listeners.onconnect(handler)
+				end
+			end
 			return dispatch( handler, buffer, err )
 		else	-- connections was closed or fatal error
 			out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
@@ -535,6 +546,12 @@
 	local _sendbuffer = function( ) -- this function sends data
 		local succ, err, byte, buffer, count;
 		if socket then
+			if pending then
+				pending = nil
+				if listeners.onconnect then
+					listeners.onconnect(handler);
+				end
+			end
 			buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
 			succ, err, byte = send( socket, buffer, 1, bufferlen )
 			count = ( succ or byte or 0 ) * STAT_UNIT
@@ -1015,17 +1032,9 @@
 	if not handler then return nil, err end
 	_socketlist[ socket ] = handler
 	if not sslctx then
+		handler._setpending()
 		_readlistlen = addsocket(_readlist, socket, _readlistlen)
 		_sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
-		if listeners.onconnect then
-			-- When socket is writeable, call onconnect
-			local _sendbuffer = handler.sendbuffer;
-			handler.sendbuffer = function ()
-				handler.sendbuffer = _sendbuffer;
-				listeners.onconnect(handler);
-				return _sendbuffer(); -- Send any queued outgoing data
-			end
-		end
 	end
 	return handler, socket
 end