9fe9a73a44a50b5068628c48cf0bc56810b4471a
[project/luci.git] / libs / lucid-http / luasrc / lucid / http / handler / luci.lua
1 --[[
2 LuCId HTTP-Slave
3 (c) 2009 Steven Barth <steven@midlink.org>
4
5 Licensed under the Apache License, Version 2.0 (the "License");
6 you may not use this file except in compliance with the License.
7 You may obtain a copy of the License at
8
9         http://www.apache.org/licenses/LICENSE-2.0
10
11 $Id$
12 ]]--
13
14 local cbi = require "luci.cbi"
15 local dsp = require "luci.dispatcher"
16 local util = require "luci.util"
17 local http = require "luci.http"
18 local ltn12 = require "luci.ltn12"
19 local srv = require "luci.lucid.http.server"
20 local coroutine = require "coroutine"
21 local type = type
22
23 module "luci.lucid.http.handler.luci"
24
25 Luci = util.class(srv.Handler)
26
27 function Luci.__init__(self, name, prefix)
28         srv.Handler.__init__(self, name)
29         self.prefix = prefix
30
31         self.dsp_tree = dsp.createtree()
32 end
33
34 function Luci.handle_HEAD(self, ...)
35         local stat, head = self:handle_GET(...)
36         return stat, head
37 end
38
39 function Luci.handle_POST(self, ...)
40         return self:handle_GET(...)
41 end
42
43 function Luci.handle_GET(self, request, sourcein)
44         local r = http.Request(
45                 request.env,
46                 sourcein
47         )
48
49         local res, id, data1, data2 = true, 0, nil, nil
50         local headers = {}
51         local status = 200
52         local active = true
53
54         local x = coroutine.create(dsp.httpdispatch)
55         while not id or id < 3 do
56                 res, id, data1, data2 = coroutine.resume(x, r, self.prefix, self.dsp_tree)
57
58                 if not res then
59                         status = 500
60                         headers["Content-Type"] = "text/plain"
61                         return status, headers, ltn12.source.string(id)
62                 end
63
64                 if id == 1 then
65                         status = data1
66                 elseif id == 2 then
67                         if not headers[data1] then
68                                 headers[data1] = data2
69                         elseif type(headers[data1]) ~= "table" then
70                                 headers[data1] = {headers[data1], data2}
71                         else
72                                 headers[data1][#headers[data1]+1] = data2
73                         end
74                 end
75         end
76         
77         if id == 6 then
78                 while (coroutine.resume(x)) do end
79                 return status, headers, srv.IOResource(data1, data2)
80         end
81
82         local function iter()
83                 local res, id, data = coroutine.resume(x)
84                 if not res then
85                         return nil, id
86                 elseif not id or not active then
87                         return true
88                 elseif id == 5 then
89                         active = false
90                         while (coroutine.resume(x)) do end
91                         return nil
92                 elseif id == 4 then
93                         return data
94                 end
95         end
96
97         return status, headers, iter
98 end
99