2024-06-02 17:02:36 +02:00
|
|
|
|
local hlib = {}
|
2024-06-12 22:29:03 +02:00
|
|
|
|
local fmt = string.format
|
|
|
|
|
local g_version = "1.1"
|
|
|
|
|
local g_status_msg = {
|
|
|
|
|
[100] = "Continue",
|
|
|
|
|
[101] = "Switching Protocols",
|
|
|
|
|
[102] = "Processing",
|
|
|
|
|
[200] = "OK",
|
|
|
|
|
[201] = "Created",
|
|
|
|
|
[202] = "Accepted",
|
|
|
|
|
[203] = "Non-authoritative Information",
|
|
|
|
|
[204] = "No Content",
|
|
|
|
|
[205] = "Reset Content",
|
|
|
|
|
[206] = "Partial Content",
|
|
|
|
|
[207] = "Multi-Status",
|
|
|
|
|
[208] = "Already Reported",
|
|
|
|
|
[226] = "IM Used",
|
|
|
|
|
[300] = "Multiple Choices",
|
|
|
|
|
[301] = "Moved Permanently",
|
|
|
|
|
[302] = "Found",
|
|
|
|
|
[303] = "See Other",
|
|
|
|
|
[304] = "Not Modified",
|
|
|
|
|
[305] = "Use Proxy",
|
|
|
|
|
[307] = "Temporary Redirect",
|
|
|
|
|
[308] = "Permanent Redirect",
|
|
|
|
|
[400] = "Bad Request",
|
|
|
|
|
[401] = "Unauthorized",
|
|
|
|
|
[402] = "Payment Required",
|
|
|
|
|
[403] = "Forbidden",
|
|
|
|
|
[404] = "Not Found",
|
|
|
|
|
[405] = "Method Not Allowed",
|
|
|
|
|
[406] = "Not Acceptable",
|
|
|
|
|
[407] = "Proxy Authentication Required",
|
|
|
|
|
[408] = "Request Timeout",
|
|
|
|
|
[409] = "Conflict",
|
|
|
|
|
[410] = "Gone",
|
|
|
|
|
[411] = "Length Required",
|
|
|
|
|
[412] = "Precondition Failed",
|
|
|
|
|
[413] = "Payload Too Large",
|
|
|
|
|
[414] = "Request-URI Too Long",
|
|
|
|
|
[415] = "Unsupported Media Type",
|
|
|
|
|
[416] = "Requested Range Not Satisfiable",
|
|
|
|
|
[417] = "Expectation Failed",
|
|
|
|
|
[418] = "I’m a teapot",
|
|
|
|
|
[421] = "Misdirected Request",
|
|
|
|
|
[422] = "Unprocessable Entity",
|
|
|
|
|
[423] = "Locked",
|
|
|
|
|
[424] = "Failed Dependency",
|
|
|
|
|
[426] = "Upgrade Required",
|
|
|
|
|
[428] = "Precondition Required",
|
|
|
|
|
[429] = "Too Many Requests",
|
|
|
|
|
[431] = "Request Header Fields Too Large",
|
|
|
|
|
[444] = "Connection Closed Without Response",
|
|
|
|
|
[451] = "Unavailable For Legal Reasons",
|
|
|
|
|
[499] = "Client Closed Request",
|
|
|
|
|
[500] = "Internal Server Error",
|
|
|
|
|
[501] = "Not Implemented",
|
|
|
|
|
[502] = "Bad Gateway",
|
|
|
|
|
[503] = "Service Unavailable",
|
|
|
|
|
[504] = "Gateway Timeout",
|
|
|
|
|
[505] = "HTTP Version Not Supported",
|
|
|
|
|
[506] = "Variant Also Negotiates",
|
|
|
|
|
[507] = "Insufficient Storage",
|
|
|
|
|
[508] = "Loop Detected",
|
|
|
|
|
[510] = "Not Extended",
|
|
|
|
|
[511] = "Network Authentication Required",
|
|
|
|
|
[599] = "Network Connect Timeout Error",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function push_headers(headers, add)
|
|
|
|
|
for k,v in pairs(add) do
|
|
|
|
|
headers[k] = v
|
|
|
|
|
end
|
|
|
|
|
return headers
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function get_content_length(body)
|
|
|
|
|
return {["Content-Length"] = #body+1}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function get_content_type(body)
|
|
|
|
|
return {["Content-Type"] = "text/html"}
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
local header_functions = {
|
|
|
|
|
get_content_length,
|
|
|
|
|
get_content_type
|
|
|
|
|
}
|
2024-06-02 17:02:36 +02:00
|
|
|
|
|
|
|
|
|
function hlib.parse_request(r)
|
2024-06-12 22:29:03 +02:00
|
|
|
|
local request = {
|
|
|
|
|
method = nil,
|
|
|
|
|
path = nil,
|
|
|
|
|
version = nil,
|
|
|
|
|
headers = {}
|
|
|
|
|
}
|
2024-06-02 17:02:36 +02:00
|
|
|
|
local lines = string.gmatch(r, "[^\n]+")
|
|
|
|
|
local head_msg = lines()
|
|
|
|
|
local _, _, method, path, version = string.find(head_msg, "(%u+) ([%w/]+) ([%w/%.]+)")
|
|
|
|
|
request.method = method
|
|
|
|
|
request.path = path
|
|
|
|
|
request.version = version
|
|
|
|
|
|
|
|
|
|
for line in lines do
|
|
|
|
|
local _, _, a, b = string.find(line, "([%w-]+): (.+)")
|
|
|
|
|
if a then
|
|
|
|
|
request.headers[a] = b
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
return request
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function hlib.response(path, status, body)
|
|
|
|
|
local resp = {
|
2024-06-12 22:29:03 +02:00
|
|
|
|
version = fmt("HTTP/%s", g_version),
|
|
|
|
|
status = status,
|
|
|
|
|
status_msg = g_status_msg[status],
|
|
|
|
|
body = body,
|
|
|
|
|
headers = {}
|
2024-06-02 17:02:36 +02:00
|
|
|
|
}
|
2024-06-12 22:29:03 +02:00
|
|
|
|
|
|
|
|
|
for k,v in pairs(header_functions) do
|
|
|
|
|
resp.headers = push_headers(resp.headers, v(body))
|
|
|
|
|
end
|
2024-06-02 17:02:36 +02:00
|
|
|
|
local r = fmt(
|
|
|
|
|
[[%s %s %s
|
2024-06-12 22:29:03 +02:00
|
|
|
|
Content-Length: %d
|
2024-06-02 17:02:36 +02:00
|
|
|
|
|
|
|
|
|
%s
|
2024-06-12 22:29:03 +02:00
|
|
|
|
]], resp.version, resp.status, resp.status_msg, #resp.body+1, resp.body)
|
2024-06-02 17:02:36 +02:00
|
|
|
|
return r
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
return hlib
|