104 lines
4.6 KiB
Lua
Executable File
104 lines
4.6 KiB
Lua
Executable File
-- skyweave/request.lua
|
|
|
|
local json = require("json") -- Assuming json.lua is in a standard Lua path e.g. /usr/lib/lua
|
|
|
|
-- Removed local parse_query_string function, will use utils.parse_query_string
|
|
-- local function parse_query_string(query_string)
|
|
-- local params = {}
|
|
-- if not query_string or query_string == "" then return params end
|
|
--
|
|
-- for pair in query_string:gmatch("[^&]+") do
|
|
-- local key, value = pair:match("([^=]+)=?(.*)")
|
|
-- if key then
|
|
-- key = key:gsub("+", " "):gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
|
|
-- value = value or "" -- Ensure value is a string, even if empty after '='
|
|
-- value = value:gsub("+", " "):gsub("%%(%x%x)", function(h) return string.char(tonumber(h, 16)) end)
|
|
-- params[key] = value
|
|
-- end
|
|
-- end
|
|
-- return params
|
|
-- end
|
|
|
|
local utils = require("skyweave.utils") -- Updated path
|
|
local request_module = {}
|
|
|
|
function request_module.create_request_context()
|
|
local request = {}
|
|
|
|
request.method = os.getenv("REQUEST_METHOD") or "GET" -- Default to GET if not set
|
|
|
|
local query_string_env = os.getenv("QUERY_STRING") or ""
|
|
request.query = utils.parse_query_string(query_string_env)
|
|
|
|
-- PATH_INFO is the part of the URL after the script name and before the query string.
|
|
-- e.g. /cgi-bin/skyweave.lua/some/path?foo=bar -> /some/path
|
|
-- This is dependent on Nginx configuration (e.g. using fastcgi_split_path_info).
|
|
-- If not properly set by Nginx, it might be nil or empty.
|
|
request.path = os.getenv("PATH_INFO") or "/"
|
|
if request.path == "" then request.path = "/" end
|
|
|
|
|
|
request.headers = {}
|
|
-- Populate headers using os.getenv for specific, known CGI variables
|
|
local content_type_env = os.getenv("CONTENT_TYPE") -- Use different var name to avoid conflict with request.headers.content-type
|
|
if content_type_env then request.headers["content-type"] = content_type_env end
|
|
|
|
local user_agent = os.getenv("HTTP_USER_AGENT")
|
|
if user_agent then request.headers["user-agent"] = user_agent end
|
|
|
|
local accept_header = os.getenv("HTTP_ACCEPT")
|
|
if accept_header then request.headers["accept"] = accept_header end
|
|
|
|
-- Add other common headers if needed, for example:
|
|
-- local accept_encoding = os.getenv("HTTP_ACCEPT_ENCODING")
|
|
-- if accept_encoding then request.headers["accept-encoding"] = accept_encoding end
|
|
--
|
|
-- local accept_language = os.getenv("HTTP_ACCEPT_LANGUAGE")
|
|
-- if accept_language then request.headers["accept-language"] = accept_language end
|
|
--
|
|
-- local referer = os.getenv("HTTP_REFERER")
|
|
-- if referer then request.headers["referer"] = referer end
|
|
--
|
|
-- Note: CONTENT_LENGTH is retrieved later via os.getenv("CONTENT_LENGTH") specifically for body processing.
|
|
-- It is not typically added to this general request.headers table unless other logic specifically needs it there.
|
|
|
|
request.raw_body = nil
|
|
request.body = nil
|
|
request.body_parse_error = nil
|
|
|
|
if request.method == "POST" or request.method == "PUT" or request.method == "PATCH" then
|
|
local content_length_str = os.getenv("CONTENT_LENGTH")
|
|
local content_length = tonumber(content_length_str or 0)
|
|
|
|
if content_length and content_length > 0 then
|
|
-- Removed: io.stdin:setvbuf("binary") -- Not supported/needed for JSON POST or general text POST
|
|
request.raw_body = io.stdin:read(content_length)
|
|
|
|
-- Try to parse if content type suggests JSON and JSON lib is available
|
|
local content_type = request.headers["content-type"] or ""
|
|
if json and content_type:lower():match("application/json") then
|
|
if request.raw_body and request.raw_body ~= "" then
|
|
local success, decoded_or_error = pcall(json.decode, request.raw_body)
|
|
if success then
|
|
request.body = decoded_or_error
|
|
else
|
|
request.body_parse_error = "JSON decode error: " .. tostring(decoded_or_error)
|
|
end
|
|
else
|
|
request.body_parse_error = "Empty body received with application/json Content-Type"
|
|
end
|
|
else
|
|
-- If not JSON or no JSON lib, body remains nil, raw_body has the content.
|
|
-- Handlers can inspect raw_body if they expect other content types.
|
|
if not json and content_type:lower():match("application/json") then
|
|
request.body_parse_error = "Received JSON Content-Type but no JSON library is loaded."
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
return request
|
|
end
|
|
|
|
return request_module
|