Software /
code /
prosody
Comparison
net/server_event.lua @ 5625:e67891ad18d6
net.server_event: Add support for listener.onreadtimeout(conn), which can return true to prevent the connection from being closed when a read timeout occurs
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 24 May 2013 14:46:16 +0100 |
parent | 5531:483f795f6f99 |
child | 5756:61521ce49aae |
comparison
equal
deleted
inserted
replaced
5624:187f734bc996 | 5625:e67891ad18d6 |
---|---|
435 end | 435 end |
436 return false, "setoption not implemented"; | 436 return false, "setoption not implemented"; |
437 end | 437 end |
438 | 438 |
439 function interface_mt:setlistener(listener) | 439 function interface_mt:setlistener(listener) |
440 self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onstatus | 440 self.onconnect, self.ondisconnect, self.onincoming, self.ontimeout, self.onreadtimeout, self.onstatus |
441 = listener.onconnect, listener.ondisconnect, listener.onincoming, listener.ontimeout, listener.onstatus; | 441 = listener.onconnect, listener.ondisconnect, listener.onincoming, |
442 end | 442 listener.ontimeout, listener.onreadtimeout, listener.onstatus; |
443 | 443 end |
444 | |
444 -- Stub handlers | 445 -- Stub handlers |
445 function interface_mt:onconnect() | 446 function interface_mt:onconnect() |
446 end | 447 end |
447 function interface_mt:onincoming() | 448 function interface_mt:onincoming() |
448 end | 449 end |
449 function interface_mt:ondisconnect() | 450 function interface_mt:ondisconnect() |
450 end | 451 end |
451 function interface_mt:ontimeout() | 452 function interface_mt:ontimeout() |
453 end | |
454 function interface_mt:onreadtimeout() | |
455 self.fatalerror = "timeout during receiving" | |
456 debug( "connection failed:", self.fatalerror ) | |
457 self:_close() | |
458 self.eventread = nil | |
452 end | 459 end |
453 function interface_mt:ondrain() | 460 function interface_mt:ondrain() |
454 end | 461 end |
455 function interface_mt:onstatus() | 462 function interface_mt:onstatus() |
456 end | 463 end |
475 receive = client.receive; | 482 receive = client.receive; |
476 onconnect = listener.onconnect; -- will be called when client disconnects | 483 onconnect = listener.onconnect; -- will be called when client disconnects |
477 ondisconnect = listener.ondisconnect; -- will be called when client disconnects | 484 ondisconnect = listener.ondisconnect; -- will be called when client disconnects |
478 onincoming = listener.onincoming; -- will be called when client sends data | 485 onincoming = listener.onincoming; -- will be called when client sends data |
479 ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs | 486 ontimeout = listener.ontimeout; -- called when fatal socket timeout occurs |
487 onreadtimeout = listener.onreadtimeout; -- called when socket inactivity timeout occurs | |
480 onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS) | 488 onstatus = listener.onstatus; -- called for status changes (e.g. of SSL/TLS) |
481 eventread = false, eventwrite = false, eventclose = false, | 489 eventread = false, eventwrite = false, eventclose = false, |
482 eventhandshake = false, eventstarthandshake = false; -- event handler | 490 eventhandshake = false, eventstarthandshake = false; -- event handler |
483 eventconnect = false, eventsession = false; -- more event handler... | 491 eventconnect = false, eventsession = false; -- more event handler... |
484 eventwritetimeout = false; -- even more event handler... | 492 eventwritetimeout = false; -- even more event handler... |
572 if interface.noreading or interface.fatalerror then -- leave this event | 580 if interface.noreading or interface.fatalerror then -- leave this event |
573 --vdebug( "leaving this event because:", tostring(interface.noreading or interface.fatalerror) ) | 581 --vdebug( "leaving this event because:", tostring(interface.noreading or interface.fatalerror) ) |
574 interface.eventread = nil | 582 interface.eventread = nil |
575 return -1 | 583 return -1 |
576 end | 584 end |
577 if EV_TIMEOUT == event then -- took too long to get some data from client -> disconnect | 585 if EV_TIMEOUT == event and interface:onreadtimeout() ~= true then |
578 interface.fatalerror = "timeout during receiving" | 586 return -1 -- took too long to get some data from client -> disconnect |
579 debug( "connection failed:", interface.fatalerror ) | 587 end |
588 if interface._usingssl then -- handle luasec | |
589 if interface.eventwritetimeout then -- ok, in the past writecallback was regged | |
590 local ret = interface.writecallback( ) -- call it | |
591 --vdebug( "tried to write in readcallback, result:", tostring(ret) ) | |
592 end | |
593 if interface.eventreadtimeout then | |
594 interface.eventreadtimeout:close( ) | |
595 interface.eventreadtimeout = nil | |
596 end | |
597 end | |
598 local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern" | |
599 --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) | |
600 buffer = buffer or part | |
601 if buffer and #buffer > cfg.MAX_READ_LENGTH then -- check buffer length | |
602 interface.fatalerror = "receive buffer exceeded" | |
603 debug( "fatal error:", interface.fatalerror ) | |
580 interface:_close() | 604 interface:_close() |
581 interface.eventread = nil | 605 interface.eventread = nil |
582 return -1 | 606 return -1 |
583 else -- can read | 607 end |
584 if interface._usingssl then -- handle luasec | 608 if err and ( err ~= "timeout" and err ~= "wantread" ) then |
585 if interface.eventwritetimeout then -- ok, in the past writecallback was regged | 609 if "wantwrite" == err then -- need to read on write event |
586 local ret = interface.writecallback( ) -- call it | 610 if not interface.eventwrite then -- register new write event if needed |
587 --vdebug( "tried to write in readcallback, result:", tostring(ret) ) | 611 interface.eventwrite = addevent( base, interface.conn, EV_WRITE, interface.writecallback, cfg.WRITE_TIMEOUT ) |
588 end | 612 end |
589 if interface.eventreadtimeout then | 613 interface.eventreadtimeout = addevent( base, nil, EV_TIMEOUT, |
590 interface.eventreadtimeout:close( ) | 614 function( ) |
591 interface.eventreadtimeout = nil | 615 interface:_close() |
592 end | 616 end, cfg.READ_TIMEOUT |
593 end | 617 ) |
594 local buffer, err, part = interface.conn:receive( interface._pattern ) -- receive buffer with "pattern" | 618 debug( "wantwrite during read attempt, reg it in writecallback but dont know what really happens next..." ) |
595 --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) | 619 -- to be honest i dont know what happens next, if it is allowed to first read, the write etc... |
596 buffer = buffer or part | 620 else -- connection was closed or fatal error |
597 if buffer and #buffer > cfg.MAX_READ_LENGTH then -- check buffer length | 621 interface.fatalerror = err |
598 interface.fatalerror = "receive buffer exceeded" | 622 debug( "connection failed in read event:", interface.fatalerror ) |
599 debug( "fatal error:", interface.fatalerror ) | |
600 interface:_close() | 623 interface:_close() |
601 interface.eventread = nil | 624 interface.eventread = nil |
602 return -1 | 625 return -1 |
603 end | 626 end |
604 if err and ( err ~= "timeout" and err ~= "wantread" ) then | 627 else |
605 if "wantwrite" == err then -- need to read on write event | 628 interface.onincoming( interface, buffer, err ) -- send new data to listener |
606 if not interface.eventwrite then -- register new write event if needed | 629 end |
607 interface.eventwrite = addevent( base, interface.conn, EV_WRITE, interface.writecallback, cfg.WRITE_TIMEOUT ) | 630 if interface.noreading then |
608 end | 631 interface.eventread = nil; |
609 interface.eventreadtimeout = addevent( base, nil, EV_TIMEOUT, | 632 return -1; |
610 function( ) | 633 end |
611 interface:_close() | 634 return EV_READ, cfg.READ_TIMEOUT |
612 end, cfg.READ_TIMEOUT | |
613 ) | |
614 debug( "wantwrite during read attempt, reg it in writecallback but dont know what really happens next..." ) | |
615 -- to be honest i dont know what happens next, if it is allowed to first read, the write etc... | |
616 else -- connection was closed or fatal error | |
617 interface.fatalerror = err | |
618 debug( "connection failed in read event:", interface.fatalerror ) | |
619 interface:_close() | |
620 interface.eventread = nil | |
621 return -1 | |
622 end | |
623 else | |
624 interface.onincoming( interface, buffer, err ) -- send new data to listener | |
625 end | |
626 if interface.noreading then | |
627 interface.eventread = nil; | |
628 return -1; | |
629 end | |
630 return EV_READ, cfg.READ_TIMEOUT | |
631 end | |
632 end | 635 end |
633 | 636 |
634 client:settimeout( 0 ) -- set non blocking | 637 client:settimeout( 0 ) -- set non blocking |
635 setmetatable(interface, interface_mt) | 638 setmetatable(interface, interface_mt) |
636 interfacelist( "add", interface ) -- add to interfacelist | 639 interfacelist( "add", interface ) -- add to interfacelist |