Files
skyweave/skyweave/request.lua
T

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