protocol-multipart 0.3.0 → 0.4.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 891a0cd8210426411b1b44e2304bdfb282ab907adf1f3bf53089b2ecd6407a44
4
- data.tar.gz: 7d24bcf5941c609e11dea28e1554e03c8696282a90f5d344c3aad580fa1484de
3
+ metadata.gz: 32d7a5d9ab53cbe80b179ea8ff2ac318415484eea858c4fc8f170c2bdcdb998a
4
+ data.tar.gz: 8540f4f11737134c960c1bcdd6303a2418c17ca6c754864e9b83204bc93410fb
5
5
  SHA512:
6
- metadata.gz: f515cd40482a06d977d689f2d43a917aef4193f5bbd2e23d0fe7b13fdc5984d42fbe5a8841736ac1d3deb1e9fa8ced71788ec17d5aacd4cedd2e17f3ac75219e
7
- data.tar.gz: e96bc422119c3c7001b3e6588281964ebab9445a6a52e8293ffb1035f01172a2f77e6497db43f36b2cd7cf4cbc319714c8352c4ae4946d8d9dbc0bc87e7d5441
6
+ metadata.gz: ce50fbd0c0bb2afc3396eba792684b2db2cfd839808bede5b0e38196966481d5924a1548dabbb6f42621b7afe0039ba8342e27c22ee815de142cc1e266ac7ee1
7
+ data.tar.gz: 534c8bbc606b71e2d532d861a7d1633c53e28188f7542c1d5aa5000b758715a2eecad9ab1ed047a0f69d6e9def50ba019fe0f0e3965cf979e3c99aa4b1d5affe
checksums.yaml.gz.sig CHANGED
Binary file
@@ -15,20 +15,20 @@ module Protocol
15
15
  CONTENT_TYPE = "multipart/form-data"
16
16
 
17
17
  # Initialize the form data parser.
18
- # @parameter maximum_field_size [Integer | Nil] The maximum size of each buffered field.
19
- # @parameter maximum_upload_size [Integer | Nil] The maximum size of each file upload.
20
- # @parameter maximum_total_size [Integer | Nil] The maximum combined size of all fields and uploads.
21
- # @parameter maximum_depth [Integer | Nil] The maximum depth of a bracketed form name.
18
+ # @parameter field_size_limit [Integer | Nil] The buffered field size limit.
19
+ # @parameter upload_size_limit [Integer | Nil] The file upload size limit.
20
+ # @parameter total_size_limit [Integer | Nil] The combined size limit for all fields and uploads.
21
+ # @parameter depth_limit [Integer | Nil] The bracketed form name depth limit.
22
22
  # @parameter options [Hash] Limits passed to the underlying multipart parser.
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, **options)
24
- if maximum_depth and maximum_depth < 0
23
+ def initialize(field_size_limit: FIELD_SIZE_LIMIT, upload_size_limit: UPLOAD_SIZE_LIMIT, total_size_limit: TOTAL_SIZE_LIMIT, depth_limit: Protocol::URL::FormData::Nested::DEPTH_LIMIT, **options)
24
+ if depth_limit and depth_limit < 0
25
25
  raise ArgumentError, "Form data limits must be non-negative!"
26
26
  end
27
27
 
28
- @maximum_field_size = maximum_field_size
29
- @maximum_upload_size = maximum_upload_size
30
- @maximum_total_size = maximum_total_size
31
- @maximum_depth = maximum_depth
28
+ @field_size_limit = field_size_limit
29
+ @upload_size_limit = upload_size_limit
30
+ @total_size_limit = total_size_limit
31
+ @depth_limit = depth_limit
32
32
  @options = options
33
33
  end
34
34
 
@@ -66,7 +66,7 @@ module Protocol
66
66
  def each(readable, boundary:)
67
67
  return to_enum(__method__, readable, boundary:) unless block_given?
68
68
 
69
- total_limit = ByteLimit.new(@maximum_total_size, name: :total_size)
69
+ total_size_limit = ByteLimit.new(@total_size_limit, name: :total_size)
70
70
  parser = Multipart::Parser.new(readable, boundary, **@options)
71
71
 
72
72
  parser.each do |part|
@@ -77,16 +77,16 @@ module Protocol
77
77
  end
78
78
 
79
79
  if filename = disposition["filename"]
80
- upload = Upload.new(part, filename, @maximum_upload_size, total_limit)
80
+ upload = Upload.new(part, filename, @upload_size_limit, total_size_limit)
81
81
  yield name, upload
82
82
  upload.discard
83
83
  else
84
- field_limit = ByteLimit.new(@maximum_field_size, name: :field_size)
84
+ field_size_limit = ByteLimit.new(@field_size_limit, name: :field_size)
85
85
  value = String.new.b
86
86
 
87
87
  part.each do |chunk|
88
- field_limit.consume(chunk.bytesize)
89
- total_limit.consume(chunk.bytesize)
88
+ field_size_limit.consume(chunk.bytesize)
89
+ total_size_limit.consume(chunk.bytesize)
90
90
  value << chunk
91
91
  end
92
92
 
@@ -98,7 +98,7 @@ module Protocol
98
98
  private
99
99
 
100
100
  def make_result
101
- return Protocol::URL::FormData::Nested.new(maximum_depth: @maximum_depth)
101
+ return Protocol::URL::FormData::Nested.new(depth_limit: @depth_limit)
102
102
  end
103
103
  end
104
104
  end
@@ -16,27 +16,27 @@ module Protocol
16
16
  class FormData < Mixed
17
17
  include Escape
18
18
 
19
- # The default maximum size of a buffered form field.
20
- MAXIMUM_FIELD_SIZE = 2 * 1024 * 1024
19
+ # The buffered form field size limit.
20
+ FIELD_SIZE_LIMIT = 2 * 1024 * 1024
21
21
 
22
- # The default maximum size of a streamed file upload.
23
- MAXIMUM_UPLOAD_SIZE = 128 * 1024 * 1024
22
+ # The streamed file upload size limit.
23
+ UPLOAD_SIZE_LIMIT = 128 * 1024 * 1024
24
24
 
25
- # The default maximum combined size of all form fields and file uploads.
26
- MAXIMUM_TOTAL_SIZE = 256 * 1024 * 1024
25
+ # The combined size limit for all form fields and file uploads.
26
+ TOTAL_SIZE_LIMIT = 256 * 1024 * 1024
27
27
 
28
28
  # A file upload yielded while parsing form data.
29
29
  class Upload
30
30
  # Initialize a streamed file upload.
31
31
  # @parameter part [Parser::Part] The underlying multipart part.
32
32
  # @parameter filename [String] The submitted filename.
33
- # @parameter maximum_size [Integer | Nil] The maximum upload size.
34
- # @parameter total_limit [ByteLimit] The shared form-data size limit.
35
- def initialize(part, filename, maximum_size, total_limit)
33
+ # @parameter size_limit [Integer | Nil] The upload size limit.
34
+ # @parameter total_size_limit [ByteLimit] The shared form-data size limit.
35
+ def initialize(part, filename, size_limit, total_size_limit)
36
36
  @part = part
37
37
  @filename = filename
38
- @limit = ByteLimit.new(maximum_size, name: :upload_size)
39
- @total_limit = total_limit
38
+ @size_limit = ByteLimit.new(size_limit, name: :upload_size)
39
+ @total_size_limit = total_size_limit
40
40
  end
41
41
 
42
42
  # The submitted filename.
@@ -49,7 +49,7 @@ module Protocol
49
49
 
50
50
  # The number of upload bytes consumed so far.
51
51
  def size
52
- @limit.size
52
+ @size_limit.size
53
53
  end
54
54
 
55
55
  # Whether the complete upload has been consumed.
@@ -63,8 +63,8 @@ module Protocol
63
63
  return to_enum(:each, chunk_size) unless block_given?
64
64
 
65
65
  @part.each(chunk_size) do |chunk|
66
- @limit.consume(chunk.bytesize)
67
- @total_limit.consume(chunk.bytesize)
66
+ @size_limit.consume(chunk.bytesize)
67
+ @total_size_limit.consume(chunk.bytesize)
68
68
  yield chunk
69
69
  end
70
70
 
@@ -14,17 +14,17 @@ module Protocol
14
14
  HEADER_PATTERN = /\A([!-9;-~]+):[ \t]*([^\x00-\x08\x0a-\x1f\x7f]*)\z/.freeze
15
15
  private_constant :HEADER_PATTERN
16
16
 
17
- # The default maximum number of preamble bytes before the first boundary.
18
- MAXIMUM_PREAMBLE_SIZE = 64 * 1024
17
+ # The preamble size limit.
18
+ PREAMBLE_SIZE_LIMIT = 64 * 1024
19
19
 
20
- # The default maximum number of header bytes in each part.
21
- MAXIMUM_HEADER_SIZE = 64 * 1024
20
+ # The header size limit for each part.
21
+ HEADER_SIZE_LIMIT = 64 * 1024
22
22
 
23
- # The default maximum number of headers in each part.
24
- MAXIMUM_HEADER_COUNT = 64
23
+ # The header count limit for each part.
24
+ HEADER_COUNT_LIMIT = 64
25
25
 
26
- # The default maximum number of parts.
27
- MAXIMUM_PART_COUNT = 128
26
+ # The part count limit.
27
+ PART_COUNT_LIMIT = 128
28
28
 
29
29
  # Represents a single part within a multipart message.
30
30
  class Part
@@ -163,12 +163,12 @@ module Protocol
163
163
  #
164
164
  # @parameter readable [IO, IO::Stream] The readable stream containing multipart data.
165
165
  # @parameter boundary [String] The boundary string that separates the parts.
166
- # @parameter maximum_preamble_size [Integer | Nil] The maximum preamble size, or nil for no limit.
167
- # @parameter maximum_header_size [Integer | Nil] The maximum header size per part, or nil for no limit.
168
- # @parameter maximum_header_count [Integer | Nil] The maximum header count per part, or nil for no limit.
169
- # @parameter maximum_part_count [Integer | Nil] The maximum part count, or nil for no limit.
170
- def initialize(readable, boundary, maximum_preamble_size: MAXIMUM_PREAMBLE_SIZE, maximum_header_size: MAXIMUM_HEADER_SIZE, maximum_header_count: MAXIMUM_HEADER_COUNT, maximum_part_count: MAXIMUM_PART_COUNT)
171
- limits = [maximum_preamble_size, maximum_header_size, maximum_header_count, maximum_part_count]
166
+ # @parameter preamble_size_limit [Integer | Nil] The preamble size limit, or nil for no limit.
167
+ # @parameter header_size_limit [Integer | Nil] The header size limit per part, or nil for no limit.
168
+ # @parameter header_count_limit [Integer | Nil] The header count limit per part, or nil for no limit.
169
+ # @parameter part_count_limit [Integer | Nil] The part count limit, or nil for no limit.
170
+ def initialize(readable, boundary, preamble_size_limit: PREAMBLE_SIZE_LIMIT, header_size_limit: HEADER_SIZE_LIMIT, header_count_limit: HEADER_COUNT_LIMIT, part_count_limit: PART_COUNT_LIMIT)
171
+ limits = [preamble_size_limit, header_size_limit, header_count_limit, part_count_limit]
172
172
 
173
173
  if limits.any?{|limit| limit and limit < 0}
174
174
  raise ArgumentError, "Multipart limits must be non-negative!"
@@ -176,10 +176,10 @@ module Protocol
176
176
 
177
177
  @readable = IO::Stream(readable)
178
178
  @boundary = boundary
179
- @maximum_preamble_size = maximum_preamble_size
180
- @maximum_header_size = maximum_header_size
181
- @maximum_header_count = maximum_header_count
182
- @maximum_part_count = maximum_part_count
179
+ @preamble_size_limit = preamble_size_limit
180
+ @header_size_limit = header_size_limit
181
+ @header_count_limit = header_count_limit
182
+ @part_count_limit = part_count_limit
183
183
 
184
184
  @boundary_marker = "--#{@boundary}\r\n".freeze
185
185
  end
@@ -195,12 +195,12 @@ module Protocol
195
195
 
196
196
  # Read lines until we find the first boundary:
197
197
  while true
198
- if line = read_line(preamble_size, @maximum_preamble_size, allowance: @boundary_marker.bytesize, chomp: false)
198
+ if line = read_line(preamble_size, @preamble_size_limit, allowance: @boundary_marker.bytesize, chomp: false)
199
199
  if line == @boundary_marker
200
200
  break
201
201
  else
202
202
  preamble_size += line.bytesize
203
- check_limit(:preamble_size, preamble_size, @maximum_preamble_size)
203
+ check_limit(:preamble_size, preamble_size, @preamble_size_limit)
204
204
  end
205
205
  else
206
206
  # End of stream reached without finding boundary:
@@ -212,7 +212,7 @@ module Protocol
212
212
 
213
213
  while true
214
214
  part_count += 1
215
- check_limit(:part_count, part_count, @maximum_part_count)
215
+ check_limit(:part_count, part_count, @part_count_limit)
216
216
 
217
217
  part = read_part
218
218
  break unless part
@@ -234,18 +234,18 @@ module Protocol
234
234
 
235
235
  private
236
236
 
237
- def read_line(size, maximum, allowance: 0, chomp:)
238
- if maximum
239
- limit = maximum - size + allowance + 1
237
+ def read_line(size, limit, allowance: 0, chomp:)
238
+ if limit
239
+ limit = limit - size + allowance + 1
240
240
  return @readable.gets("\r\n", limit, chomp: chomp)
241
241
  else
242
242
  return @readable.gets("\r\n", chomp: chomp)
243
243
  end
244
244
  end
245
245
 
246
- def check_limit(name, value, maximum)
247
- if maximum and value > maximum
248
- raise RangeError, "Multipart #{name} exceeded limit of #{maximum}!"
246
+ def check_limit(name, value, limit)
247
+ if limit and value > limit
248
+ raise RangeError, "Multipart #{name} exceeded limit of #{limit}!"
249
249
  end
250
250
  end
251
251
 
@@ -255,18 +255,18 @@ module Protocol
255
255
  header_count = 0
256
256
 
257
257
  # Read headers until empty line
258
- while line = read_line(header_size, @maximum_header_size, allowance: 2, chomp: true)
258
+ while line = read_line(header_size, @header_size_limit, allowance: 2, chomp: true)
259
259
  if line.empty?
260
260
  break # End of headers
261
261
  end
262
262
 
263
263
  header_size += line.bytesize + 2
264
- check_limit(:header_size, header_size, @maximum_header_size)
264
+ check_limit(:header_size, header_size, @header_size_limit)
265
265
 
266
266
  if match = line.match(HEADER_PATTERN)
267
267
  # Parse header line (name: value)
268
268
  header_count += 1
269
- check_limit(:header_count, header_count, @maximum_header_count)
269
+ check_limit(:header_count, header_count, @header_count_limit)
270
270
 
271
271
  fields << [match[1], match[2].strip]
272
272
  else
@@ -5,6 +5,6 @@
5
5
 
6
6
  module Protocol
7
7
  module Multipart
8
- VERSION = "0.3.0"
8
+ VERSION = "0.4.0"
9
9
  end
10
10
  end
data/readme.md CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  Please see the [project releases](https://socketry.github.io/protocol-multipart/releases/index) for all releases.
8
8
 
9
+ ### v0.4.0
10
+
11
+ - Use consistent limit naming for multipart parser constraints.
12
+
9
13
  ### v0.3.0
10
14
 
11
15
  - Add a configurable `Protocol::Multipart::FormData::Parser` which parses a streaming body and explicit boundary into nested arguments.
data/releases.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Releases
2
2
 
3
+ ## v0.4.0
4
+
5
+ - Use consistent limit naming for multipart parser constraints.
6
+
3
7
  ## v0.3.0
4
8
 
5
9
  - Add a configurable `Protocol::Multipart::FormData::Parser` which parses a streaming body and explicit boundary into nested arguments.
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protocol-multipart
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
metadata.gz.sig CHANGED
Binary file