1- local co_wrap_iter = require (" resty.coroutines" ).co_wrap_iter
2- local co_yield = coroutine ._yield
1+ local httpc = require " resty.resolver.http"
32
43local _M = {
54}
65
76local cr_lf = " \r\n "
8- local default_max_chunk_size = 32 * 1024 -- 32K
97
108local function send (socket , data )
119 if not data or data == ' ' then
@@ -21,100 +19,9 @@ local function print_err(error_code, ...)
2119 return ngx .exit (error_code )
2220end
2321
24- -- This is a copy of lua-resty-http _chunked_body_reader function but with
25- -- extra bits to make chunked encoding work with raw socket
26- -- https://github.com/ledgetech/lua-resty-http/blob/v0.16.1/lib/resty/http.lua#L418
27-
28- -- chunked_reader return a body reader that translates the data read from sock
29- -- out of HTTP "chunked" format before returning it
30- --
31- -- The chunked reader return nil when the final 0-length chunk is read
32- function _M .chunked_reader (sock , max_chunk_size )
33- max_chunk_size = max_chunk_size or default_max_chunk_size
34-
35- if not sock then
36- return nil , " chunked_reader: invalid sock"
37- end
38-
39- return co_wrap_iter (function ()
40- local eof = false
41- local remaining = 0
42- local size = 0
43- repeat
44- -- If we still have data on this chunk
45- if max_chunk_size and remaining > 0 then
46- if remaining > max_chunk_size then
47- -- Consume up to max_chunk_size
48- size = max_chunk_size
49- remaining = remaining - max_chunk_size
50- else
51- -- Consume all remaining
52- size = remaining
53- remaining = 0
54- end
55- else
56- -- read a line from socket
57- -- chunk-size CRLF
58- local line , err = sock :receive ()
59- if not line then
60- co_yield (nil , " chunked_reader: failed to receive chunk size, err: " .. (err or " unknown" ))
61- end
62-
63- size = tonumber (line , 16 )
64- if not size then
65- co_yield (nil , " chunked_reader: unable to read chunksize" )
66- end
67-
68- if max_chunk_size and size > max_chunk_size then
69- -- Consume up to max_chunk_size
70- remaining = size - max_chunk_size
71- size = max_chunk_size
72- end
73- end
74-
75-
76- if size > 0 then
77- -- Receive the chunk
78- local chunk , err = sock :receive (size )
79- if not chunk then
80- co_yield (nil , " chunked_reader: failed to receive chunk of size " .. size .. " err: " .. (err or " unknown" ))
81- end
82-
83- if remaining == 0 then
84- -- We're at the end of a chunk, read the next two bytes
85- -- and verify they are "\r\n"
86- local data , err = sock :receive (2 )
87- if not data then
88- co_yield (nil , " chunked_reader: failed to receive chunk terminator, err: " .. (err or " unknown" ))
89- end
90- end
91-
92- chunk = string.format (" %x\r\n " , size ) .. chunk .. cr_lf
93-
94- co_yield (chunk )
95- else
96- -- we're at the end of a chunk, read the next two
97- -- bytes to verify they are "\r\n".
98- local chunk , err = sock :receive (2 )
99- if not chunk then
100- co_yield (nil , " chunked_reader: failed to receive chunk terminator, err: " .. (err or " unknown" ))
101- end
102-
103- if chunk ~= " \r\n " then
104- co_yield (nil , " chunked_reader: bad chunk terminator" )
105- end
106-
107- eof = true
108- co_yield (" 0\r\n\r\n " )
109- break
110- end
111- until eof
112- end )
113- end
114-
115- -- chunked_writer writes response body reader to sock in the HTTP/1.x server response format,
22+ -- write_response writes response body reader to sock in the HTTP/1.x server response format,
11623-- including the status line, headers, body, and optional trailer.
117- function _M .chunked_writer (sock , res , chunksize )
24+ function _M .write_response (sock , res , chunksize )
11825 local bytes , err
11926 chunksize = chunksize or 65536
12027
@@ -163,4 +70,35 @@ function _M.chunked_writer(sock, res, chunksize)
16370 end
16471end
16572
73+ -- chunked_reader return a body reader that translates the data read from
74+ -- lua-resty-http client_body_reader to HTTP "chunked" format before returning it
75+ --
76+ -- The chunked reader return nil when the final 0-length chunk is read
77+ function _M .chunked_reader (sock , chunksize )
78+ chunksize = chunksize or 65536
79+ local eof = false
80+ local reader = httpc :get_client_body_reader (chunksize , sock )
81+ if not reader then
82+ return nil
83+ end
84+
85+ return function ()
86+ if eof then
87+ return nil
88+ end
89+
90+ local buffer , err = reader ()
91+ if err then
92+ return nil , err
93+ end
94+ if buffer then
95+ local chunk = string.format (" %x\r\n " , # buffer ) .. buffer .. cr_lf
96+ return chunk
97+ else
98+ eof = true
99+ return " 0\r\n\r\n "
100+ end
101+ end
102+ end
103+
166104return _M
0 commit comments