f48ad7ef9bd827bf7107134aa654a1eaa0819277
[project/luci.git] / libs / sgi-uhttpd / luasrc / sgi / uhttpd.lua
1 --[[
2 LuCI - Server Gateway Interface for the uHTTPd server
3
4 Copyright 2010 Jo-Philipp Wich <xm@subsignal.org>
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 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17
18 ]]--
19
20 exectime = os.clock()
21 require "nixio.util"
22 require "luci.http"
23 require "luci.sys"
24 require "luci.dispatcher"
25 require "luci.ltn12"
26
27 function handle_request(env)
28 local renv = {
29 CONTENT_LENGTH = env.CONTENT_LENGTH,
30 CONTENT_TYPE = env.CONTENT_TYPE,
31 REQUEST_METHOD = env.REQUEST_METHOD,
32 REQUEST_URI = env.REQUEST_URI,
33 PATH_INFO = env.PATH_INFO,
34 SCRIPT_NAME = env.SCRIPT_NAME:gsub("/+$", ""),
35 SCRIPT_FILENAME = env.SCRIPT_NAME,
36 SERVER_PROTOCOL = env.SERVER_PROTOCOL,
37 QUERY_STRING = env.QUERY_STRING
38 }
39
40 local k, v
41 for k, v in pairs(env.headers) do
42 k = k:upper():gsub("%-", "_")
43 renv["HTTP_" .. k] = v
44 end
45
46 local len = env.CONTENT_LENGTH or 0
47 local function recv()
48 if len > 0 then
49 local rlen, rbuf = uhttpd.recv(4096)
50 if rlen >= 0 then
51 len = len - rlen
52 return rbuf
53 end
54 end
55 return nil
56 end
57
58 local function send(...)
59 return uhttpd.send(...)
60 end
61
62 local function sendc(...)
63 if env.HTTP_VERSION > 1.0 then
64 return uhttpd.sendc(...)
65 else
66 return uhttpd.send(...)
67 end
68 end
69
70 local req = luci.http.Request(
71 renv, recv, luci.ltn12.sink.file(io.stderr)
72 )
73
74
75 local x = coroutine.create(luci.dispatcher.httpdispatch)
76 local hcache = { }
77 local active = true
78
79 if env.HTTP_VERSION > 1.0 then
80 hcache["Transfer-Encoding"] = "chunked"
81 end
82
83 while coroutine.status(x) ~= "dead" do
84 local res, id, data1, data2 = coroutine.resume(x, req)
85
86 if not res then
87 send(env.SERVER_PROTOCOL)
88 send(" 500 Internal Server Error\r\n")
89 send("Content-Type: text/plain\r\n\r\n")
90 send(tostring(id))
91 break
92 end
93
94 if active then
95 if id == 1 then
96 send(env.SERVER_PROTOCOL)
97 send(" ")
98 send(tostring(data1))
99 send(" ")
100 send(tostring(data2))
101 send("\r\n")
102 elseif id == 2 then
103 hcache[data1] = data2
104 elseif id == 3 then
105 for k, v in pairs(hcache) do
106 send(tostring(k))
107 send(": ")
108 send(tostring(v))
109 send("\r\n")
110 end
111 send("\r\n")
112 elseif id == 4 then
113 sendc(tostring(data1 or ""))
114 elseif id == 5 then
115 active = false
116 elseif id == 6 then
117 data1:copyz(nixio.stdout, data2)
118 end
119 end
120 end
121 end