@@ -7,6 +7,9 @@ local match = string.match
77local setmetatable = setmetatable
88local type = type
99local ngx_var = ngx .var
10+ local ngx_init_body = ngx .req .init_body
11+ local ngx_finish_body = ngx .req .finish_body
12+ local ngx_append_body = ngx .req .append_body
1013-- local print = print
1114
1215
@@ -21,11 +24,57 @@ local STATE_READING_HEADER = 2
2124local STATE_READING_BODY = 3
2225local STATE_EOF = 4
2326
24-
2527local mt = { __index = _M }
2628
2729local state_handlers
2830
31+ local function wrapped_receiveuntil (self , until_str )
32+ local iter , err_outer = self :old_receiveuntil (until_str )
33+ if iter == nil then
34+ ngx_finish_body ()
35+ end
36+
37+ local function wrapped (size )
38+ local ret , err = iter (size )
39+ if ret then
40+ ngx_append_body (ret )
41+ end
42+
43+ -- non-nil ret for call with no size or successful size call and nil ret
44+ if (not size and ret ) or (size and not ret and not err ) then
45+ ngx_append_body (until_str )
46+ end
47+ return ret , err
48+ end
49+
50+ return wrapped , err_outer
51+ end
52+
53+
54+ local function wrapped_receive (self , arg )
55+ local ret , err , partial = self :old_receive (arg )
56+ if ret then
57+ ngx_append_body (ret )
58+
59+ elseif partial then
60+ ngx_append_body (partial )
61+ end
62+
63+ if ret == nil then
64+ ngx_finish_body ()
65+ end
66+
67+ return ret , err
68+ end
69+
70+
71+ local function req_socket_body_collector (sock )
72+ sock .old_receiveuntil = sock .receiveuntil
73+ sock .old_receive = sock .receive
74+ sock .receiveuntil = wrapped_receiveuntil
75+ sock .receive = wrapped_receive
76+ end
77+
2978
3079local function get_boundary ()
3180 local header = ngx_var .content_type
@@ -46,7 +95,7 @@ local function get_boundary()
4695end
4796
4897
49- function _M .new (self , chunk_size , max_line_size )
98+ function _M .new (self , chunk_size , max_line_size , preserve_body )
5099 local boundary = get_boundary ()
51100
52101 -- print("boundary: ", boundary)
@@ -62,6 +111,11 @@ function _M.new(self, chunk_size, max_line_size)
62111 return nil , err
63112 end
64113
114+ if preserve_body then
115+ ngx_init_body (chunk_size )
116+ req_socket_body_collector (sock )
117+ end
118+
65119 local read2boundary , err = sock :receiveuntil (" --" .. boundary )
66120 if not read2boundary then
67121 return nil , err
@@ -79,7 +133,8 @@ function _M.new(self, chunk_size, max_line_size)
79133 read2boundary = read2boundary ,
80134 read_line = read_line ,
81135 boundary = boundary ,
82- state = STATE_BEGIN
136+ state = STATE_BEGIN ,
137+ preserve_body = preserve_body
83138 }, mt )
84139end
85140
@@ -104,6 +159,10 @@ local function discard_line(self)
104159
105160 local dummy , err = read_line (1 )
106161 if dummy then
162+ if self .preserve_body then
163+ ngx_finish_body ()
164+ end
165+
107166 return nil , " line too long: " .. line .. dummy .. " ..."
108167 end
109168
@@ -179,6 +238,10 @@ local function read_header(self)
179238
180239 local dummy , err = read_line (1 )
181240 if dummy then
241+ if self .preserve_body then
242+ ngx_finish_body ()
243+ end
244+
182245 return nil , nil , " line too long: " .. line .. dummy .. " ..."
183246 end
184247
0 commit comments