Mercurial > prosody-hg
comparison net/server_event.lua @ 2535:75bb31b6c53f
net.server_event: Trailing whitespace
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Fri, 29 Jan 2010 16:49:43 +0000 |
| parents | 1f46a9d9b16a |
| children | e7bec4072c61 |
comparison
equal
deleted
inserted
replaced
| 2534:1f46a9d9b16a | 2535:75bb31b6c53f |
|---|---|
| 26 MAX_SEND_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes size of write buffer (for writing on sockets) | 26 MAX_SEND_LENGTH = 1024 * 1024 * 1024 * 1024, -- max bytes size of write buffer (for writing on sockets) |
| 27 ACCEPT_DELAY = 10, -- seconds to wait until the next attemp of a full server to accept | 27 ACCEPT_DELAY = 10, -- seconds to wait until the next attemp of a full server to accept |
| 28 READ_TIMEOUT = 60 * 30, -- timeout in seconds for read data from socket | 28 READ_TIMEOUT = 60 * 30, -- timeout in seconds for read data from socket |
| 29 WRITE_TIMEOUT = 30, -- timeout in seconds for write data on socket | 29 WRITE_TIMEOUT = 30, -- timeout in seconds for write data on socket |
| 30 CONNECT_TIMEOUT = 10, -- timeout in seconds for connection attemps | 30 CONNECT_TIMEOUT = 10, -- timeout in seconds for connection attemps |
| 31 CLEAR_DELAY = 5, -- seconds to wait for clearing interface list (and calling ondisconnect listeners) | 31 CLEAR_DELAY = 5, -- seconds to wait for clearing interface list (and calling ondisconnect listeners) |
| 32 DEBUG = true, -- show debug messages | 32 DEBUG = true, -- show debug messages |
| 33 } | 33 } |
| 34 | 34 |
| 35 local function use(x) return rawget(_G, x); end | 35 local function use(x) return rawget(_G, x); end |
| 36 local print = use "print" | 36 local print = use "print" |
| 55 | 55 |
| 56 local bitor = ( function( ) -- thx Rici Lake | 56 local bitor = ( function( ) -- thx Rici Lake |
| 57 local hasbit = function( x, p ) | 57 local hasbit = function( x, p ) |
| 58 return x % ( p + p ) >= p | 58 return x % ( p + p ) >= p |
| 59 end | 59 end |
| 60 return function( x, y ) | 60 return function( x, y ) |
| 61 local p = 1 | 61 local p = 1 |
| 62 local z = 0 | 62 local z = 0 |
| 63 local limit = x > y and x or y | 63 local limit = x > y and x or y |
| 64 while p <= limit do | 64 while p <= limit do |
| 65 if hasbit( x, p ) or hasbit( y, p ) then | 65 if hasbit( x, p ) or hasbit( y, p ) then |
| 66 z = z + p | 66 z = z + p |
| 67 end | 67 end |
| 68 p = p + p | 68 p = p + p |
| 69 end | 69 end |
| 101 interface:_position( position ) -- set new position in array | 101 interface:_position( position ) -- set new position in array |
| 102 else -- free last position | 102 else -- free last position |
| 103 array[ len ] = nil | 103 array[ len ] = nil |
| 104 end | 104 end |
| 105 len = len - 1 | 105 len = len - 1 |
| 106 return len | 106 return len |
| 107 else | 107 else |
| 108 return array | 108 return array |
| 109 end | 109 end |
| 110 end | 110 end |
| 111 end )( ) | 111 end )( ) |
| 157 end | 157 end |
| 158 function interface_mt:_start_session(onconnect) -- new session, for example after startssl | 158 function interface_mt:_start_session(onconnect) -- new session, for example after startssl |
| 159 if self.type == "client" then | 159 if self.type == "client" then |
| 160 local callback = function( ) | 160 local callback = function( ) |
| 161 self:_lock( false, false, false ) | 161 self:_lock( false, false, false ) |
| 162 --vdebug( "start listening on client socket with id:", self.id ) | 162 --vdebug( "start listening on client socket with id:", self.id ) |
| 163 self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ) -- register callback | 163 self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ) -- register callback |
| 164 self:onconnect() | 164 self:onconnect() |
| 165 self.eventsession = nil | 165 self.eventsession = nil |
| 166 return -1 | 166 return -1 |
| 167 end | 167 end |
| 219 self:_start_session( onsomething ) | 219 self:_start_session( onsomething ) |
| 220 debug( "ssl handshake done" ) | 220 debug( "ssl handshake done" ) |
| 221 self.eventhandshake = nil | 221 self.eventhandshake = nil |
| 222 return -1 | 222 return -1 |
| 223 end | 223 end |
| 224 debug( "error during ssl handshake:", err ) | 224 debug( "error during ssl handshake:", err ) |
| 225 if err == "wantwrite" then | 225 if err == "wantwrite" then |
| 226 event = EV_WRITE | 226 event = EV_WRITE |
| 227 elseif err == "wantread" then | 227 elseif err == "wantread" then |
| 228 event = EV_READ | 228 event = EV_READ |
| 229 else | 229 else |
| 230 self.fatalerror = err | 230 self.fatalerror = err |
| 231 end | 231 end |
| 232 end | 232 end |
| 233 if self.fatalerror then | 233 if self.fatalerror then |
| 234 if "onconnect" == arg then | 234 if "onconnect" == arg then |
| 235 self.ondisconnect = nil -- dont call this when client isnt really connected | 235 self.ondisconnect = nil -- dont call this when client isnt really connected |
| 236 end | 236 end |
| 242 event = coroutine_yield( event, cfg.HANDSHAKE_TIMEOUT ) -- yield this monster... | 242 event = coroutine_yield( event, cfg.HANDSHAKE_TIMEOUT ) -- yield this monster... |
| 243 end | 243 end |
| 244 end | 244 end |
| 245 ) | 245 ) |
| 246 debug "starting handshake..." | 246 debug "starting handshake..." |
| 247 self:_lock( false, true, true ) -- unlock read/write events, but keep interface locked | 247 self:_lock( false, true, true ) -- unlock read/write events, but keep interface locked |
| 248 self.eventhandshake = addevent( base, self.conn, EV_READWRITE, handshakecallback, cfg.HANDSHAKE_TIMEOUT ) | 248 self.eventhandshake = addevent( base, self.conn, EV_READWRITE, handshakecallback, cfg.HANDSHAKE_TIMEOUT ) |
| 249 return true | 249 return true |
| 250 end | 250 end |
| 251 function interface_mt:_destroy() -- close this interface + events and call last listener | 251 function interface_mt:_destroy() -- close this interface + events and call last listener |
| 252 debug( "closing client with id:", self.id ) | 252 debug( "closing client with id:", self.id ) |
| 297 local total = len + self.writebufferlen | 297 local total = len + self.writebufferlen |
| 298 if total > cfg.MAX_SEND_LENGTH then -- check buffer length | 298 if total > cfg.MAX_SEND_LENGTH then -- check buffer length |
| 299 local err = "send buffer exceeded" | 299 local err = "send buffer exceeded" |
| 300 debug( "error:", err ) -- to much, check your app | 300 debug( "error:", err ) -- to much, check your app |
| 301 return nil, err | 301 return nil, err |
| 302 end | 302 end |
| 303 self.writebuffer = self.writebuffer .. data -- new buffer | 303 self.writebuffer = self.writebuffer .. data -- new buffer |
| 304 self.writebufferlen = total | 304 self.writebufferlen = total |
| 305 if not self.eventwrite then -- register new write event | 305 if not self.eventwrite then -- register new write event |
| 306 --vdebug( "register new write event" ) | 306 --vdebug( "register new write event" ) |
| 307 self.eventwrite = addevent( base, self.conn, EV_WRITE, self.writecallback, cfg.WRITE_TIMEOUT ) | 307 self.eventwrite = addevent( base, self.conn, EV_WRITE, self.writecallback, cfg.WRITE_TIMEOUT ) |
| 397 elseif self._usingssl then -- startssl was already called | 397 elseif self._usingssl then -- startssl was already called |
| 398 err = "ssl already active" | 398 err = "ssl already active" |
| 399 end | 399 end |
| 400 if err then | 400 if err then |
| 401 debug( "error:", err ) | 401 debug( "error:", err ) |
| 402 return nil, err | 402 return nil, err |
| 403 end | 403 end |
| 404 self._usingssl = true | 404 self._usingssl = true |
| 405 self.startsslcallback = function( ) -- we have to start the handshake outside of a read/write event | 405 self.startsslcallback = function( ) -- we have to start the handshake outside of a read/write event |
| 406 self.startsslcallback = nil | 406 self.startsslcallback = nil |
| 407 self:_start_ssl(); | 407 self:_start_ssl(); |
| 438 end | 438 end |
| 439 function interface_mt:ondisconnect() | 439 function interface_mt:ondisconnect() |
| 440 end | 440 end |
| 441 function interface_mt:ontimeout() | 441 function interface_mt:ontimeout() |
| 442 end | 442 end |
| 443 end | 443 end |
| 444 | 444 |
| 445 -- End of client interface methods | 445 -- End of client interface methods |
| 446 | 446 |
| 447 local handleclient; | 447 local handleclient; |
| 448 do | 448 do |
| 496 interface.eventwrite = false | 496 interface.eventwrite = false |
| 497 return -1 | 497 return -1 |
| 498 end | 498 end |
| 499 if EV_TIMEOUT == event then -- took too long to write some data to socket -> disconnect | 499 if EV_TIMEOUT == event then -- took too long to write some data to socket -> disconnect |
| 500 interface.fatalerror = "timeout during writing" | 500 interface.fatalerror = "timeout during writing" |
| 501 debug( "writing failed:", interface.fatalerror ) | 501 debug( "writing failed:", interface.fatalerror ) |
| 502 interface:_close() | 502 interface:_close() |
| 503 interface.eventwrite = false | 503 interface.eventwrite = false |
| 504 return -1 | 504 return -1 |
| 505 else -- can write :) | 505 else -- can write :) |
| 506 if interface._usingssl then -- handle luasec | 506 if interface._usingssl then -- handle luasec |
| 530 interface.eventwrite = nil | 530 interface.eventwrite = nil |
| 531 return -1 | 531 return -1 |
| 532 elseif byte then -- want write again | 532 elseif byte then -- want write again |
| 533 --vdebug( "writebuffer is not empty:", err ) | 533 --vdebug( "writebuffer is not empty:", err ) |
| 534 interface.writebuffer = string_sub( interface.writebuffer, byte + 1, interface.writebufferlen ) -- new buffer | 534 interface.writebuffer = string_sub( interface.writebuffer, byte + 1, interface.writebufferlen ) -- new buffer |
| 535 interface.writebufferlen = interface.writebufferlen - byte | 535 interface.writebufferlen = interface.writebufferlen - byte |
| 536 if "wantread" == err then -- happens only with luasec | 536 if "wantread" == err then -- happens only with luasec |
| 537 local callback = function( ) | 537 local callback = function( ) |
| 538 interface:_close() | 538 interface:_close() |
| 539 interface.eventwritetimeout = nil | 539 interface.eventwritetimeout = nil |
| 540 return evreturn, evtimeout | 540 return evreturn, evtimeout |
| 542 interface.eventwritetimeout = addevent( base, nil, EV_TIMEOUT, callback, cfg.WRITE_TIMEOUT ) -- reg a new timeout event | 542 interface.eventwritetimeout = addevent( base, nil, EV_TIMEOUT, callback, cfg.WRITE_TIMEOUT ) -- reg a new timeout event |
| 543 debug( "wantread during write attemp, reg it in readcallback but dont know what really happens next..." ) | 543 debug( "wantread during write attemp, reg it in readcallback but dont know what really happens next..." ) |
| 544 -- hopefully this works with luasec; its simply not possible to use 2 different write events on a socket in luaevent | 544 -- hopefully this works with luasec; its simply not possible to use 2 different write events on a socket in luaevent |
| 545 return -1 | 545 return -1 |
| 546 end | 546 end |
| 547 return EV_WRITE, cfg.WRITE_TIMEOUT | 547 return EV_WRITE, cfg.WRITE_TIMEOUT |
| 548 else -- connection was closed during writing or fatal error | 548 else -- connection was closed during writing or fatal error |
| 549 interface.fatalerror = err or "fatal error" | 549 interface.fatalerror = err or "fatal error" |
| 550 debug( "connection failed in write event:", interface.fatalerror ) | 550 debug( "connection failed in write event:", interface.fatalerror ) |
| 551 interface:_close() | 551 interface:_close() |
| 552 interface.eventwrite = nil | 552 interface.eventwrite = nil |
| 553 return -1 | 553 return -1 |
| 554 end | 554 end |
| 555 end | 555 end |
| 562 interface.eventread = nil | 562 interface.eventread = nil |
| 563 return -1 | 563 return -1 |
| 564 end | 564 end |
| 565 if EV_TIMEOUT == event then -- took too long to get some data from client -> disconnect | 565 if EV_TIMEOUT == event then -- took too long to get some data from client -> disconnect |
| 566 interface.fatalerror = "timeout during receiving" | 566 interface.fatalerror = "timeout during receiving" |
| 567 debug( "connection failed:", interface.fatalerror ) | 567 debug( "connection failed:", interface.fatalerror ) |
| 568 interface:_close() | 568 interface:_close() |
| 569 interface.eventread = nil | 569 interface.eventread = nil |
| 570 return -1 | 570 return -1 |
| 571 else -- can read | 571 else -- can read |
| 572 if interface._usingssl then -- handle luasec | 572 if interface._usingssl then -- handle luasec |
| 578 interface.eventreadtimeout:close( ) | 578 interface.eventreadtimeout:close( ) |
| 579 interface.eventreadtimeout = nil | 579 interface.eventreadtimeout = nil |
| 580 end | 580 end |
| 581 end | 581 end |
| 582 local buffer, err, part = interface.conn:receive( pattern ) -- receive buffer with "pattern" | 582 local buffer, err, part = interface.conn:receive( pattern ) -- receive buffer with "pattern" |
| 583 --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) | 583 --vdebug( "read data:", tostring(buffer), "error:", tostring(err), "part:", tostring(part) ) |
| 584 buffer = buffer or part or "" | 584 buffer = buffer or part or "" |
| 585 local len = string_len( buffer ) | 585 local len = string_len( buffer ) |
| 586 if len > cfg.MAX_READ_LENGTH then -- check buffer length | 586 if len > cfg.MAX_READ_LENGTH then -- check buffer length |
| 587 interface.fatalerror = "receive buffer exceeded" | 587 interface.fatalerror = "receive buffer exceeded" |
| 588 debug( "fatal error:", interface.fatalerror ) | 588 debug( "fatal error:", interface.fatalerror ) |
| 598 end | 598 end |
| 599 interface.eventreadtimeout = addevent( base, nil, EV_TIMEOUT, | 599 interface.eventreadtimeout = addevent( base, nil, EV_TIMEOUT, |
| 600 function( ) | 600 function( ) |
| 601 interface:_close() | 601 interface:_close() |
| 602 end, cfg.READ_TIMEOUT | 602 end, cfg.READ_TIMEOUT |
| 603 ) | 603 ) |
| 604 debug( "wantwrite during read attemp, reg it in writecallback but dont know what really happens next..." ) | 604 debug( "wantwrite during read attemp, reg it in writecallback but dont know what really happens next..." ) |
| 605 -- to be honest i dont know what happens next, if it is allowed to first read, the write etc... | 605 -- to be honest i dont know what happens next, if it is allowed to first read, the write etc... |
| 606 else -- connection was closed or fatal error | 606 else -- connection was closed or fatal error |
| 607 interface.fatalerror = err | 607 interface.fatalerror = err |
| 608 debug( "connection failed in read event:", interface.fatalerror ) | 608 debug( "connection failed in read event:", interface.fatalerror ) |
| 609 interface:_close() | 609 interface:_close() |
| 610 interface.eventread = nil | 610 interface.eventread = nil |
| 611 return -1 | 611 return -1 |
| 612 end | 612 end |
| 613 end | 613 end |
| 705 sslctx, err = ssl.newcontext( sslcfg ) | 705 sslctx, err = ssl.newcontext( sslcfg ) |
| 706 if err then | 706 if err then |
| 707 debug( "error while creating new ssl context for server socket:", err ) | 707 debug( "error while creating new ssl context for server socket:", err ) |
| 708 return nil, err | 708 return nil, err |
| 709 end | 709 end |
| 710 end | 710 end |
| 711 local interface = handleserver( server, addr, port, pattern, listener, sslctx, startssl ) -- new server handler | 711 local interface = handleserver( server, addr, port, pattern, listener, sslctx, startssl ) -- new server handler |
| 712 debug( "new server created with id:", tostring(interface)) | 712 debug( "new server created with id:", tostring(interface)) |
| 713 return interface | 713 return interface |
| 714 end | 714 end |
| 715 end )( ) | 715 end )( ) |
| 724 end | 724 end |
| 725 | 725 |
| 726 function addclient( addr, serverport, listener, pattern, localaddr, localport, sslcfg, startssl ) | 726 function addclient( addr, serverport, listener, pattern, localaddr, localport, sslcfg, startssl ) |
| 727 local client, err = socket.tcp() -- creating new socket | 727 local client, err = socket.tcp() -- creating new socket |
| 728 if not client then | 728 if not client then |
| 729 debug( "cannot create socket:", err ) | 729 debug( "cannot create socket:", err ) |
| 730 return nil, err | 730 return nil, err |
| 731 end | 731 end |
| 732 client:settimeout( 0 ) -- set nonblocking | 732 client:settimeout( 0 ) -- set nonblocking |
| 733 if localaddr then | 733 if localaddr then |
| 734 local res, err = client:bind( localaddr, localport, -1 ) | 734 local res, err = client:bind( localaddr, localport, -1 ) |
| 738 end | 738 end |
| 739 end | 739 end |
| 740 local sslctx | 740 local sslctx |
| 741 if sslcfg then -- handle ssl/new context | 741 if sslcfg then -- handle ssl/new context |
| 742 if not ssl then | 742 if not ssl then |
| 743 debug "need luasec, but not available" | 743 debug "need luasec, but not available" |
| 744 return nil, "luasec not found" | 744 return nil, "luasec not found" |
| 745 end | 745 end |
| 746 sslctx, err = ssl.newcontext( sslcfg ) | 746 sslctx, err = ssl.newcontext( sslcfg ) |
| 747 if err then | 747 if err then |
| 748 debug( "cannot create new ssl context:", err ) | 748 debug( "cannot create new ssl context:", err ) |
