aboutsummaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
Diffstat (limited to 'net/http')
-rw-r--r--net/http/codes.lua106
-rw-r--r--net/http/server.lua44
2 files changed, 86 insertions, 64 deletions
diff --git a/net/http/codes.lua b/net/http/codes.lua
index 1090e545..8098b5c3 100644
--- a/net/http/codes.lua
+++ b/net/http/codes.lua
@@ -1,73 +1,85 @@
local response_codes = {
-- Source: http://www.iana.org/assignments/http-status-codes
- -- s/^\(\d*\)\s*\(.*\S\)\s*\[RFC.*\]\s*$/^I["\1"] = "\2";
- [100] = "Continue";
- [101] = "Switching Protocols";
+
+ [100] = "Continue"; -- RFC7231, Section 6.2.1
+ [101] = "Switching Protocols"; -- RFC7231, Section 6.2.2
[102] = "Processing";
+ [103] = "Early Hints";
+ -- [104-199] = "Unassigned";
- [200] = "OK";
- [201] = "Created";
- [202] = "Accepted";
- [203] = "Non-Authoritative Information";
- [204] = "No Content";
- [205] = "Reset Content";
- [206] = "Partial Content";
+ [200] = "OK"; -- RFC7231, Section 6.3.1
+ [201] = "Created"; -- RFC7231, Section 6.3.2
+ [202] = "Accepted"; -- RFC7231, Section 6.3.3
+ [203] = "Non-Authoritative Information"; -- RFC7231, Section 6.3.4
+ [204] = "No Content"; -- RFC7231, Section 6.3.5
+ [205] = "Reset Content"; -- RFC7231, Section 6.3.6
+ [206] = "Partial Content"; -- RFC7233, Section 4.1
[207] = "Multi-Status";
[208] = "Already Reported";
+ -- [209-225] = "Unassigned";
[226] = "IM Used";
+ -- [227-299] = "Unassigned";
- [300] = "Multiple Choices";
- [301] = "Moved Permanently";
- [302] = "Found";
- [303] = "See Other";
- [304] = "Not Modified";
- [305] = "Use Proxy";
- -- The 306 status code was used in a previous version of [RFC2616], is no longer used, and the code is reserved.
- [307] = "Temporary Redirect";
+ [300] = "Multiple Choices"; -- RFC7231, Section 6.4.1
+ [301] = "Moved Permanently"; -- RFC7231, Section 6.4.2
+ [302] = "Found"; -- RFC7231, Section 6.4.3
+ [303] = "See Other"; -- RFC7231, Section 6.4.4
+ [304] = "Not Modified"; -- RFC7232, Section 4.1
+ [305] = "Use Proxy"; -- RFC7231, Section 6.4.5
+ -- [306] = "(Unused)"; -- RFC7231, Section 6.4.6
+ [307] = "Temporary Redirect"; -- RFC7231, Section 6.4.7
[308] = "Permanent Redirect";
+ -- [309-399] = "Unassigned";
- [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] = "URI Too Long";
- [415] = "Unsupported Media Type";
- [416] = "Range Not Satisfiable";
- [417] = "Expectation Failed";
- [418] = "I'm a teapot";
- [421] = "Misdirected Request";
+ [400] = "Bad Request"; -- RFC7231, Section 6.5.1
+ [401] = "Unauthorized"; -- RFC7235, Section 3.1
+ [402] = "Payment Required"; -- RFC7231, Section 6.5.2
+ [403] = "Forbidden"; -- RFC7231, Section 6.5.3
+ [404] = "Not Found"; -- RFC7231, Section 6.5.4
+ [405] = "Method Not Allowed"; -- RFC7231, Section 6.5.5
+ [406] = "Not Acceptable"; -- RFC7231, Section 6.5.6
+ [407] = "Proxy Authentication Required"; -- RFC7235, Section 3.2
+ [408] = "Request Timeout"; -- RFC7231, Section 6.5.7
+ [409] = "Conflict"; -- RFC7231, Section 6.5.8
+ [410] = "Gone"; -- RFC7231, Section 6.5.9
+ [411] = "Length Required"; -- RFC7231, Section 6.5.10
+ [412] = "Precondition Failed"; -- RFC7232, Section 4.2
+ [413] = "Payload Too Large"; -- RFC7231, Section 6.5.11
+ [414] = "URI Too Long"; -- RFC7231, Section 6.5.12
+ [415] = "Unsupported Media Type"; -- RFC7231, Section 6.5.13
+ [416] = "Range Not Satisfiable"; -- RFC7233, Section 4.4
+ [417] = "Expectation Failed"; -- RFC7231, Section 6.5.14
+ [418] = "I'm a teapot"; -- RFC2324, Section 2.3.2
+ -- [419-420] = "Unassigned";
+ [421] = "Misdirected Request"; -- RFC7540, Section 9.1.2
[422] = "Unprocessable Entity";
[423] = "Locked";
[424] = "Failed Dependency";
- -- The 425 status code is reserved for the WebDAV advanced collections expired proposal [RFC2817]
- [426] = "Upgrade Required";
+ [425] = "Too Early";
+ [426] = "Upgrade Required"; -- RFC7231, Section 6.5.15
+ -- [427] = "Unassigned";
[428] = "Precondition Required";
[429] = "Too Many Requests";
+ -- [430] = "Unassigned";
[431] = "Request Header Fields Too Large";
+ -- [432-450] = "Unassigned";
[451] = "Unavailable For Legal Reasons";
+ -- [452-499] = "Unassigned";
- [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"; -- Experimental
+ [500] = "Internal Server Error"; -- RFC7231, Section 6.6.1
+ [501] = "Not Implemented"; -- RFC7231, Section 6.6.2
+ [502] = "Bad Gateway"; -- RFC7231, Section 6.6.3
+ [503] = "Service Unavailable"; -- RFC7231, Section 6.6.4
+ [504] = "Gateway Timeout"; -- RFC7231, Section 6.6.5
+ [505] = "HTTP Version Not Supported"; -- RFC7231, Section 6.6.6
+ [506] = "Variant Also Negotiates";
[507] = "Insufficient Storage";
[508] = "Loop Detected";
+ -- [509] = "Unassigned";
[510] = "Not Extended";
[511] = "Network Authentication Required";
+ -- [512-599] = "Unassigned";
};
for k,v in pairs(response_codes) do response_codes[k] = k.." "..v; end
diff --git a/net/http/server.lua b/net/http/server.lua
index 877c7f17..9b63d516 100644
--- a/net/http/server.lua
+++ b/net/http/server.lua
@@ -8,7 +8,7 @@ local os_date = os.date;
local pairs = pairs;
local s_upper = string.upper;
local setmetatable = setmetatable;
-local xpcall = xpcall;
+local xpcall = require "util.xpcall".xpcall;
local traceback = debug.traceback;
local tostring = tostring;
local cache = require "util.cache";
@@ -88,8 +88,6 @@ setmetatable(events._handlers, {
});
local handle_request;
-local _1, _2, _3;
-local function _handle_request() return handle_request(_1, _2, _3); end
local last_err;
local function _traceback_handler(err) last_err = err; log("error", "Traceback[httpserver]: %s", traceback(tostring(err), 2)); end
@@ -107,9 +105,7 @@ function listener.onconnect(conn)
while sessions[conn] and #pending > 0 do
local request = t_remove(pending);
--log("debug", "process_next: %s", request.path);
- --handle_request(conn, request, process_next);
- _1, _2, _3 = conn, request, process_next;
- if not xpcall(_handle_request, _traceback_handler) then
+ if not xpcall(handle_request, _traceback_handler, conn, request, process_next) then
conn:write("HTTP/1.0 500 Internal Server Error\r\n\r\n"..events.fire_event("http-error", { code = 500, private_message = last_err }));
conn:close();
end
@@ -217,14 +213,6 @@ function handle_request(conn, request, finish_cb)
local err_code, err;
if not request.path then
err_code, err = 400, "Invalid path";
- elseif not hosts[host] then
- if hosts[default_host] then
- host = default_host;
- elseif host then
- err_code, err = 404, "Unknown host: "..host;
- else
- err_code, err = 400, "Missing or invalid 'Host' header";
- end
end
if err then
@@ -233,10 +221,32 @@ function handle_request(conn, request, finish_cb)
return;
end
- local event = request.method.." "..host..request.path:match("[^?]*");
+ local global_event = request.method.." "..request.path:match("[^?]*");
+
local payload = { request = request, response = response };
- log("debug", "Firing event: %s", event);
- local result = events.fire_event(event, payload);
+ log("debug", "Firing event: %s", global_event);
+ local result = events.fire_event(global_event, payload);
+ if result == nil then
+ if not hosts[host] then
+ if hosts[default_host] then
+ host = default_host;
+ elseif host then
+ err_code, err = 404, "Unknown host: "..host;
+ else
+ err_code, err = 400, "Missing or invalid 'Host' header";
+ end
+ end
+
+ if err then
+ response.status_code = err_code;
+ response:send(events.fire_event("http-error", { code = err_code, message = err, response = response }));
+ return;
+ end
+
+ local host_event = request.method.." "..host..request.path:match("[^?]*");
+ log("debug", "Firing event: %s", host_event);
+ result = events.fire_event(host_event, payload);
+ end
if result ~= nil then
if result ~= true then
local body;