Mercurial > prosody-hg
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 |
| parents | 483f795f6f99 |
| children | 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 |
