serve/net/http/server.lua

Thu, 23 Mar 2023 12:14:53 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 23 Mar 2023 12:14:53 +0000
changeset 172
2c17151ed21b
parent 138
561f0af6c9dc
permissions
-rw-r--r--

client: Fix timeout handling

Previously, the timeout handler would fire an error that would get caught and
logged by the timer code. However that error never reached the upper levels of
scansion, leading to the whole thing just hanging.

Now we just trigger resumption of the async runner, and throw the error from
there if we haven't received the stanza yet.

With this change, timeouts are now correctly handled and reported as failures.

138
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local t_insert, t_remove, t_concat = table.insert, table.remove, table.concat;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local parser_new = require "net.http.parser".new;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local events = require "util.events".new();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local addserver = require "net.server".addserver;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 local log = require "util.logger".init("http.server");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local os_date = os.date;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 local pairs = pairs;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 local s_upper = string.upper;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 local setmetatable = setmetatable;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 local xpcall = xpcall;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 local traceback = debug.traceback;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 local tostring = tostring;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 local cache = require "util.cache";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 local codes = require "net.http.codes";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 local blocksize = 2^16;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 local _M = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 local sessions = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 local incomplete = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 local listener = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 local hosts = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 local default_host;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 local options = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 local function is_wildcard_event(event)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 return event:sub(-2, -1) == "/*";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 local function is_wildcard_match(wildcard_event, event)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 return wildcard_event:sub(1, -2) == event:sub(1, #wildcard_event-1);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 local _handlers = events._handlers;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 local recent_wildcard_events = cache.new(10000, function (key, value) -- luacheck: ignore 212/value
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 rawset(_handlers, key, nil);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 end);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 local event_map = events._event_map;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 setmetatable(events._handlers, {
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 -- Called when firing an event that doesn't exist (but may match a wildcard handler)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 __index = function (handlers, curr_event)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 if is_wildcard_event(curr_event) then return; end -- Wildcard events cannot be fired
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 -- Find all handlers that could match this event, sort them
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 -- and then put the array into handlers[curr_event] (and return it)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 local matching_handlers_set = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 local handlers_array = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 for event, handlers_set in pairs(event_map) do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 if event == curr_event or
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 is_wildcard_event(event) and is_wildcard_match(event, curr_event) then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 for handler, priority in pairs(handlers_set) do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 matching_handlers_set[handler] = { (select(2, event:gsub("/", "%1"))), is_wildcard_event(event) and 0 or 1, priority };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 table.insert(handlers_array, handler);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 if #handlers_array > 0 then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 table.sort(handlers_array, function(b, a)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 local a_score, b_score = matching_handlers_set[a], matching_handlers_set[b];
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 for i = 1, #a_score do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 if a_score[i] ~= b_score[i] then -- If equal, compare next score value
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 return a_score[i] < b_score[i];
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 return false;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 end);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 handlers_array = false;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 rawset(handlers, curr_event, handlers_array);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 if not event_map[curr_event] then -- Only wildcard handlers match, if any
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 recent_wildcard_events:set(curr_event, true);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 return handlers_array;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 end;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 __newindex = function (handlers, curr_event, handlers_array)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 if handlers_array == nil
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 and is_wildcard_event(curr_event) then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 -- Invalidate the indexes of all matching events
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 for event in pairs(handlers) do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 if is_wildcard_match(curr_event, event) then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 handlers[event] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 rawset(handlers, curr_event, handlers_array);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 end;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 });
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 local handle_request;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 local _1, _2, _3;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 local function _handle_request() return handle_request(_1, _2, _3); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 local last_err;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 local function _traceback_handler(err) last_err = err; log("error", "Traceback[httpserver]: %s", traceback(tostring(err), 2)); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 events.add_handler("http-error", function (error)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 return "Error processing request: "..codes[error.code]..". Check your error log for more information.";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 end, -1);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 function listener.onconnect(conn)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 local secure = conn:ssl() and true or nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 local pending = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 local waiting = false;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 local function process_next()
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 if waiting then return; end -- log("debug", "can't process_next, waiting");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 waiting = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 while sessions[conn] and #pending > 0 do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 local request = t_remove(pending);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 --log("debug", "process_next: %s", request.path);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 --handle_request(conn, request, process_next);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 _1, _2, _3 = conn, request, process_next;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 if not xpcall(_handle_request, _traceback_handler) then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 conn:write("HTTP/1.0 500 Internal Server Error\r\n\r\n"..events.fire_event("http-error", { code = 500, private_message = last_err }));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 conn:close();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 --log("debug", "ready for more");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 waiting = false;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 local function success_cb(request)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 --log("debug", "success_cb: %s", request.path);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 if waiting then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 log("error", "http connection handler is not reentrant: %s", request.path);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 assert(false, "http connection handler is not reentrant");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 request.secure = secure;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 t_insert(pending, request);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 process_next();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 local function error_cb(err)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 log("debug", "error_cb: %s", err or "<nil>");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 -- FIXME don't close immediately, wait until we process current stuff
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 -- FIXME if err, send off a bad-request response
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 sessions[conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 conn:close();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 local function options_cb()
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 return options;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 sessions[conn] = parser_new(success_cb, error_cb, "server", options_cb);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 function listener.ondisconnect(conn)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 local open_response = conn._http_open_response;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 if open_response and open_response.on_destroy then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 open_response.finished = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 open_response:on_destroy();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 incomplete[conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 sessions[conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 function listener.ondetach(conn)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 sessions[conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 incomplete[conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 function listener.onincoming(conn, data)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 sessions[conn]:feed(data);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 function listener.ondrain(conn)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 local response = incomplete[conn];
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 if response and response._send_more then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 response._send_more();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 local headerfix = setmetatable({}, {
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 __index = function(t, k)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 local v = "\r\n"..k:gsub("_", "-"):gsub("%f[%w].", s_upper)..": ";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 t[k] = v;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 return v;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 });
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 function _M.hijack_response(response, listener) -- luacheck: ignore
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 error("TODO");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 function handle_request(conn, request, finish_cb)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 --log("debug", "handler: %s", request.path);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 local headers = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 for k,v in pairs(request.headers) do headers[k:gsub("-", "_")] = v; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 request.headers = headers;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 request.conn = conn;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 local date_header = os_date('!%a, %d %b %Y %H:%M:%S GMT'); -- FIXME use
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 local conn_header = request.headers.connection;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 conn_header = conn_header and ","..conn_header:gsub("[ \t]", ""):lower().."," or ""
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 local httpversion = request.httpversion
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 local persistent = conn_header:find(",keep-alive,", 1, true)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 or (httpversion == "1.1" and not conn_header:find(",close,", 1, true));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 local response_conn_header;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 if persistent then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 response_conn_header = "Keep-Alive";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 response_conn_header = httpversion == "1.1" and "close" or nil
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 local response = {
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 request = request;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 status_code = 200;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 headers = { date = date_header, connection = response_conn_header };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 persistent = persistent;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 conn = conn;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 send = _M.send_response;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 send_file = _M.send_file;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 done = _M.finish_response;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 finish_cb = finish_cb;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 conn._http_open_response = response;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 local host = (request.headers.host or ""):match("[^:]+");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 -- Some sanity checking
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 local err_code, err;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 if not request.path then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 err_code, err = 400, "Invalid path";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220 elseif not hosts[host] then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 if hosts[default_host] then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 host = default_host;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 elseif host then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224 err_code, err = 404, "Unknown host: "..host;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226 err_code, err = 400, "Missing or invalid 'Host' header";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230 if err then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231 response.status_code = err_code;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 response:send(events.fire_event("http-error", { code = err_code, message = err, response = response }));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 return;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 local event = request.method.." "..host..request.path:match("[^?]*");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 local payload = { request = request, response = response };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238 log("debug", "Firing event: %s", event);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 local result = events.fire_event(event, payload);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 if result ~= nil then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241 if result ~= true then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
242 local body;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
243 local result_type = type(result);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
244 if result_type == "number" then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
245 response.status_code = result;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
246 if result >= 400 then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
247 payload.code = result;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
248 body = events.fire_event("http-error", payload);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
250 elseif result_type == "string" then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
251 body = result;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
252 elseif result_type == "table" then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
253 for k, v in pairs(result) do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
254 if k ~= "headers" then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
255 response[k] = v;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
256 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
257 for header_name, header_value in pairs(v) do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
258 response.headers[header_name] = header_value;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
259 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
260 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
261 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
262 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
263 response:send(body);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
264 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
265 return;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
266 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
267
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
268 -- if handler not called, return 404
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
269 response.status_code = 404;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
270 payload.code = 404;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
271 response:send(events.fire_event("http-error", payload));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
272 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
273 local function prepare_header(response)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
274 local status_line = "HTTP/"..response.request.httpversion.." "..(response.status or codes[response.status_code]);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
275 local headers = response.headers;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
276 local output = { status_line };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
277 for k,v in pairs(headers) do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
278 t_insert(output, headerfix[k]..v);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
279 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
280 t_insert(output, "\r\n\r\n");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
281 return output;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
282 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
283 _M.prepare_header = prepare_header;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
284 function _M.send_response(response, body)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
285 if response.finished then return; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
286 body = body or response.body or "";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
287 response.headers.content_length = #body;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
288 local output = prepare_header(response);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
289 t_insert(output, body);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
290 response.conn:write(t_concat(output));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
291 response:done();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
293 function _M.send_file(response, f)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
294 if response.finished then return; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
295 local chunked = not response.headers.content_length;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
296 if chunked then response.headers.transfer_encoding = "chunked"; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
297 incomplete[response.conn] = response;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
298 response._send_more = function ()
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
299 if response.finished then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
300 incomplete[response.conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
301 return;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
302 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
303 local chunk = f:read(blocksize);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
304 if chunk then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
305 if chunked then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
306 chunk = ("%x\r\n%s\r\n"):format(#chunk, chunk);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
307 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
308 -- io.write("."); io.flush();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
309 response.conn:write(chunk);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
310 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
311 if chunked then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
312 response.conn:write("0\r\n\r\n");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
313 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
314 -- io.write("\n");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
315 if f.close then f:close(); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
316 incomplete[response.conn] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
317 return response:done();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
318 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
319 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
320 response.conn:write(t_concat(prepare_header(response)));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
321 return true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
322 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
323 function _M.finish_response(response)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
324 if response.finished then return; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
325 response.finished = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
326 response.conn._http_open_response = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
327 if response.on_destroy then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
328 response:on_destroy();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
329 response.on_destroy = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
330 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
331 if response.persistent then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
332 response:finish_cb();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
333 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
334 response.conn:close();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
335 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
336 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
337 function _M.add_handler(event, handler, priority)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
338 events.add_handler(event, handler, priority);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
339 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
340 function _M.remove_handler(event, handler)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
341 events.remove_handler(event, handler);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
342 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
343
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
344 function _M.listen_on(port, interface, ssl)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
345 return addserver(interface or "*", port, listener, "*a", ssl);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
346 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
347 function _M.add_host(host)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
348 hosts[host] = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
349 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
350 function _M.remove_host(host)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
351 hosts[host] = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
352 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
353 function _M.set_default_host(host)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
354 default_host = host;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
355 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
356 function _M.fire_event(event, ...)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
357 return events.fire_event(event, ...);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
358 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
359 function _M.set_option(name, value)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
360 options[name] = value;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
361 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
362
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
363 _M.listener = listener;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
364 _M.codes = codes;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
365 _M._events = events;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
366 return _M;

mercurial