Software /
code /
prosody
Annotate
net/http/parser.lua @ 7575:3ae247af68f4
net.http.parser: Buffer into a table to reduce GC pressure, collapse to string when needed (fixes #603)
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 13 Aug 2016 20:19:08 +0200 |
parent | 6523:63d3126b75f1 |
child | 7576:d3646443a02e |
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; |
5463
111953bfe767
net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents:
5462
diff
changeset
|
32 local chunked, chunk_size, chunk_start; |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
33 local state = nil; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
34 local packet; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
35 local len; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
36 local have_body; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
37 local error; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
38 return { |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
39 feed = function(self, data) |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
40 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
|
41 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
|
42 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
|
43 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
|
44 packet.body = buf; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
45 success_cb(packet); |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
46 elseif buf ~= "" then -- unexpected EOF |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
47 error = true; return error_cb(); |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
48 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
49 return; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
50 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
|
51 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
|
52 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
|
53 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
|
54 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
|
55 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
|
56 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
|
57 buflen = buflen + #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
|
58 while buflen > 0 do |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
59 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
|
60 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
|
61 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
|
62 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
|
63 local method, path, httpversion, status_code, reason_phrase; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
64 local first_line; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
65 local headers = {}; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
66 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
|
67 if first_line then |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
68 local key, val = line:match("^([^%s:]+): *(.*)$"); |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
69 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
|
70 key = key:lower(); |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
71 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
|
72 else |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
73 first_line = line; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
74 if client then |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
75 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
|
76 status_code = tonumber(status_code); |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
77 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
|
78 have_body = not |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
79 ( (options_cb and options_cb().method == "HEAD") |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
80 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
|
81 or (status_code >= 100 and status_code < 200) ); |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
82 else |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
83 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
|
84 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
|
85 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
86 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
87 end |
5291
01f7522049fb
net.http.parser: Abort if no status line is received.
Kim Alvefur <zash@zash.se>
parents:
5259
diff
changeset
|
88 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
|
89 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
|
90 len = tonumber(headers["content-length"]); -- TODO check for invalid len |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
91 if client then |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
92 -- FIXME handle '100 Continue' response (by skipping it) |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
93 if not have_body then len = 0; end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
94 packet = { |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
95 code = status_code; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
96 httpversion = httpversion; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
97 headers = headers; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
98 body = have_body and "" or nil; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
99 -- COMPAT the properties below are deprecated |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
100 responseversion = httpversion; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
101 responseheaders = headers; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
102 }; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
103 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
|
104 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
|
105 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
|
106 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
|
107 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
|
108 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
|
109 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
|
110 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
|
111 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
|
112 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
|
113 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
|
114 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
|
115 |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
116 len = len or 0; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
117 packet = { |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
118 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
|
119 url = parsed_url; |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
120 path = path; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
121 httpversion = httpversion; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
122 headers = headers; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
123 body = nil; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
124 }; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
125 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
126 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
|
127 buflen = #buf; |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
128 state = true; |
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 if state then -- read body |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
131 if client then |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
132 if chunked 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
|
133 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
|
134 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
|
135 return; |
111953bfe767
net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents:
5462
diff
changeset
|
136 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
|
137 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
|
138 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
|
139 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
|
140 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
|
141 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
|
142 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
|
143 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
|
144 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
|
145 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
|
146 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
|
147 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
|
148 buf = buf:sub(chunk_start + chunk_size + 2); |
111953bfe767
net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents:
5462
diff
changeset
|
149 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
|
150 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
|
151 break; |
111953bfe767
net.http.parser: Fix chunked encoding response parsing, and make it more robust
Matthew Wild <mwild1@gmail.com>
parents:
5462
diff
changeset
|
152 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
|
153 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
|
154 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
|
155 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
|
156 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
|
157 else |
63d3126b75f1
net.http.parser: Fix whitespace/indentation
Matthew Wild <mwild1@gmail.com>
parents:
6522
diff
changeset
|
158 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
|
159 buflen = #buf; |
6523
63d3126b75f1
net.http.parser: Fix whitespace/indentation
Matthew Wild <mwild1@gmail.com>
parents:
6522
diff
changeset
|
160 end |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
161 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
|
162 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
|
163 break; |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
164 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
|
165 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
|
166 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
|
167 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
|
168 buflen = #buf; |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
169 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
|
170 else |
e5ec60dfb202
net.http.parser: Break loop when no more usable data in buffer
Matthew Wild <mwild1@gmail.com>
parents:
4879
diff
changeset
|
171 break; |
4631
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
172 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
173 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
174 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
175 end; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
176 }; |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
177 end |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
178 |
fc5d3b053454
net.http.{server|codes|parser}: Initial commit.
Waqas Hussain <waqas20@gmail.com>
parents:
diff
changeset
|
179 return httpstream; |