Class: Protocol::Multipart::FormData::Parser
- Inherits:
-
Object
- Object
- Protocol::Multipart::FormData::Parser
- Defined in:
- lib/protocol/multipart/form_data/parser.rb
Overview
A configurable parser for multipart/form-data bodies.
Constant Summary collapse
- CONTENT_TYPE =
"multipart/form-data"
Instance Method Summary collapse
-
#each(readable, boundary:) ⇒ Object
Incrementally enumerate multipart form data.
-
#initialize(maximum_field_size: MAXIMUM_FIELD_SIZE, maximum_upload_size: MAXIMUM_UPLOAD_SIZE, maximum_total_size: MAXIMUM_TOTAL_SIZE, maximum_depth: Protocol::URL::FormData::Nested::MAXIMUM_DEPTH, **options) ⇒ Parser
constructor
Initialize the form data parser.
-
#parse(readable, result = make_result, boundary:) ⇒ Object
Parse multipart form data into a nested hash.
Constructor Details
#initialize(maximum_field_size: MAXIMUM_FIELD_SIZE, maximum_upload_size: MAXIMUM_UPLOAD_SIZE, maximum_total_size: MAXIMUM_TOTAL_SIZE, maximum_depth: Protocol::URL::FormData::Nested::MAXIMUM_DEPTH, **options) ⇒ Parser
Initialize the form data parser.
23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/protocol/multipart/form_data/parser.rb', line 23 def initialize(maximum_field_size: MAXIMUM_FIELD_SIZE, maximum_upload_size: MAXIMUM_UPLOAD_SIZE, maximum_total_size: MAXIMUM_TOTAL_SIZE, maximum_depth: Protocol::URL::FormData::Nested::MAXIMUM_DEPTH, **) if maximum_depth and maximum_depth < 0 raise ArgumentError, "Form data limits must be non-negative!" end @maximum_field_size = maximum_field_size @maximum_upload_size = maximum_upload_size @maximum_total_size = maximum_total_size @maximum_depth = maximum_depth @options = end |
Instance Method Details
#each(readable, boundary:) ⇒ Object
Incrementally enumerate multipart form data.
Fields are yielded as strings. File uploads are yielded as streaming Upload instances and are only readable during the corresponding block invocation.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/protocol/multipart/form_data/parser.rb', line 66 def each(readable, boundary:) return to_enum(__method__, readable, boundary:) unless block_given? total_limit = ByteLimit.new(@maximum_total_size, name: :total_size) parser = Multipart::Parser.new(readable, boundary, **@options) parser.each do |part| disposition = part.headers["content-disposition"] unless disposition&.type == "form-data" and name = disposition["name"] raise ArgumentError, "Multipart form part is missing a form-data name!" end if filename = disposition["filename"] upload = Upload.new(part, filename, @maximum_upload_size, total_limit) yield name, upload upload.discard else field_limit = ByteLimit.new(@maximum_field_size, name: :field_size) value = String.new.b part.each do |chunk| field_limit.consume(chunk.bytesize) total_limit.consume(chunk.bytesize) value << chunk end yield name, value end end end |
#parse(readable, result = make_result, boundary:) ⇒ Object
Parse multipart form data into a nested hash.
When a block is given, each value is passed through the block before assignment. The value returned by the block is assigned to the result. Uploads require a block because they must be consumed before parsing advances to the next part.
44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/protocol/multipart/form_data/parser.rb', line 44 def parse(readable, result = make_result, boundary:) each(readable, boundary:) do |name, value| if block_given? value = yield(name, value) elsif value.is_a?(Upload) raise ArgumentError, "A block is required to consume file uploads!" end result.add(name, value) end return result.to_h end |