8cd946f33d32755b5cfa0529093c817d7a60a604
[project/luci.git] / libs / httpd / luasrc / httpd.lua
1 --[[
2
3 HTTP server implementation for LuCI - core
4 (c) 2008 Freifunk Leipzig / Jo-Philipp Wich <xm@leipzig.freifunk.net>
5
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9
10         http://www.apache.org/licenses/LICENSE-2.0
11
12 $Id$
13
14 ]]--
15
16 require("ltn12")
17 require("socket")
18 require("luci.util")
19
20
21 Daemon = luci.util.class()
22
23 function Daemon.__init__(self, threadlimit)
24         self.reading = {}
25         self.running = {}
26         self.handler = {}
27         self.threadlimit = threadlimit
28 end
29
30 function Daemon.register(self, socket, clhandler, errhandler)
31         table.insert( self.reading, socket )
32         self.handler[socket] = { clhandler = clhandler, errhandler = errhandler }
33 end
34
35 function Daemon.run(self)
36         while true do
37                 self:step()
38         end
39 end
40
41 function Daemon.step(self)      
42         local input = socket.select( self.reading, nil, 0 )
43
44         -- accept new connections
45         for i, connection in ipairs(input) do
46
47                 local sock = connection:accept()
48
49                 -- check capacity
50                 if self.threadlimit and #running < self.threadlimit then
51
52                         table.insert( self.running, {
53                                 coroutine.create( self.handler[connection].clhandler ),
54                                 sock
55                         } )
56
57                 -- reject client
58                 else
59                         if self.handler[connection].errhandler then
60                                 self.handler[connection].errhandler( sock )
61                         end
62                         
63                         sock:close()
64                 end
65         end
66
67         -- create client handler
68         for i, client in ipairs( self.running ) do
69
70                 -- reap dead clients
71                 if coroutine.status( client[1] ) == "dead" then
72                         table.remove( self.running, i )
73                 end
74
75                 coroutine.resume( client[1], client[2] )
76         end
77 end