net/httpserver.lua

Wed, 03 Jun 2009 08:00:07 +0500

author
Waqas Hussain <waqas20@gmail.com>
date
Wed, 03 Jun 2009 08:00:07 +0500
changeset 1292
b18c1ad7fcb6
parent 1119
61a011ebe243
child 1435
7a073b0a8f6a
permissions
-rw-r--r--

stanza_router: Remove the 'to' attribute when it's value is the bare JID of the local user sending the stanza

634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local socket = require "socket"
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local server = require "net.server"
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local url_parse = require "socket.url".parse;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 local connlisteners_start = require "net.connlisteners".start;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local connlisteners_get = require "net.connlisteners".get;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 local listener;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 local t_insert, t_concat = table.insert, table.concat;
1111
a1cf1d623695 net.http, net.httpserver: Remove urlcodes table... it really isn't needed (thanks Jan Harkes)
Matthew Wild <mwild1@gmail.com>
parents: 1110
diff changeset
11 local s_match, s_gmatch = string.match, string.gmatch;
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 local tonumber, tostring, pairs = tonumber, tostring, pairs;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13
1113
89ac8e9e1426 net.httpserver: Fix for urlencoding to always produce 2 digits
Matthew Wild <mwild1@gmail.com>
parents: 1111
diff changeset
14 local urlencode = function (s) return s and (s:gsub("%W", function (c) return string.format("%%%02x", c:byte()); end)); end
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 local log = require "util.logger".init("httpserver");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 local http_servers = {};
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 module "httpserver"
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 local default_handler;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 local function expectbody(reqt)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 return reqt.method == "POST";
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 local function send_response(request, response)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 -- Write status line
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 local resp;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 if response.body then
1052
a3429542631d net.httpserver: Don't log the response body (can be binary data...)
Matthew Wild <mwild1@gmail.com>
parents: 958
diff changeset
32 log("debug", "Sending response to %s", request.id);
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 resp = { "HTTP/1.0 ", response.status or "200 OK", "\r\n"};
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 local h = response.headers;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 if h then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 for k, v in pairs(h) do
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 t_insert(resp, k);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 t_insert(resp, ": ");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 t_insert(resp, v);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 t_insert(resp, "\r\n");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 if response.body and not (h and h["Content-Length"]) then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 t_insert(resp, "Content-Length: ");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 t_insert(resp, #response.body);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 t_insert(resp, "\r\n");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 t_insert(resp, "\r\n");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 if response.body and request.method ~= "HEAD" then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 t_insert(resp, response.body);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 else
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 -- Response we have is just a string (the body)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 log("debug", "Sending response to %s: %s", request.id, response);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 resp = { "HTTP/1.0 200 OK\r\n" };
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 t_insert(resp, "Connection: close\r\n");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 t_insert(resp, "Content-Length: ");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 t_insert(resp, #response);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 t_insert(resp, "\r\n\r\n");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 t_insert(resp, response);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 request.write(t_concat(resp));
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 if not request.stayopen then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 request:destroy();
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 local function call_callback(request, err)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 if request.handled then return; end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 request.handled = true;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 local callback = request.callback;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 if not callback and request.path then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 local path = request.url.path;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 local base = path:match("^/([^/?]+)");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 if not base then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 base = path:match("^http://[^/?]+/([^/?]+)");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 callback = (request.server and request.server.handlers[base]) or default_handler;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 if callback == default_handler then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 log("debug", "Default callback for this request (base: "..tostring(base)..")")
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 if callback then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 if err then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 log("debug", "Request error: "..err);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 if not callback(nil, err, request) then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 destroy_request(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 return;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 local response = callback(request.method, request.body and t_concat(request.body), request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 if response then
958
172fb9a73017 net.httpserver: Don't log that a request has been left open if it is destroyed
Matthew Wild <mwild1@gmail.com>
parents: 697
diff changeset
98 if response == true and not request.destroyed then
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 -- Keep connection open, we will reply later
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 log("warn", "Request %s left open, on_destroy is %s", request.id, tostring(request.on_destroy));
1053
c04b40a0740b net.httpserver: Fix traceback when sending response to a destroyed request
Matthew Wild <mwild1@gmail.com>
parents: 1052
diff changeset
101 elseif response ~= true then
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 -- Assume response
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 send_response(request, response);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 destroy_request(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 else
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 log("debug", "Request handler provided no response, destroying request...");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 -- No response, close connection
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 destroy_request(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 local function request_reader(request, data, startpos)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 if not data then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 if request.body then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 call_callback(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 else
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 -- Error.. connection was closed prematurely
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 call_callback(request, "connection-closed");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 -- Here we force a destroy... the connection is gone, so we can't reply later
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 destroy_request(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 return;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 if request.state == "body" then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 log("debug", "Reading body...")
697
8ddc85fa7602 core.httpserver: Rename request.responseheaders to the more logical request.headers
Matthew Wild <mwild1@gmail.com>
parents: 634
diff changeset
128 if not request.body then request.body = {}; request.havebodylength, request.bodylength = 0, tonumber(request.headers["content-length"]); end
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 if startpos then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 data = data:sub(startpos, -1)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 t_insert(request.body, data);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 if request.bodylength then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 request.havebodylength = request.havebodylength + #data;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 if request.havebodylength >= request.bodylength then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 -- We have the body
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 call_callback(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 elseif request.state == "headers" then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 log("debug", "Reading headers...")
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 local pos = startpos;
697
8ddc85fa7602 core.httpserver: Rename request.responseheaders to the more logical request.headers
Matthew Wild <mwild1@gmail.com>
parents: 634
diff changeset
143 local headers = request.headers or {};
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 for line in data:gmatch("(.-)\r\n") do
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 startpos = (startpos or 1) + #line + 2;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 local k, v = line:match("(%S+): (.+)");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 if k and v then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 headers[k:lower()] = v;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 -- log("debug", "Header: "..k:lower().." = "..v);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 elseif #line == 0 then
697
8ddc85fa7602 core.httpserver: Rename request.responseheaders to the more logical request.headers
Matthew Wild <mwild1@gmail.com>
parents: 634
diff changeset
151 request.headers = headers;
634
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 break;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 else
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 log("debug", "Unhandled header line: "..line);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 if not expectbody(request) then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 call_callback(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 return;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 -- Reached the end of the headers
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 request.state = "body";
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 if #data > startpos then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 return request_reader(request, data:sub(startpos, -1));
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 elseif request.state == "request" then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 log("debug", "Reading request line...")
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 local method, path, http, linelen = data:match("^(%S+) (%S+) HTTP/(%S+)\r\n()", startpos);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 if not method then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 return call_callback(request, "invalid-status-line");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 request.method, request.path, request.httpversion = method, path, http;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 request.url = url_parse(request.path);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 log("debug", method.." request for "..tostring(request.path) .. " on port "..request.handler.serverport());
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 if request.onlystatus then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 if not call_callback(request) then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 return;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 request.state = "headers";
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 if #data > linelen then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 return request_reader(request, data:sub(linelen, -1));
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 -- The default handler for requests
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 default_handler = function (method, body, request)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 log("debug", method.." request for "..tostring(request.path) .. " on port "..request.handler.serverport());
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 return { status = "404 Not Found",
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 headers = { ["Content-Type"] = "text/html" },
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 body = "<html><head><title>Page Not Found</title></head><body>Not here :(</body></html>" };
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 function new_request(handler)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 return { handler = handler, conn = handler.socket,
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 write = handler.write, state = "request",
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 server = http_servers[handler.serverport()],
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 send = send_response,
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 destroy = destroy_request,
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 id = tostring{}:match("%x+$")
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 };
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 function destroy_request(request)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 log("debug", "Destroying request %s", request.id);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 listener = listener or connlisteners_get("httpserver");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 if not request.destroyed then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 request.destroyed = true;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 if request.on_destroy then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220 log("debug", "Request has destroy callback");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 request.on_destroy(request);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 else
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 log("debug", "Request has no destroy callback");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 request.handler.close()
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226 if request.conn then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 listener.disconnect(request.conn, "closed");
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 function new(params)
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 local http_server = http_servers[params.port];
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234 if not http_server then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235 http_server = { handlers = {} };
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 http_servers[params.port] = http_server;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 -- We weren't already listening on this port, so start now
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238 connlisteners_start("httpserver", params);
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 if params.base then
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241 http_server.handlers[params.base] = params.handler;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
242 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
243 end
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
244
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
245 _M.request_reader = request_reader;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
246 _M.send_response = send_response;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
247 _M.urlencode = urlencode;
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
248
1af93ea23f96 Adding initial net.httpserver (lots of work to do on it)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249 return _M;

mercurial