2 LuCI - HTTP-Interaction
5 HTTP-Header manipulator and form variable preprocessor
14 Copyright 2008 Steven Barth <steven@midlink.org>
16 Licensed under the Apache License, Version 2.0 (the "License");
17 you may not use this file except in compliance with the License.
18 You may obtain a copy of the License at
20 http://www.apache.org/licenses/LICENSE-2.0
22 Unless required by applicable law or agreed to in writing, software
23 distributed under the License is distributed on an "AS IS" BASIS,
24 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25 See the License for the specific language governing permissions and
26 limitations under the License.
30 module("luci.http", package.seeall)
31 require("luci.http.protocol")
34 context = luci.util.threadlocal()
37 Request = luci.util.class()
38 function Request.__init__(self, env, instream, errstream)
40 self.error = errstream
47 self.filehandler = function() end
52 setmetatable(self.get, {__index =
54 tbl = luci.http.protocol.urldecode_params(self.env.QUERY_STRING)
55 setmetatable(tbl, nil)
56 return rawget(tbl, key)
59 setmetatable(self.post, {__index =
61 tbl = luci.http.protocol.
62 setmetatable(tbl, nil)
63 return rawget(tbl, key)
67 function Request.formvalue(self, name, default)
68 return tostring(self.post[name] or self.get[name] or default)
71 function Request.formvaluetable(self, prefix)
73 prefix = prefix and prefix .. "." or "."
75 for k, v in pairs(self.getvalue()) do
76 if k:find(prefix, 1, true) == 1 then
77 vals[k:sub(#prefix + 1)] = tostring(v)
81 for k, v in pairs(self.postvalue()) do
82 if k:find(prefix, 1, true) == 1 then
83 vals[k:sub(#prefix + 1)] = tostring(v)
90 function Request.getenv(self, name)
91 return name and self.env[name] or self.env
94 function Request.getvalue(self, name)
95 local void = self.get[nil]
96 return name and self.get[name] or self.get
99 function Request.postvalue(self, name)
100 local void = self.post[nil]
101 return name and self.post[name] or self.post
104 function Request.setfilehandler(self, callback)
105 self.filehandler = callback
110 if not context.eoh then
115 if not context.closed then
116 context.closed = true
121 function formvalue(...)
122 return context.request:formvalue(...)
125 function formvaluetable(...)
126 return context.request:formvaluetable(...)
129 function getvalue(...)
130 return context.request:getvalue(...)
133 function postvalue(...)
134 return context.request:postvalue(...)
138 return context.request:getenv(...)
141 function setfilehandler(...)
142 return context.request:setfilehandler(...)
145 function header(key, value)
146 if not context.status then
149 if not context.headers then
152 context.headers[key:lower()] = value
153 coroutine.yield(2, key, value)
156 function prepare_content(mime)
157 header("Content-Type", mime)
160 function status(code, message)
162 message = message or "OK"
163 context.status = code
164 coroutine.yield(1, code, message)
167 function write(content)
168 if not content or #content == 0 then
171 if not context.eoh then
172 if not context.status then
175 if not context.headers or not context.headers["content-type"] then
176 header("Content-Type", "text/html; charset=utf-8")
182 coroutine.yield(4, content)
186 function basic_auth(realm, errorpage)
187 header("Status", "401 Unauthorized")
188 header("WWW-Authenticate", string.format('Basic realm="%s"', realm or ""))
197 function redirect(url)
198 header("Status", "302 Found")
199 header("Location", url)
203 function build_querystring(table)
206 for k, v in pairs(table) do
207 s = s .. urlencode(k) .. "=" .. urlencode(v) .. "&"
213 urldecode = luci.http.protocol.urldecode
214 urlencode = luci.http.protocol.urlencode
216 function urldecode(str)
217 str = str:gsub("+", " ")
218 str = str:gsub("%%(%x%x)",
219 function(h) return string.char(tonumber(h,16)) end)
220 str = str:gsub("\r\n", "\n")
224 function urlencode(str)
225 str = str:gsub("\n", "\r\n")
226 str = str:gsub("([^%w ])",
227 function (c) return string.format ("%%%02X", string.byte(c)) end)
228 str = str:gsub(" ", "+")