Comparison

net/server_select.lua @ 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
parent 10474:175b72700d79
child 10852:2e48aebdb915
comparison
equal deleted inserted replaced
10850:bd2814f900dd 10851:6cf16abd0976
287 287
288 --// private closures of the object //-- 288 --// private closures of the object //--
289 289
290 local ssl 290 local ssl
291 291
292 local pending
293
292 local dispatch = listeners.onincoming 294 local dispatch = listeners.onincoming
293 local status = listeners.onstatus 295 local status = listeners.onstatus
294 local disconnect = listeners.ondisconnect 296 local disconnect = listeners.ondisconnect
295 local drain = listeners.ondrain 297 local drain = listeners.ondrain
296 local onreadtimeout = listeners.onreadtimeout; 298 local onreadtimeout = listeners.onreadtimeout;
340 handler.onreadtimeout = listeners.onreadtimeout 342 handler.onreadtimeout = listeners.onreadtimeout
341 detach = listeners.ondetach 343 detach = listeners.ondetach
342 if listeners.onattach then 344 if listeners.onattach then
343 listeners.onattach(self, data) 345 listeners.onattach(self, data)
344 end 346 end
347 end
348 handler._setpending = function( )
349 pending = true
345 end 350 end
346 handler.getstats = function( ) 351 handler.getstats = function( )
347 return readtraffic, sendtraffic 352 return readtraffic, sendtraffic
348 end 353 end
349 handler.ssl = function( ) 354 handler.ssl = function( )
523 local count = len * STAT_UNIT 528 local count = len * STAT_UNIT
524 readtraffic = readtraffic + count 529 readtraffic = readtraffic + count
525 _readtraffic = _readtraffic + count 530 _readtraffic = _readtraffic + count
526 _readtimes[ handler ] = _currenttime 531 _readtimes[ handler ] = _currenttime
527 --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err ) 532 --out_put( "server.lua: read data '", buffer:gsub("[^%w%p ]", "."), "', error: ", err )
533 if pending then -- connection established
534 pending = nil
535 if listeners.onconnect then
536 listeners.onconnect(handler)
537 end
538 end
528 return dispatch( handler, buffer, err ) 539 return dispatch( handler, buffer, err )
529 else -- connections was closed or fatal error 540 else -- connections was closed or fatal error
530 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) ) 541 out_put( "server.lua: client ", tostring(ip), ":", tostring(clientport), " read error: ", tostring(err) )
531 _ = handler and handler:force_close( err ) 542 _ = handler and handler:force_close( err )
532 return false 543 return false
533 end 544 end
534 end 545 end
535 local _sendbuffer = function( ) -- this function sends data 546 local _sendbuffer = function( ) -- this function sends data
536 local succ, err, byte, buffer, count; 547 local succ, err, byte, buffer, count;
537 if socket then 548 if socket then
549 if pending then
550 pending = nil
551 if listeners.onconnect then
552 listeners.onconnect(handler);
553 end
554 end
538 buffer = table_concat( bufferqueue, "", 1, bufferqueuelen ) 555 buffer = table_concat( bufferqueue, "", 1, bufferqueuelen )
539 succ, err, byte = send( socket, buffer, 1, bufferlen ) 556 succ, err, byte = send( socket, buffer, 1, bufferlen )
540 count = ( succ or byte or 0 ) * STAT_UNIT 557 count = ( succ or byte or 0 ) * STAT_UNIT
541 sendtraffic = sendtraffic + count 558 sendtraffic = sendtraffic + count
542 _sendtraffic = _sendtraffic + count 559 _sendtraffic = _sendtraffic + count
1013 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx, extra ) 1030 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx, extra )
1014 local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx, sslctx, extra) 1031 local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx, sslctx, extra)
1015 if not handler then return nil, err end 1032 if not handler then return nil, err end
1016 _socketlist[ socket ] = handler 1033 _socketlist[ socket ] = handler
1017 if not sslctx then 1034 if not sslctx then
1035 handler._setpending()
1018 _readlistlen = addsocket(_readlist, socket, _readlistlen) 1036 _readlistlen = addsocket(_readlist, socket, _readlistlen)
1019 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) 1037 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen)
1020 if listeners.onconnect then
1021 -- When socket is writeable, call onconnect
1022 local _sendbuffer = handler.sendbuffer;
1023 handler.sendbuffer = function ()
1024 handler.sendbuffer = _sendbuffer;
1025 listeners.onconnect(handler);
1026 return _sendbuffer(); -- Send any queued outgoing data
1027 end
1028 end
1029 end 1038 end
1030 return handler, socket 1039 return handler, socket
1031 end 1040 end
1032 1041
1033 local addclient = function( address, port, listeners, pattern, sslctx, typ, extra ) 1042 local addclient = function( address, port, listeners, pattern, sslctx, typ, extra )