mame/plugins/weblit/auto-headers.lua

93 lines
2.6 KiB
Lua

--[[
Response automatic values:
- Auto Server header
- Auto Date Header
- code defaults to 404 with body "Not Found\n"
- if there is a string body add Content-Length and ETag if missing
- if string body and no Content-Type, use text/plain for valid utf-8, application/octet-stream otherwise
- Auto add "; charset=utf-8" to Content-Type when body is known to be valid utf-8
- Auto 304 responses for if-none-match requests
- Auto strip body with HEAD requests
- Auto chunked encoding if body with unknown length
- if Connection header set and not keep-alive, set res.keepAlive to false
- Add Connection Keep-Alive/Close if not found based on res.keepAlive
--TODO: utf8 scanning
]]
--local digest = require('openssl').digest.digest
local date = require('os').date
return function (req, res, go)
local isHead = false
if req.method == "HEAD" then
req.method = "GET"
isHead = true
end
local requested = req.headers["if-none-match"]
go()
-- We could use the fancy metatable, but this is much faster
local lowerHeaders = {}
local headers = res.headers
for i = 1, #headers do
local key, value = unpack(headers[i])
lowerHeaders[key:lower()] = value
end
if not lowerHeaders.server then
headers[#headers + 1] = {"Server", serverName}
end
if not lowerHeaders.date then
headers[#headers + 1] = {"Date", date("!%a, %d %b %Y %H:%M:%S GMT")}
end
if not lowerHeaders.connection then
if req.keepAlive then
lowerHeaders.connection = "Keep-Alive"
headers[#headers + 1] = {"Connection", "Keep-Alive"}
else
headers[#headers + 1] = {"Connection", "Close"}
end
end
res.keepAlive = lowerHeaders.connection and lowerHeaders.connection:lower() == "keep-alive"
local body = res.body
if body then
local needLength = not lowerHeaders["content-length"] and not lowerHeaders["transfer-encoding"]
if type(body) == "string" then
if needLength then
headers[#headers + 1] = {"Content-Length", #body}
end
-- if not lowerHeaders.etag then
-- local etag = '"' .. digest("sha1", body) .. '"'
-- lowerHeaders.etag = etag
--headers[#headers + 1] = {"ETag", etag}
-- end
else
if needLength then
headers[#headers + 1] = {"Transfer-Encoding", "chunked"}
end
end
if not lowerHeaders["content-type"] then
headers[#headers + 1] = {"Content-Type", "text/plain"}
end
end
local etag = lowerHeaders.etag
if requested and res.code >= 200 and res.code < 300 and requested == etag then
res.code = 304
body = nil
end
if isHead then body = nil end
res.body = body
end