@@ -52,3 +52,268 @@ failed to receive: closed [d]
52
52
-- - no_error_log
53
53
[error]
54
54
55
+
56
+
57
+ === TEST 2 : multipart rfc sample (just partial streaming)
58
+ -- - config
59
+ location / t {
60
+ content_by_lua '
61
+ local sock, err = ngx.req.socket()
62
+ if sock then
63
+ ngx.say("got the request socket")
64
+ else
65
+ ngx.say("failed to get the request socket: ", err)
66
+ end
67
+
68
+ local boundary
69
+ local header = ngx.var.http_content_type
70
+ local m = ngx.re.match(header, [[; +boundary=(?:"(.*?)"|(\\ w+))]], "jo")
71
+ if m then
72
+ boundary = m[1] or m[2]
73
+
74
+ else
75
+ ngx.say("invalid content-type header")
76
+ return
77
+ end
78
+
79
+ local read_to_boundary = sock:receiveuntil("\\ r\\ n--" .. boundary)
80
+ local read_line = sock:receiveuntil("\\ r\\ n")
81
+
82
+ local data, err, part = read_to_boundary()
83
+ if data then
84
+ ngx.say("preamble: [" .. data .. "]")
85
+ else
86
+ ngx.say("failed to read the first boundary: ", err)
87
+ return
88
+ end
89
+
90
+ local i = 1
91
+ while true do
92
+ local line, err = read_line()
93
+
94
+ if not line then
95
+ ngx.say("failed to read post-boundary line: ", err)
96
+ return
97
+ end
98
+
99
+ m = ngx.re.match(line, "--$", "jo")
100
+ if m then
101
+ ngx.say("found the end of the stream")
102
+ return
103
+ end
104
+
105
+ while true do
106
+ local line, err = read_line()
107
+ if not line then
108
+ ngx.say("failed to read part ", i, " header: ", err)
109
+ return
110
+ end
111
+
112
+ if line == "" then
113
+ -- the header part completes
114
+ break
115
+ end
116
+
117
+ ngx.say("part ", i, " header: [", line, "]")
118
+ end
119
+
120
+ local data, err, part = read_to_boundary()
121
+ if data then
122
+ ngx.say("part ", i, " body: [" .. data .. "]")
123
+ else
124
+ ngx.say("failed to read part ", i + 1, " boundary: ", err)
125
+ return
126
+ end
127
+
128
+ i = i + 1
129
+ end
130
+ ' ;
131
+ }
132
+ -- - request eval
133
+ " POST /t
134
+ This is the preamble. It is to be ignored, though it
135
+ is a handy place for mail composers to include an
136
+ explanatory note to non-MIME compliant readers.\r
137
+ --simple boundary\r
138
+ \r
139
+ This is implicitly typed plain ASCII text.
140
+ It does NOT end with a linebreak.\r
141
+ --simple boundary\r
142
+ Content-type: text/plain; charset=us-ascii\r
143
+ \r
144
+ This is explicitly typed plain ASCII text.
145
+ It DOES end with a linebreak.
146
+ \r
147
+ --simple boundary--\r
148
+ This is the epilogue. It is also to be ignored.
149
+ "
150
+ -- - more_headers
151
+ Content-Type: multipart/ mixed; boundary= " simple boundary"
152
+ -- - response_body
153
+ got the request socket
154
+ preamble: [This is the preamble. It is to be ignored, though it
155
+ is a handy place for mail composers to include an
156
+ explanatory note to non-MIME compliant readers. ]
157
+ part 1 body : [This is implicitly typed plain ASCII text.
158
+ It does NOT end with a linebreak. ]
159
+ part 2 header: [Content-type: text/ plain; charset= us-ascii]
160
+ part 2 body : [This is explicitly typed plain ASCII text.
161
+ It DOES end with a linebreak.
162
+ ]
163
+ found the end of the stream
164
+ -- - no_error_log
165
+ [error]
166
+
167
+
168
+
169
+ === TEST 3 : multipart rfc sample (completely streaming)
170
+ -- - config
171
+ location / t {
172
+ content_by_lua '
173
+ local sock, err = ngx.req.socket()
174
+ if sock then
175
+ ngx.say("got the request socket")
176
+ else
177
+ ngx.say("failed to get the request socket: ", err)
178
+ end
179
+
180
+ local boundary
181
+ local header = ngx.var.http_content_type
182
+ local m = ngx.re.match(header, [[; +boundary=(?:"(.*?)"|(\\ w+))]], "jo")
183
+ if m then
184
+ boundary = m[1] or m[2]
185
+
186
+ else
187
+ ngx.say("invalid content-type header")
188
+ return
189
+ end
190
+
191
+ local read_to_boundary = sock:receiveuntil("\\ r\\ n--" .. boundary)
192
+ local read_line = sock:receiveuntil("\\ r\\ n")
193
+
194
+ local preamble = ""
195
+ while true do
196
+ local data, err, part = read_to_boundary(1)
197
+ if data then
198
+ preamble = preamble .. data
199
+
200
+ elseif not err then
201
+ break
202
+
203
+ else
204
+ ngx.say("failed to read the first boundary: ", err)
205
+ return
206
+ end
207
+ end
208
+
209
+ ngx.say("preamble: [" .. preamble .. "]")
210
+
211
+ local i = 1
212
+ while true do
213
+ local line, err = read_line(50)
214
+
215
+ if not line and err then
216
+ ngx.say("1: failed to read post-boundary line: ", err)
217
+ return
218
+ end
219
+
220
+ if line then
221
+ local dummy
222
+ dummy, err = read_line(1)
223
+ if err then
224
+ ngx.say("2: failed to read post-boundary line: ", err)
225
+ return
226
+ end
227
+
228
+ if dummy then
229
+ ngx.say("bad post-boundary line: ", dummy)
230
+ return
231
+ end
232
+
233
+ m = ngx.re.match(line, "--$", "jo")
234
+ if m then
235
+ ngx.say("found the end of the stream")
236
+ return
237
+ end
238
+ end
239
+
240
+ while true do
241
+ local line, err = read_line(50)
242
+ if not line and err then
243
+ ngx.say("failed to read part ", i, " header: ", err)
244
+ return
245
+ end
246
+
247
+ if line then
248
+ local line, err = read_line(1)
249
+ if line or err then
250
+ ngx.say("error")
251
+ return
252
+ end
253
+ end
254
+
255
+ if line == "" then
256
+ -- the header part completes
257
+ break
258
+ end
259
+
260
+ ngx.say("part ", i, " header: [", line, "]")
261
+ end
262
+
263
+ local body = ""
264
+
265
+ while true do
266
+ local data, err, part = read_to_boundary(1)
267
+ if data then
268
+ body = body .. data
269
+
270
+ elseif err then
271
+ ngx.say("failed to read part ", i + 1, " boundary: ", err)
272
+ return
273
+
274
+ else
275
+ break
276
+ end
277
+ end
278
+
279
+ ngx.say("part ", i, " body: [" .. body .. "]")
280
+
281
+ i = i + 1
282
+ end
283
+ ' ;
284
+ }
285
+ -- - request eval
286
+ " POST /t
287
+ This is the preamble. It is to be ignored, though it
288
+ is a handy place for mail composers to include an
289
+ explanatory note to non-MIME compliant readers.\r
290
+ --simple boundary\r
291
+ \r
292
+ This is implicitly typed plain ASCII text.
293
+ It does NOT end with a linebreak.\r
294
+ --simple boundary\r
295
+ Content-type: text/plain; charset=us-ascii\r
296
+ \r
297
+ This is explicitly typed plain ASCII text.
298
+ It DOES end with a linebreak.
299
+ \r
300
+ --simple boundary--\r
301
+ This is the epilogue. It is also to be ignored.
302
+ "
303
+ -- - more_headers
304
+ Content-Type: multipart/ mixed; boundary= " simple boundary"
305
+ -- - response_body
306
+ got the request socket
307
+ preamble: [This is the preamble. It is to be ignored, though it
308
+ is a handy place for mail composers to include an
309
+ explanatory note to non-MIME compliant readers. ]
310
+ part 1 body : [This is implicitly typed plain ASCII text.
311
+ It does NOT end with a linebreak. ]
312
+ part 2 header: [Content-type: text/ plain; charset= us-ascii]
313
+ part 2 body : [This is explicitly typed plain ASCII text.
314
+ It DOES end with a linebreak.
315
+ ]
316
+ found the end of the stream
317
+ -- - no_error_log
318
+ [error]
319
+
0 commit comments