* luci/libs: add support for chunked transfer decoding in http.protocol
[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