* libs/httpd: Prepared HTTPD dispatching model
This commit is contained in:
parent
16dfa697e4
commit
90aef16aea
3 changed files with 87 additions and 30 deletions
|
@ -15,27 +15,31 @@ $Id$
|
||||||
|
|
||||||
require("ltn12")
|
require("ltn12")
|
||||||
require("socket")
|
require("socket")
|
||||||
|
|
||||||
require("luci.util")
|
require("luci.util")
|
||||||
require("luci.http.protocol")
|
|
||||||
require("luci.httpd.server")
|
|
||||||
|
|
||||||
|
|
||||||
local srv = luci.httpd.server
|
Daemon = luci.util.class()
|
||||||
local host = "0.0.0.0"
|
|
||||||
local port = 50000
|
|
||||||
|
|
||||||
|
function Daemon.__init__(self, threadlimit)
|
||||||
|
self.reading = {}
|
||||||
|
self.running = {}
|
||||||
|
self.handler = {}
|
||||||
|
self.threadlimit = threadlimit
|
||||||
|
end
|
||||||
|
|
||||||
server = socket.bind(host, port)
|
function Daemon.register(self, socket, clhandler, errhandler)
|
||||||
server:settimeout( 0, "t" )
|
table.insert( self.reading, socket )
|
||||||
|
self.handler[socket] = { clhandler = clhandler, errhandler = errhandler }
|
||||||
|
end
|
||||||
|
|
||||||
reading = { server }
|
function Daemon.run(self)
|
||||||
running = { }
|
while true do
|
||||||
|
self:step()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Daemon.step(self)
|
||||||
while true do
|
local input = socket.select( self.reading, nil, 0 )
|
||||||
|
|
||||||
local input = socket.select( reading, nil, 0.1 )
|
|
||||||
|
|
||||||
-- accept new connections
|
-- accept new connections
|
||||||
for i, connection in ipairs(input) do
|
for i, connection in ipairs(input) do
|
||||||
|
@ -43,25 +47,29 @@ while true do
|
||||||
local sock = connection:accept()
|
local sock = connection:accept()
|
||||||
|
|
||||||
-- check capacity
|
-- check capacity
|
||||||
if #running < srv.MAX_CLIENTS then
|
if self.threadlimit and #running < self.threadlimit then
|
||||||
|
|
||||||
table.insert( running, {
|
table.insert( self.running, {
|
||||||
coroutine.create( srv.client_handler ),
|
coroutine.create( self.handler[connection].clhandler ),
|
||||||
sock
|
sock
|
||||||
} )
|
} )
|
||||||
|
|
||||||
-- reject client
|
-- reject client
|
||||||
else
|
else
|
||||||
srv.error503( sock )
|
if self.handler[connection].errhandler then
|
||||||
|
self.handler[connection].errhandler( sock )
|
||||||
|
end
|
||||||
|
|
||||||
|
sock:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- create client handler
|
-- create client handler
|
||||||
for i, client in ipairs( running ) do
|
for i, client in ipairs( self.running ) do
|
||||||
|
|
||||||
-- reap dead clients
|
-- reap dead clients
|
||||||
if coroutine.status( client[1] ) == "dead" then
|
if coroutine.status( client[1] ) == "dead" then
|
||||||
table.remove( running, i )
|
table.remove( self.running, i )
|
||||||
end
|
end
|
||||||
|
|
||||||
coroutine.resume( client[1], client[2] )
|
coroutine.resume( client[1], client[2] )
|
||||||
|
|
|
@ -13,6 +13,7 @@ $Id$
|
||||||
]]--
|
]]--
|
||||||
module("luci.httpd.module", package.seeall)
|
module("luci.httpd.module", package.seeall)
|
||||||
require("luci.util")
|
require("luci.util")
|
||||||
|
require("luci.http.protocol")
|
||||||
require("ltn12")
|
require("ltn12")
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,7 +91,7 @@ function Handler.process(self, request, sourcein, sinkout, sinkerr)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
luci.http.protocol.push_response(request,response, sourceout, sinkout, sinkerr)
|
luci.http.protocol.push_response(request, response, sourceout, sinkout, sinkerr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,58 @@ $Id$
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
module("luci.httpd.server", package.seeall)
|
module("luci.httpd.server", package.seeall)
|
||||||
|
require("luci.util")
|
||||||
|
|
||||||
|
|
||||||
MAX_CLIENTS = 15
|
|
||||||
READ_BUFSIZE = 1024
|
READ_BUFSIZE = 1024
|
||||||
|
|
||||||
|
VHost = luci.util.class()
|
||||||
|
|
||||||
function error400( client, msg )
|
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 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( "HTTP/1.0 400 Bad request\r\n" )
|
||||||
client:send( "Content-Type: text/plain\r\n\r\n" )
|
client:send( "Content-Type: text/plain\r\n\r\n" )
|
||||||
|
|
||||||
|
@ -31,15 +76,18 @@ function error400( client, msg )
|
||||||
client:close()
|
client:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
function error503( client )
|
function Server.error503(self, client)
|
||||||
client:send( "HTTP/1.0 503 Server unavailable\r\n" )
|
client:send( "HTTP/1.0 503 Server unavailable\r\n" )
|
||||||
client:send( "Content-Type: text/plain\r\n\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:send( "There are too many clients connected, try again later\r\n" )
|
||||||
client:close()
|
end
|
||||||
|
|
||||||
|
function Server.process(self, ...)
|
||||||
|
-- TODO: Dispatch vhost
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function client_handler(client)
|
function Server.client_handler(self, client)
|
||||||
|
|
||||||
client:settimeout( 0 )
|
client:settimeout( 0 )
|
||||||
|
|
||||||
|
@ -114,12 +162,12 @@ function client_handler(client)
|
||||||
luci.util.dumptable( message )
|
luci.util.dumptable( message )
|
||||||
|
|
||||||
if not s and e then
|
if not s and e then
|
||||||
error400( client, e )
|
self:error400( client, e )
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
error400( client, err )
|
self:error400( client, err )
|
||||||
end
|
end
|
||||||
|
|
||||||
-- send response
|
-- send response
|
||||||
error400( client, "Dummy response" )
|
self:error400( client, "Dummy response" )
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue