Skip to content

Commit 978a425

Browse files
suikabreakerStarlightIbuki
authored andcommitted
feature: lf_line_break
1 parent 73c8984 commit 978a425

File tree

2 files changed

+95
-5
lines changed

2 files changed

+95
-5
lines changed

lib/resty/upload.lua

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,26 @@ local function get_boundary()
9494
return match(header, ";%s*boundary=([^\",;]+)")
9595
end
9696

97+
local function read_line_construct(sock, lf_line_break)
98+
local line_end = "\r\n"
99+
if lf_line_break then
100+
line_end = "\n"
101+
end
102+
local read_line, err = sock:receiveuntil(line_end)
103+
if lf_line_break and read_line then
104+
return function (arg)
105+
local ret, err_inner = read_line(arg)
106+
if ret and ret:sub(-1,-1) == '\r' then
107+
ret = ret:sub(1,-2)
108+
end
109+
return ret, err_inner
110+
end
111+
else
112+
return read_line, err
113+
end
114+
end
97115

98-
function _M.new(self, chunk_size, max_line_size, preserve_body)
116+
function _M.new(self, chunk_size, max_line_size, preserve_body, lf_line_break)
99117
local boundary = get_boundary()
100118

101119
-- print("boundary: ", boundary)
@@ -121,7 +139,7 @@ function _M.new(self, chunk_size, max_line_size, preserve_body)
121139
return nil, err
122140
end
123141

124-
local read_line, err = sock:receiveuntil("\r\n")
142+
local read_line, err = read_line_construct(sock, lf_line_break)
125143
if not read_line then
126144
return nil, err
127145
end
@@ -134,7 +152,8 @@ function _M.new(self, chunk_size, max_line_size, preserve_body)
134152
read_line = read_line,
135153
boundary = boundary,
136154
state = STATE_BEGIN,
137-
preserve_body = preserve_body
155+
preserve_body = preserve_body,
156+
lf_line_break = lf_line_break
138157
}, mt)
139158
end
140159

@@ -202,7 +221,17 @@ local function read_body_part(self)
202221
if not chunk then
203222
local sock = self.sock
204223

205-
local data = sock:receive(2)
224+
local data, err = sock:receive(1)
225+
226+
-- partial lookahead: -- or CRLF?
227+
if data == "-" or data == "\r" then
228+
local next
229+
next, err = sock:receive(1)
230+
if next then
231+
data = data .. next
232+
end
233+
end
234+
206235
if data == "--" then
207236
local ok, err = discard_rest(self)
208237
if not ok then
@@ -213,7 +242,7 @@ local function read_body_part(self)
213242
return "part_end"
214243
end
215244

216-
if data ~= "\r\n" then
245+
if data ~= "\r\n" and not (data == "\n" and self.lf_line_break) then
217246
local ok, err = discard_line(self)
218247
if not ok then
219248
return nil, nil, err

t/sanity.t

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -770,3 +770,64 @@ remain body length: 336
770770

771771
--- no_error_log
772772
[error]
773+
774+
775+
776+
=== TEST 13: LF line break
777+
--- http_config eval: $::HttpConfig
778+
--- config
779+
location /t {
780+
content_by_lua '
781+
local upload = require "resty.upload"
782+
local ljson = require "ljson"
783+
784+
local form = upload:new(5, nil, nil, true)
785+
786+
form:set_timeout(1000) -- 1 sec
787+
788+
while true do
789+
local typ, res, err = form:read()
790+
if not typ then
791+
ngx.say("failed to read: ", err)
792+
return
793+
end
794+
795+
ngx.say("read: ", ljson.encode({typ, res}))
796+
797+
if typ == "eof" then
798+
break
799+
end
800+
end
801+
802+
local typ, res, err = form:read()
803+
ngx.say("read: ", ljson.encode({typ, res}))
804+
';
805+
}
806+
--- more_headers
807+
Content-Type: multipart/form-data; boundary=---------------------------820127721219505131303151179
808+
--- request eval
809+
qq{POST /t\n-----------------------------820127721219505131303151179\r
810+
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
811+
Content-Type: text/plain\r
812+
\r
813+
Hello, world\n-----------------------------820127721219505131303151179
814+
Content-Disposition: form-data; name="test"\r
815+
\r
816+
value\r
817+
\r\n-----------------------------820127721219505131303151179--\r
818+
}
819+
--- response_body
820+
read: ["header",["Content-Disposition","form-data; name=\"file1\"; filename=\"a.txt\"","Content-Disposition: form-data; name=\"file1\"; filename=\"a.txt\""]]
821+
read: ["header",["Content-Type","text/plain","Content-Type: text/plain"]]
822+
read: ["body","Hello"]
823+
read: ["body",", wor"]
824+
read: ["body","ld"]
825+
read: ["part_end"]
826+
read: ["header",["Content-Disposition","form-data; name=\"test\"","Content-Disposition: form-data; name=\"test\""]]
827+
read: ["body","value"]
828+
read: ["body","\r\n"]
829+
read: ["part_end"]
830+
read: ["eof"]
831+
read: ["eof"]
832+
--- no_error_log
833+
[error]

0 commit comments

Comments
 (0)