* libs/httpd: Prepared HTTPD dispatching model
authorSteven Barth <steven@midlink.org>
Sat, 21 Jun 2008 19:41:17 +0000 (19:41 +0000)
committerSteven Barth <steven@midlink.org>
Sat, 21 Jun 2008 19:41:17 +0000 (19:41 +0000)
libs/httpd/luasrc/httpd.lua
libs/httpd/luasrc/httpd/module.lua
libs/httpd/luasrc/httpd/server.lua

index d95de7d..8cd946f 100644 (file)
@@ -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] )
index c53e834..28460a1 100644 (file)
@@ -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
 
 
index 9155e93..7f973ac 100644 (file)
@@ -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