serve/net/http/server.lua

Tue, 11 Sep 2018 23:27:56 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Tue, 11 Sep 2018 23:27:56 +0100
changeset 138
561f0af6c9dc
permissions
-rw-r--r--

serve/: Import dependencies required for serve mode from Prosody 329a670ae975

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