libs/web: add luci.http.write_json()

This commit is contained in:
Jo-Philipp Wich 2010-11-07 19:27:15 +00:00
parent fcd9579fd4
commit 561673c0a1

View file

@ -12,9 +12,9 @@ Copyright 2008 Steven Barth <steven@midlink.org>
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
You may obtain a copy of the License at You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0 http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, distributed under the License is distributed on an "AS IS" BASIS,
@ -29,8 +29,10 @@ local protocol = require "luci.http.protocol"
local util = require "luci.util" local util = require "luci.util"
local string = require "string" local string = require "string"
local coroutine = require "coroutine" local coroutine = require "coroutine"
local table = require "table"
local pairs, tostring, error = pairs, tostring, error local ipairs, pairs, next, type, tostring, error =
ipairs, pairs, next, type, tostring, error
--- LuCI Web Framework high-level HTTP functions. --- LuCI Web Framework high-level HTTP functions.
module "luci.http" module "luci.http"
@ -45,14 +47,14 @@ function Request.__init__(self, env, sourcein, sinkerr)
-- File handler -- File handler
self.filehandler = function() end self.filehandler = function() end
-- HTTP-Message table -- HTTP-Message table
self.message = { self.message = {
env = env, env = env,
headers = {}, headers = {},
params = protocol.urldecode_params(env.QUERY_STRING or ""), params = protocol.urldecode_params(env.QUERY_STRING or ""),
} }
self.parsed_input = false self.parsed_input = false
end end
@ -60,7 +62,7 @@ function Request.formvalue(self, name, noparse)
if not noparse and not self.parsed_input then if not noparse and not self.parsed_input then
self:_parse_input() self:_parse_input()
end end
if name then if name then
return self.message.params[name] return self.message.params[name]
else else
@ -71,18 +73,18 @@ end
function Request.formvaluetable(self, prefix) function Request.formvaluetable(self, prefix)
local vals = {} local vals = {}
prefix = prefix and prefix .. "." or "." prefix = prefix and prefix .. "." or "."
if not self.parsed_input then if not self.parsed_input then
self:_parse_input() self:_parse_input()
end end
local void = self.message.params[nil] local void = self.message.params[nil]
for k, v in pairs(self.message.params) do for k, v in pairs(self.message.params) do
if k:find(prefix, 1, true) == 1 then if k:find(prefix, 1, true) == 1 then
vals[k:sub(#prefix + 1)] = tostring(v) vals[k:sub(#prefix + 1)] = tostring(v)
end end
end end
return vals return vals
end end
@ -90,7 +92,7 @@ function Request.content(self)
if not self.parsed_input then if not self.parsed_input then
self:_parse_input() self:_parse_input()
end end
return self.message.content, self.message.content_length return self.message.content, self.message.content_length
end end
@ -128,7 +130,7 @@ function close()
context.eoh = true context.eoh = true
coroutine.yield(3) coroutine.yield(3)
end end
if not context.closed then if not context.closed then
context.closed = true context.closed = true
coroutine.yield(5) coroutine.yield(5)
@ -164,7 +166,7 @@ function getcookie(name)
return context.request:getcookie(name) return context.request:getcookie(name)
end end
--- Get the value of a certain HTTP environment variable --- Get the value of a certain HTTP environment variable
-- or the environment table itself. -- or the environment table itself.
-- @param name Environment variable -- @param name Environment variable
-- @return HTTP environment value or environment table -- @return HTTP environment value or environment table
@ -248,8 +250,8 @@ function write(content, src_err)
header("Cache-Control", "no-cache") header("Cache-Control", "no-cache")
header("Expires", "0") header("Expires", "0")
end end
context.eoh = true context.eoh = true
coroutine.yield(3) coroutine.yield(3)
end end
@ -276,14 +278,18 @@ end
--- Create a querystring out of a table of key - value pairs. --- Create a querystring out of a table of key - value pairs.
-- @param table Query string source table -- @param table Query string source table
-- @return Encoded HTTP query string -- @return Encoded HTTP query string
function build_querystring(table) function build_querystring(q)
local s="?" local s = { "?" }
for k, v in pairs(table) do for k, v in pairs(q) do
s = s .. urlencode(k) .. "=" .. urlencode(v) .. "&" if #s > 1 then s[#s+1] = "&" end
s[#s+1] = urldecode(k)
s[#s+1] = "="
s[#s+1] = urldecode(v)
end end
return s return table.concat(s, "")
end end
--- Return the URL-decoded equivalent of a string. --- Return the URL-decoded equivalent of a string.
@ -298,3 +304,37 @@ urldecode = protocol.urldecode
-- @return URL-encoded string -- @return URL-encoded string
-- @see urldecode -- @see urldecode
urlencode = protocol.urlencode urlencode = protocol.urlencode
--- Send the given data as JSON encoded string.
-- @param data Data to send
function write_json(x)
if x == nil then
write("null")
elseif type(x) == "table" then
local k, v
if type(next(x)) == "number" then
write("[ ")
for k, v in ipairs(x) do
write_json(v)
if next(x, k) then
write(", ")
end
end
write(" ]")
else
write("{ ")
for k, v in pairs(x) do
write("%q: " % k)
write_json(v)
if next(x, k) then
write(", ")
end
end
write(" }")
end
elseif type(x) == "number" or type(x) == "boolean" then
write(tostring(x))
elseif type(x) == "string" then
write("%q" % tostring(x))
end
end