From: Steven Barth Date: Sat, 21 Jun 2008 19:41:17 +0000 (+0000) Subject: * libs/httpd: Prepared HTTPD dispatching model X-Git-Tag: 0.8.0~788 X-Git-Url: https://git.archive.openwrt.org/?p=project%2Fluci.git;a=commitdiff_plain;h=90aef16aea255b6f863cda36f118bf5bde0316b4 * libs/httpd: Prepared HTTPD dispatching model --- diff --git a/libs/httpd/luasrc/httpd.lua b/libs/httpd/luasrc/httpd.lua index d95de7d31..8cd946f33 100644 --- a/libs/httpd/luasrc/httpd.lua +++ b/libs/httpd/luasrc/httpd.lua @@ -15,27 +15,31 @@ $Id$ require("ltn12") require("socket") - require("luci.util") -require("luci.http.protocol") -require("luci.httpd.server") - -local srv = luci.httpd.server -local host = "0.0.0.0" -local port = 50000 +Daemon = luci.util.class() -server = socket.bind(host, port) -server:settimeout( 0, "t" ) - -reading = { server } -running = { } +function Daemon.__init__(self, threadlimit) + self.reading = {} + self.running = {} + self.handler = {} + self.threadlimit = threadlimit +end +function Daemon.register(self, socket, clhandler, errhandler) + table.insert( self.reading, socket ) + self.handler[socket] = { clhandler = clhandler, errhandler = errhandler } +end -while true do +function Daemon.run(self) + while true do + self:step() + end +end - local input = socket.select( reading, nil, 0.1 ) +function Daemon.step(self) + local input = socket.select( self.reading, nil, 0 ) -- accept new connections for i, connection in ipairs(input) do @@ -43,25 +47,29 @@ while true do local sock = connection:accept() -- check capacity - if #running < srv.MAX_CLIENTS then + if self.threadlimit and #running < self.threadlimit then - table.insert( running, { - coroutine.create( srv.client_handler ), + table.insert( self.running, { + coroutine.create( self.handler[connection].clhandler ), sock } ) -- reject client else - srv.error503( sock ) + if self.handler[connection].errhandler then + self.handler[connection].errhandler( sock ) + end + + sock:close() end end -- create client handler - for i, client in ipairs( running ) do + for i, client in ipairs( self.running ) do -- reap dead clients if coroutine.status( client[1] ) == "dead" then - table.remove( running, i ) + table.remove( self.running, i ) end coroutine.resume( client[1], client[2] ) diff --git a/libs/httpd/luasrc/httpd/module.lua b/libs/httpd/luasrc/httpd/module.lua index c53e834b4..28460a1c9 100644 --- a/libs/httpd/luasrc/httpd/module.lua +++ b/libs/httpd/luasrc/httpd/module.lua @@ -13,6 +13,7 @@ $Id$ ]]-- module("luci.httpd.module", package.seeall) require("luci.util") +require("luci.http.protocol") require("ltn12") @@ -90,7 +91,7 @@ function Handler.process(self, request, sourcein, sinkout, sinkerr) end end - luci.http.protocol.push_response(request,response, sourceout, sinkout, sinkerr) + luci.http.protocol.push_response(request, response, sourceout, sinkout, sinkerr) end diff --git a/libs/httpd/luasrc/httpd/server.lua b/libs/httpd/luasrc/httpd/server.lua index 9155e93f5..7f973ac03 100644 --- a/libs/httpd/luasrc/httpd/server.lua +++ b/libs/httpd/luasrc/httpd/server.lua @@ -14,13 +14,58 @@ $Id$ ]]-- module("luci.httpd.server", package.seeall) +require("luci.util") - -MAX_CLIENTS = 15 READ_BUFSIZE = 1024 +VHost = luci.util.class() + +function VHost.__init__(self, handler) + self.handler = handler + self.dhandler = {} +end + +function VHost.process(self, ...) + -- TODO: Dispatch handler +end + +function VHost.sethandler(self, handler, match) + if match then + self.dhandler[match] = handler + else + self.handler = handler + end +end + + + +Server = luci.util.class() -function error400( client, msg ) +function Server.__init__(self, ip, port, base) + self.socket = socket.bind(ip, port) + self.socket:settimeout(0, "t") + self.clhandler = client_handler + self.errhandler = error503 + self.host = nil + self.vhosts = {} + + -- Clone another server + if base then + getmetatable(self).__index = base + end +end + +-- Sets a vhost +function Server.setvhost(self, vhost, name) + if name then + self.vhosts[name] = vhost + else + self.host = vhost + end +end + + +function Server.error400(self, client, msg) client:send( "HTTP/1.0 400 Bad request\r\n" ) client:send( "Content-Type: text/plain\r\n\r\n" ) @@ -31,15 +76,18 @@ function error400( client, msg ) client:close() end -function error503( client ) +function Server.error503(self, client) client:send( "HTTP/1.0 503 Server unavailable\r\n" ) client:send( "Content-Type: text/plain\r\n\r\n" ) client:send( "There are too many clients connected, try again later\r\n" ) - client:close() +end + +function Server.process(self, ...) + -- TODO: Dispatch vhost end -function client_handler(client) +function Server.client_handler(self, client) client:settimeout( 0 ) @@ -114,12 +162,12 @@ function client_handler(client) luci.util.dumptable( message ) if not s and e then - error400( client, e ) + self:error400( client, e ) end else - error400( client, err ) + self:error400( client, err ) end -- send response - error400( client, "Dummy response" ) + self:error400( client, "Dummy response" ) end