serve/net/http/parser.lua

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

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

client: Fix timeout handling

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

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

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

138
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local tonumber = tonumber;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 local assert = assert;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 local t_insert, t_concat = table.insert, table.concat;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 local url_parse = require "socket.url".parse;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 local urldecode = require "util.http".urldecode;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 local function preprocess_path(path)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 path = urldecode((path:gsub("//+", "/")));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 if path:sub(1,1) ~= "/" then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 path = "/"..path;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 local level = 0;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 for component in path:gmatch("([^/]+)/") do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 if component == ".." then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 level = level - 1;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 elseif component ~= "." then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 level = level + 1;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 if level < 0 then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 return nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 return path;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 local httpstream = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 function httpstream.new(success_cb, error_cb, parser_type, options_cb)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 local client = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 if not parser_type or parser_type == "server" then client = false; else assert(parser_type == "client", "Invalid parser type"); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 local buf, buflen, buftable = {}, 0, true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 local bodylimit = tonumber(options_cb and options_cb().body_size_limit) or 10*1024*1024;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 local buflimit = tonumber(options_cb and options_cb().buffer_size_limit) or bodylimit * 2;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 local chunked, chunk_size, chunk_start;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 local state = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 local packet;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 local len;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 local have_body;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 local error;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 return {
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 feed = function(_, data)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 if error then return nil, "parse has failed"; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 if not data then -- EOF
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 if buftable then buf, buftable = t_concat(buf), false; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 if state and client and not len then -- reading client body until EOF
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 packet.body = buf;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 success_cb(packet);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 elseif buf ~= "" then -- unexpected EOF
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 error = true; return error_cb("unexpected-eof");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 return;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 if buftable then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 t_insert(buf, data);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 buf = { buf, data };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 buftable = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 buflen = buflen + #data;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 if buflen > buflimit then error = true; return error_cb("max-buffer-size-exceeded"); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 while buflen > 0 do
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 if state == nil then -- read request
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 if buftable then buf, buftable = t_concat(buf), false; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 local index = buf:find("\r\n\r\n", nil, true);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 if not index then return; end -- not enough data
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 local method, path, httpversion, status_code, reason_phrase;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 local first_line;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 local headers = {};
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 for line in buf:sub(1,index+1):gmatch("([^\r\n]+)\r\n") do -- parse request
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 if first_line then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 local key, val = line:match("^([^%s:]+): *(.*)$");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 if not key then error = true; return error_cb("invalid-header-line"); end -- TODO handle multi-line and invalid headers
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 key = key:lower();
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 headers[key] = headers[key] and headers[key]..","..val or val;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 first_line = line;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 if client then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 httpversion, status_code, reason_phrase = line:match("^HTTP/(1%.[01]) (%d%d%d) (.*)$");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 status_code = tonumber(status_code);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 if not status_code then error = true; return error_cb("invalid-status-line"); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 have_body = not
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 ( (options_cb and options_cb().method == "HEAD")
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83 or (status_code == 204 or status_code == 304 or status_code == 301)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 or (status_code >= 100 and status_code < 200) );
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 method, path, httpversion = line:match("^(%w+) (%S+) HTTP/(1%.[01])$");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 if not method then error = true; return error_cb("invalid-status-line"); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 if not first_line then error = true; return error_cb("invalid-status-line"); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 chunked = have_body and headers["transfer-encoding"] == "chunked";
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 len = tonumber(headers["content-length"]); -- TODO check for invalid len
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 if len and len > bodylimit then error = true; return error_cb("content-length-limit-exceeded"); end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 if client then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 -- FIXME handle '100 Continue' response (by skipping it)
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 if not have_body then len = 0; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 packet = {
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 code = status_code;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 httpversion = httpversion;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 headers = headers;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 body = have_body and "" or nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 -- COMPAT the properties below are deprecated
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 responseversion = httpversion;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 responseheaders = headers;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 local parsed_url;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 if path:byte() == 47 then -- starts with /
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 local _path, _query = path:match("([^?]*).?(.*)");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 if _query == "" then _query = nil; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 parsed_url = { path = _path, query = _query };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 parsed_url = url_parse(path);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 if not(parsed_url and parsed_url.path) then error = true; return error_cb("invalid-url"); 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 path = preprocess_path(parsed_url.path);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 headers.host = parsed_url.host or headers.host;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 len = len or 0;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 packet = {
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 method = method;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 url = parsed_url;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 path = path;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 httpversion = httpversion;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 headers = headers;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 body = nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 };
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 buf = buf:sub(index + 4);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 buflen = #buf;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 state = true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 if state then -- read body
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 if client then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 if chunked then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 if chunk_start and buflen - chunk_start - 2 < chunk_size then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 return;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 end -- not enough data
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140 if buftable then buf, buftable = t_concat(buf), false; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 if not buf:find("\r\n", nil, true) then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 return;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 end -- not enough data
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 if not chunk_size then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 chunk_size, chunk_start = buf:match("^(%x+)[^\r\n]*\r\n()");
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 chunk_size = chunk_size and tonumber(chunk_size, 16);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 if not chunk_size then error = true; return error_cb("invalid-chunk-size"); end
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 if chunk_size == 0 and buf:find("\r\n\r\n", chunk_start-2, true) then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 state, chunk_size = nil, nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 buf = buf:gsub("^.-\r\n\r\n", ""); -- This ensure extensions and trailers are stripped
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 success_cb(packet);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 elseif buflen - chunk_start - 2 >= chunk_size then -- we have a chunk
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 packet.body = packet.body..buf:sub(chunk_start, chunk_start + (chunk_size-1));
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 buf = buf:sub(chunk_start + chunk_size + 2);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 buflen = buflen - (chunk_start + chunk_size + 2 - 1);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 chunk_size, chunk_start = nil, nil;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 else -- Partial chunk remaining
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 break;
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 elseif len and buflen >= len then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 if buftable then buf, buftable = t_concat(buf), false; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 if packet.code == 101 then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 packet.body, buf, buflen, buftable = buf, {}, 0, true;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 packet.body, buf = buf:sub(1, len), buf:sub(len + 1);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 buflen = #buf;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 state = nil; success_cb(packet);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 break;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 elseif buflen >= len then
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 if buftable then buf, buftable = t_concat(buf), false; end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 packet.body, buf = buf:sub(1, len), buf:sub(len + 1);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 buflen = #buf;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 state = nil; success_cb(packet);
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 else
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 break;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 end
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 end;
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 };
561f0af6c9dc serve/: Import dependencies required for serve mode from Prosody 329a670ae975
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 end
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 return httpstream;

mercurial