Annotate

net/http/parser.lua @ 9340:368b092bf4bf

mod_storage_memory: Fix saving of remaining items during deletion All data is compiled into functions that return new copies in order to prevent mutation of stored data. This has downsides. Also an ugly hack.
author Kim Alvefur <zash@zash.se>
date Sat, 22 Sep 2018 16:03:50 +0200
parent 8045:55a56dc935f2
child 10540:375d31225d53
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
1 local tonumber = tonumber;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
2 local assert = assert;
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
3 local t_insert, t_concat = table.insert, table.concat;
4866
d54999db3aa1 net.http.parser: Do full URL decoding and parsing (e.g. adds request.url.query when present)
Matthew Wild <mwild1@gmail.com>
parents: 4716
diff changeset
4 local url_parse = require "socket.url".parse;
5460
274c10668fe8 net.http.parser: Depend on util.http instead of net.http for urlencode
Matthew Wild <mwild1@gmail.com>
parents: 5323
diff changeset
5 local urldecode = require "util.http".urldecode;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
6
4716
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
7 local function preprocess_path(path)
5222
61c47d26481d net.http.parser: Fix syntax error introduced in c5edb08fc7cb.
Waqas Hussain <waqas20@gmail.com>
parents: 5207
diff changeset
8 path = urldecode((path:gsub("//+", "/")));
4716
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
9 if path:sub(1,1) ~= "/" then
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
10 path = "/"..path;
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
11 end
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
12 local level = 0;
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
13 for component in path:gmatch("([^/]+)/") do
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
14 if component == ".." then
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
15 level = level - 1;
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
16 elseif component ~= "." then
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
17 level = level + 1;
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
18 end
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
19 if level < 0 then
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
20 return nil;
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
21 end
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
22 end
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
23 return path;
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
24 end
6eeb142a8073 mod_http_files, net.http.parser: Move path normalization to net.http.parser so that all modules can benefit
Matthew Wild <mwild1@gmail.com>
parents: 4712
diff changeset
25
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
26 local httpstream = {};
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
27
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
28 function httpstream.new(success_cb, error_cb, parser_type, options_cb)
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
29 local client = true;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@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
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
31 local buf, buflen, buftable = {}, 0, true;
7578
65bf55fdf971 net.http.parser: Allow limits to be configurable via options callback
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
32 local bodylimit = tonumber(options_cb and options_cb().body_size_limit) or 10*1024*1024;
65bf55fdf971 net.http.parser: Allow limits to be configurable via options callback
Kim Alvefur <zash@zash.se>
parents: 7577
diff changeset
33 local buflimit = tonumber(options_cb and options_cb().buffer_size_limit) or bodylimit * 2;
5463
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
34 local chunked, chunk_size, chunk_start;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
35 local state = nil;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
36 local packet;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
37 local len;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
38 local have_body;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
39 local error;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
40 return {
7569
a15ce0014ac9 net.http.parser: Remove unused argument [luacheck]
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
41 feed = function(_, data)
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
42 if error then return nil, "parse has failed"; end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
43 if not data then -- EOF
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
44 if buftable then buf, buftable = t_concat(buf), false; end
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
45 if state and client and not len then -- reading client body until EOF
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
46 packet.body = buf;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
47 success_cb(packet);
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
48 elseif buf ~= "" then -- unexpected EOF
8045
55a56dc935f2 net.http: Pass error all the way to callback
Kim Alvefur <zash@zash.se>
parents: 7635
diff changeset
49 error = true; return error_cb("unexpected-eof");
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
50 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
51 return;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
52 end
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
53 if buftable then
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
54 t_insert(buf, data);
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
55 else
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
56 buf = { buf, data };
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
57 buftable = true;
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
58 end
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
59 buflen = buflen + #data;
7577
3dc52f1778db net.http.parser: Add a limit on maximum buffer size, default to 20M
Kim Alvefur <zash@zash.se>
parents: 7576
diff changeset
60 if buflen > buflimit then error = true; return error_cb("max-buffer-size-exceeded"); end
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
61 while buflen > 0 do
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
62 if state == nil then -- read request
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
63 if buftable then buf, buftable = t_concat(buf), false; end
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
64 local index = buf:find("\r\n\r\n", nil, true);
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
65 if not index then return; end -- not enough data
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
66 local method, path, httpversion, status_code, reason_phrase;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
67 local first_line;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
68 local headers = {};
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
69 for line in buf:sub(1,index+1):gmatch("([^\r\n]+)\r\n") do -- parse request
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
70 if first_line then
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
71 local key, val = line:match("^([^%s:]+): *(.*)$");
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@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
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
73 key = key:lower();
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
74 headers[key] = headers[key] and headers[key]..","..val or val;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
75 else
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
76 first_line = line;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
77 if client then
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
78 httpversion, status_code, reason_phrase = line:match("^HTTP/(1%.[01]) (%d%d%d) (.*)$");
5462
3ecae471d9dd net.http.parser: Convert status_code to a number before trying to compare it to numbers
Matthew Wild <mwild1@gmail.com>
parents: 5461
diff changeset
79 status_code = tonumber(status_code);
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
80 if not status_code then error = true; return error_cb("invalid-status-line"); end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
81 have_body = not
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
82 ( (options_cb and options_cb().method == "HEAD")
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
83 or (status_code == 204 or status_code == 304 or status_code == 301)
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
84 or (status_code >= 100 and status_code < 200) );
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
85 else
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
86 method, path, httpversion = line:match("^(%w+) (%S+) HTTP/(1%.[01])$");
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
87 if not method then error = true; return error_cb("invalid-status-line"); end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
88 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
89 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
90 end
5291
01f7522049fb net.http.parser: Abort if no status line is received.
Kim Alvefur <zash@zash.se>
parents: 5259
diff changeset
91 if not first_line then error = true; return error_cb("invalid-status-line"); end
5463
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
92 chunked = have_body and headers["transfer-encoding"] == "chunked";
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
93 len = tonumber(headers["content-length"]); -- TODO check for invalid len
7576
d3646443a02e net.http.parser: Add a limit on content length, default to 10M
Kim Alvefur <zash@zash.se>
parents: 7575
diff changeset
94 if len and len > bodylimit then error = true; return error_cb("content-length-limit-exceeded"); end
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
95 if client then
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
96 -- FIXME handle '100 Continue' response (by skipping it)
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
97 if not have_body then len = 0; end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
98 packet = {
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
99 code = status_code;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
100 httpversion = httpversion;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
101 headers = headers;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
102 body = have_body and "" or nil;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
103 -- COMPAT the properties below are deprecated
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
104 responseversion = httpversion;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
105 responseheaders = headers;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
106 };
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
107 else
5259
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
108 local parsed_url;
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
109 if path:byte() == 47 then -- starts with /
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
110 local _path, _query = path:match("([^?]*).?(.*)");
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
111 if _query == "" then _query = nil; end
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
112 parsed_url = { path = _path, query = _query };
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
113 else
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
114 parsed_url = url_parse(path);
5323
4c30f638ff55 net.http.parser: Ensure full URL in status line contains a path.
Waqas Hussain <waqas20@gmail.com>
parents: 5322
diff changeset
115 if not(parsed_url and parsed_url.path) then error = true; return error_cb("invalid-url"); end
5259
c85c348253bd net.http.parser: Skip url.parse when we don't have a full URL (also fixes traceback on paths starting with '//').
Waqas Hussain <waqas20@gmail.com>
parents: 5222
diff changeset
116 end
4866
d54999db3aa1 net.http.parser: Do full URL decoding and parsing (e.g. adds request.url.query when present)
Matthew Wild <mwild1@gmail.com>
parents: 4716
diff changeset
117 path = preprocess_path(parsed_url.path);
4879
45bb378a4a98 net.http.parser: Keep the Host header no host is present in the URI
Kim Alvefur <zash@zash.se>
parents: 4866
diff changeset
118 headers.host = parsed_url.host or headers.host;
4712
4fc99f1b7570 net.http.parser: Handle full URLs in status line.
Waqas Hussain <waqas20@gmail.com>
parents: 4631
diff changeset
119
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
120 len = len or 0;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
121 packet = {
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
122 method = method;
4866
d54999db3aa1 net.http.parser: Do full URL decoding and parsing (e.g. adds request.url.query when present)
Matthew Wild <mwild1@gmail.com>
parents: 4716
diff changeset
123 url = parsed_url;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
124 path = path;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
125 httpversion = httpversion;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
126 headers = headers;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
127 body = nil;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
128 };
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
129 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
130 buf = buf:sub(index + 4);
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
131 buflen = #buf;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
132 state = true;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
133 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
134 if state then -- read body
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
135 if client then
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
136 if chunked then
7635
6879a220917b net.http.parser: Don't collapse buffer when expecting a chunk and not enough data has been received
Kim Alvefur <zash@zash.se>
parents: 7634
diff changeset
137 if chunk_start and buflen - chunk_start - 2 < chunk_size then
6879a220917b net.http.parser: Don't collapse buffer when expecting a chunk and not enough data has been received
Kim Alvefur <zash@zash.se>
parents: 7634
diff changeset
138 return;
6879a220917b net.http.parser: Don't collapse buffer when expecting a chunk and not enough data has been received
Kim Alvefur <zash@zash.se>
parents: 7634
diff changeset
139 end -- not enough data
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
140 if buftable then buf, buftable = t_concat(buf), false; end
5463
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
141 if not buf:find("\r\n", nil, true) then
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
142 return;
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
143 end -- not enough data
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
144 if not chunk_size then
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
145 chunk_size, chunk_start = buf:match("^(%x+)[^\r\n]*\r\n()");
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
146 chunk_size = chunk_size and tonumber(chunk_size, 16);
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
147 if not chunk_size then error = true; return error_cb("invalid-chunk-size"); end
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
148 end
5463
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
149 if chunk_size == 0 and buf:find("\r\n\r\n", chunk_start-2, true) then
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
150 state, chunk_size = nil, nil;
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
151 buf = buf:gsub("^.-\r\n\r\n", ""); -- This ensure extensions and trailers are stripped
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
152 success_cb(packet);
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
153 elseif buflen - chunk_start - 2 >= chunk_size then -- we have a chunk
5475
c2c9f07c5d6a net.http.parser: Fix off-by-one error in chunked encoding parser
Matthew Wild <mwild1@gmail.com>
parents: 5463
diff changeset
154 packet.body = packet.body..buf:sub(chunk_start, chunk_start + (chunk_size-1));
5463
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
155 buf = buf:sub(chunk_start + chunk_size + 2);
7634
b1132d74f54c net.http.parser: Fix missing buffer length adjustment when parsing chunked streams
Kim Alvefur <zash@zash.se>
parents: 7581
diff changeset
156 buflen = buflen - (chunk_start + chunk_size + 2 - 1);
5463
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
157 chunk_size, chunk_start = nil, nil;
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
158 else -- Partial chunk remaining
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
159 break;
111953bfe767 net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents: 5462
diff changeset
160 end
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
161 elseif len and buflen >= len then
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
162 if buftable then buf, buftable = t_concat(buf), false; end
6523
63d3126b75f1 net.http.parser: Fix whitespace/indentation
Matthew Wild <mwild1@gmail.com>
parents: 6522
diff changeset
163 if packet.code == 101 then
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
164 packet.body, buf, buflen, buftable = buf, {}, 0, true;
6523
63d3126b75f1 net.http.parser: Fix whitespace/indentation
Matthew Wild <mwild1@gmail.com>
parents: 6522
diff changeset
165 else
63d3126b75f1 net.http.parser: Fix whitespace/indentation
Matthew Wild <mwild1@gmail.com>
parents: 6522
diff changeset
166 packet.body, buf = buf:sub(1, len), buf:sub(len + 1);
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
167 buflen = #buf;
6523
63d3126b75f1 net.http.parser: Fix whitespace/indentation
Matthew Wild <mwild1@gmail.com>
parents: 6522
diff changeset
168 end
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
169 state = nil; success_cb(packet);
5461
67b674f6a299 net.http.parser: Break when no more usable data in buffer (client part of e5ec60dfb202)
Matthew Wild <mwild1@gmail.com>
parents: 5460
diff changeset
170 else
67b674f6a299 net.http.parser: Break when no more usable data in buffer (client part of e5ec60dfb202)
Matthew Wild <mwild1@gmail.com>
parents: 5460
diff changeset
171 break;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
172 end
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
173 elseif buflen >= len then
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
174 if buftable then buf, buftable = t_concat(buf), false; end
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
175 packet.body, buf = buf:sub(1, len), buf:sub(len + 1);
7575
3ae247af68f4 net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
Kim Alvefur <zash@zash.se>
parents: 6523
diff changeset
176 buflen = #buf;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
177 state = nil; success_cb(packet);
4910
e5ec60dfb202 net.http.parser: Break loop when no more usable data in buffer
Matthew Wild <mwild1@gmail.com>
parents: 4879
diff changeset
178 else
e5ec60dfb202 net.http.parser: Break loop when no more usable data in buffer
Matthew Wild <mwild1@gmail.com>
parents: 4879
diff changeset
179 break;
4631
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
180 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
181 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
182 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
183 end;
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
184 };
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
185 end
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
186
fc5d3b053454 net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff changeset
187 return httpstream;