123 lines
2.5 KiB
Lua
123 lines
2.5 KiB
Lua
-- Copyright 2008 Steven Barth <steven@midlink.org>
|
|
-- Copyright 2017 Matthias Schiffer <mschiffer@universe-factory.net>
|
|
-- Licensed to the public under the Apache License 2.0.
|
|
|
|
local protocol = require "gluon.web.http.protocol"
|
|
local util = require "gluon.web.util"
|
|
|
|
|
|
local M = {}
|
|
|
|
local Http = util.class()
|
|
M.Http = Http
|
|
|
|
function Http:__init__(env, input, output)
|
|
self.input = input
|
|
self.output = output
|
|
|
|
self.request = {
|
|
env = env,
|
|
headers = {},
|
|
params = protocol.urldecode_params(env.QUERY_STRING or ""),
|
|
}
|
|
self.headers = {}
|
|
end
|
|
|
|
local function push_headers(self)
|
|
if self.eoh then return end
|
|
|
|
for _, header in pairs(self.headers) do
|
|
self.output:write(string.format("%s: %s\r\n", header[1], header[2]))
|
|
end
|
|
self.output:write("\r\n")
|
|
|
|
self.eoh = true
|
|
end
|
|
|
|
function Http:parse_input(filehandler)
|
|
protocol.parse_message_body(
|
|
self.input,
|
|
self.request,
|
|
filehandler
|
|
)
|
|
end
|
|
|
|
function Http:formvalue(name)
|
|
return self:formvaluetable(name)[1]
|
|
end
|
|
|
|
function Http:formvaluetable(name)
|
|
return self.request.params[name] or {}
|
|
end
|
|
|
|
function Http:getcookie(name)
|
|
local c = string.gsub(";" .. (self:getenv("HTTP_COOKIE") or "") .. ";", "%s*;%s*", ";")
|
|
local p = ";" .. name .. "=(.-);"
|
|
local _, _, value = c:find(p)
|
|
return value and protocol.urldecode(value)
|
|
end
|
|
|
|
function Http:getenv(name)
|
|
return self.request.env[name]
|
|
end
|
|
|
|
function Http:close()
|
|
if not self.output then return end
|
|
|
|
push_headers(self)
|
|
|
|
self.output:flush()
|
|
self.output:close()
|
|
self.output = nil
|
|
end
|
|
|
|
function Http:header(key, value)
|
|
self.headers[key:lower()] = {key, value}
|
|
end
|
|
|
|
function Http:prepare_content(mime)
|
|
if self.headers["content-type"] then return end
|
|
|
|
if mime == "application/xhtml+xml" then
|
|
local accept = self:getenv("HTTP_ACCEPT")
|
|
if not accept or not accept:find("application/xhtml+xml", nil, true) then
|
|
mime = "text/html; charset=UTF-8"
|
|
end
|
|
self:header("Vary", "Accept")
|
|
end
|
|
self:header("Content-Type", mime)
|
|
end
|
|
|
|
function Http:status(code, request)
|
|
if not self.output or self.code then return end
|
|
|
|
code = code or 200
|
|
request = request or "OK"
|
|
self.code = code
|
|
self.output:write(string.format("Status: %i %s\r\n", code, request))
|
|
end
|
|
|
|
function Http:write(content)
|
|
if not self.output then return end
|
|
|
|
self:status()
|
|
|
|
self:prepare_content("text/html; charset=utf-8")
|
|
|
|
if not self.headers["cache-control"] then
|
|
self:header("Cache-Control", "no-cache")
|
|
self:header("Expires", "0")
|
|
end
|
|
|
|
push_headers(self)
|
|
self.output:write(content)
|
|
end
|
|
|
|
function Http:redirect(url)
|
|
self:status(302, "Found")
|
|
self:header("Location", url)
|
|
self:close()
|
|
end
|
|
|
|
return M
|