diff options
Diffstat (limited to 'net/http')
-rw-r--r-- | net/http/codes.lua | 106 | ||||
-rw-r--r-- | net/http/server.lua | 44 |
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; |