Software /
code /
prosody
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 ) |