-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
parser.cr
45 lines (42 loc) · 1.58 KB
/
parser.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
module HTTP::FormData
class Parser
# Creates a new parser which parses *io* with multipart boundary *boundary*.
def initialize(io, boundary)
@multipart = MIME::Multipart::Parser.new(io, boundary)
end
# Parses the next form-data part and yields field name, io, `FileMetadata`,
# and raw headers.
#
# This method yields once instead of returning the values, because the IO
# object yielded to the block is only valid while the block is executing.
# The IO object will be closed as soon as the block returns. To store the
# content of the body part for longer than the block, the IO must be read
# into memory.
#
# ```
# require "http"
#
# form_data = "--aA40\r\nContent-Disposition: form-data; name=\"field1\"; filename=\"foo.txt\"; size=13\r\nContent-Type: text/plain\r\n\r\nfield data\r\n--aA40--"
# parser = HTTP::FormData::Parser.new(IO::Memory.new(form_data), "aA40")
# parser.next do |part|
# part.name # => "field1"
# part.body.gets_to_end # => "field data"
# part.filename # => "foo.txt"
# part.size # => 13
# part.headers["Content-Type"] # => "text/plain"
# end
# ```
def next
raise FormData::Error.new("Parser has already finished parsing") unless has_next?
while @multipart.has_next?
@multipart.next do |headers, io|
yield HTTP::FormData::Part.new(headers, io)
end
end
end
# True if `#next` can be called legally.
def has_next?
@multipart.has_next?
end
end
end