serve/net/http/parser.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 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