multipart_parser 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/multipart_parser/multipart_parser_c.c +28 -1
- data/lib/multipart_parser/version.rb +1 -1
- data/spec/multipart_parser_spec.rb +106 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dc18a37bf3a19151afcd3124b1cd17a3aea71da5
|
4
|
+
data.tar.gz: bfa0342a40514e68f5e8550ca3ad5f92b84dfe1c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 47060a489239ef727a32472ff2930d7ed227ce8ecdb437cdc09cdeaa430a0e6f525b2cfa91dc62ed8da0423d18bcff8d9715284e8d8f5b960c6ef22913ebd15c
|
7
|
+
data.tar.gz: 5c4934e4d5d787349c2d6ff8030923f0cf32d7fa9ffa06a0416b3c8fd2a1bfae89dd6c32095fef8e479c9d1dcde2ba7eaa4e79d5c31426dfa32da552becc6c73
|
@@ -50,6 +50,8 @@ enum state {
|
|
50
50
|
s_uninitialized = 1,
|
51
51
|
s_start,
|
52
52
|
s_start_boundary,
|
53
|
+
s_preamble,
|
54
|
+
s_preamble_almost_boundary,
|
53
55
|
s_header_field_start,
|
54
56
|
s_header_field,
|
55
57
|
s_headers_almost_done,
|
@@ -137,12 +139,37 @@ size_t multipart_parser_c_execute(multipart_parser_c* p, const multipart_parser_
|
|
137
139
|
p->state = s_header_field_start;
|
138
140
|
break;
|
139
141
|
}
|
142
|
+
|
143
|
+
/* if starting boundaru doesn't match, assume we are reading the preamble */
|
140
144
|
if (c != p->multipart_boundary[p->index]) {
|
141
|
-
|
145
|
+
p->index = 0;
|
146
|
+
|
147
|
+
if (c == CR) { /* smallest preable is CR LF */
|
148
|
+
|
149
|
+
p->state = s_preamble_almost_boundary;
|
150
|
+
} else {
|
151
|
+
p->state = s_preamble;
|
152
|
+
}
|
153
|
+
break;
|
142
154
|
}
|
155
|
+
|
143
156
|
p->index++;
|
144
157
|
break;
|
145
158
|
|
159
|
+
case s_preamble:
|
160
|
+
if (c == CR) {
|
161
|
+
p->state = s_preamble_almost_boundary;
|
162
|
+
}
|
163
|
+
break;
|
164
|
+
|
165
|
+
case s_preamble_almost_boundary:
|
166
|
+
if(c == LF) {
|
167
|
+
p->state = s_start_boundary;
|
168
|
+
} else {
|
169
|
+
p->state = s_preamble;
|
170
|
+
}
|
171
|
+
break;
|
172
|
+
|
146
173
|
case s_header_field_start:
|
147
174
|
multipart_log("s_header_field_start");
|
148
175
|
mark = i;
|
@@ -151,7 +151,113 @@ describe MultipartParser do
|
|
151
151
|
expect(MultipartParser::VERSION).not_to be nil
|
152
152
|
end
|
153
153
|
|
154
|
+
|
154
155
|
specify { expect { MultipartParser.new }.to raise_error(ArgumentError) }
|
155
156
|
|
157
|
+
context "multipart_parser.c" do
|
158
|
+
let(:parser) { MultipartParser.new "Boundary+17376C87E2579930" }
|
159
|
+
|
160
|
+
|
161
|
+
# https://www.ietf.org/rfc/rfc2046.txt
|
162
|
+
|
163
|
+
# boundary := 0*69<bchars> bcharsnospace
|
164
|
+
|
165
|
+
# bchars := bcharsnospace / " "
|
166
|
+
|
167
|
+
# bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" /
|
168
|
+
# "+" / "_" / "," / "-" / "." /
|
169
|
+
# "/" / ":" / "=" / "?"
|
170
|
+
|
171
|
+
# Overall, the body of a "multipart" entity may be specified as
|
172
|
+
# follows:
|
173
|
+
|
174
|
+
# dash-boundary := "--" boundary
|
175
|
+
# ; boundary taken from the value of
|
176
|
+
# ; boundary parameter of the
|
177
|
+
# ; Content-Type field.
|
178
|
+
|
179
|
+
# multipart-body := [preamble CRLF]
|
180
|
+
# dash-boundary transport-padding CRLF
|
181
|
+
# body-part *encapsulation
|
182
|
+
# close-delimiter transport-padding
|
183
|
+
# [CRLF epilogue]
|
184
|
+
|
185
|
+
|
186
|
+
# transport-padding := *LWSP-char
|
187
|
+
# ; Composers MUST NOT generate
|
188
|
+
# ; non-zero length transport
|
189
|
+
# ; padding, but receivers MUST
|
190
|
+
# ; be able to handle padding
|
191
|
+
# ; added by message transports.
|
192
|
+
|
193
|
+
# encapsulation := delimiter transport-padding
|
194
|
+
# CRLF body-part
|
195
|
+
|
196
|
+
# delimiter := CRLF dash-boundary
|
197
|
+
|
198
|
+
# close-delimiter := delimiter "--"
|
199
|
+
|
200
|
+
# preamble := discard-text
|
201
|
+
|
202
|
+
# epilogue := discard-text
|
203
|
+
|
204
|
+
# discard-text := *(*text CRLF) *text
|
205
|
+
# ; May be ignored or discarded.
|
206
|
+
|
207
|
+
# body-part := MIME-part-headers [CRLF *OCTET]
|
208
|
+
# ; Lines in a body-part must not start
|
209
|
+
# ; with the specified dash-boundary and
|
210
|
+
# ; the delimiter must not appear anywhere
|
211
|
+
# ; in the body part. Note that the
|
212
|
+
# ; semantics of a body-part differ from
|
213
|
+
# ; the semantics of a message, as
|
214
|
+
# ; described in the text.
|
215
|
+
|
216
|
+
# OCTET := <any 0-255 octet value>
|
217
|
+
|
218
|
+
it "allows a preamble" do
|
219
|
+
#https://www.ietf.org/rfc/rfc2046.txt section 5.1.1
|
220
|
+
|
221
|
+
# There appears to be room for additional information prior to the
|
222
|
+
# first boundary delimiter line and following the final boundary
|
223
|
+
# delimiter line. These areas should generally be left blank, and
|
224
|
+
# IMPLEMENTATIONS MUST IGNORE ANYTHING THAT APPEARS BEFORE THE FIRST
|
225
|
+
# BOUNDARY DELIMITER LINE OR AFTER THE LAST ONE.
|
226
|
+
|
227
|
+
parser.on_data = handler
|
228
|
+
|
229
|
+
expect(handler).to receive(:call).with("first frame")
|
230
|
+
|
231
|
+
parser << "preamble\r\n--Boundary+17376C87E2579930\r\n\r\nfirst frame\r\n";
|
232
|
+
parser << "--Boundary+17376C87E2579930--\r\n"
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
it "requires the preamble to be terminated with a CRLF" do
|
237
|
+
|
238
|
+
# multipart-body := [preamble CRLF]
|
239
|
+
# dash-boundary transport-padding CRLF
|
240
|
+
|
241
|
+
parser.on_data = handler
|
242
|
+
|
243
|
+
expect(handler).to_not receive(:call)
|
244
|
+
|
245
|
+
parser << "preamble--Boundary+17376C87E2579930\r\n\r\nfirst frame\r\n";
|
246
|
+
parser << "--Boundary+17376C87E2579930--\r\n"
|
247
|
+
|
248
|
+
end
|
249
|
+
|
250
|
+
it "handles a preamble that is only CRLF" do
|
251
|
+
|
252
|
+
parser.on_data = handler
|
253
|
+
|
254
|
+
expect(handler).to receive(:call).with("first frame")
|
255
|
+
|
256
|
+
parser << "\r\n--Boundary+17376C87E2579930\r\n\r\nfirst frame\r\n";
|
257
|
+
parser << "--Boundary+17376C87E2579930--\r\n"
|
258
|
+
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
156
262
|
end
|
157
263
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: multipart_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin Bryant
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-08-
|
11
|
+
date: 2015-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|