Class: Protocol::Multipart::Parser::Part
- Inherits:
-
Object
- Object
- Protocol::Multipart::Parser::Part
- Defined in:
- lib/protocol/multipart/parser.rb
Overview
Represents a single part within a multipart message.
Instance Attribute Summary collapse
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
- #The headers associated with this part.(headersassociatedwiththispart.) ⇒ Object readonly
Instance Method Summary collapse
-
#closing_boundary? ⇒ Boolean
Checks if this part ends with a closing boundary.
-
#discard ⇒ Object
Efficiently discards all data until the next boundary is found.
-
#each(chunk_size = 8192) ⇒ Object
Iterate through the part content in chunks.
-
#ended? ⇒ Boolean
Checks if this part has been completely read.
-
#finish ⇒ Object
Finishes reading this part's data and advances to the next boundary.
-
#initialize(readable, headers, boundary) ⇒ Part
constructor
Initialize a new part with a readable stream, headers, and a boundary string.
-
#read_boundary_suffix ⇒ Object
Reads the suffix after a boundary to determine if it's a closing boundary.
-
#read_empty_boundary? ⇒ Boolean
Checks if the next content is an empty boundary (part with no content).
Constructor Details
#initialize(readable, headers, boundary) ⇒ Part
Initialize a new part with a readable stream, headers, and a boundary string.
36 37 38 39 40 41 42 |
# File 'lib/protocol/multipart/parser.rb', line 36 def initialize(readable, headers, boundary) @readable = readable @boundary = boundary @headers = headers @ended = false @is_closing = false end |
Instance Attribute Details
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
45 46 47 |
# File 'lib/protocol/multipart/parser.rb', line 45 def headers @headers end |
#The headers associated with this part.(headersassociatedwiththispart.) ⇒ Object (readonly)
45 |
# File 'lib/protocol/multipart/parser.rb', line 45 attr_reader :headers |
Instance Method Details
#closing_boundary? ⇒ Boolean
Checks if this part ends with a closing boundary. A closing boundary indicates that this is the last part in the multipart message.
157 158 159 |
# File 'lib/protocol/multipart/parser.rb', line 157 def closing_boundary? @is_closing || (@readable.nil? && @is_closing) end |
#discard ⇒ Object
Efficiently discards all data until the next boundary is found. This is used to skip parts without reading their content into memory.
134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/protocol/multipart/parser.rb', line 134 def discard # Efficiently discard all data until boundary return unless @readable # Discard data until boundary @readable.discard_until("\r\n--#{@boundary}") self.read_boundary_suffix return nil end |
#each(chunk_size = 8192) ⇒ Object
Iterate through the part content in chunks.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/protocol/multipart/parser.rb', line 51 def each(chunk_size = 8192) return to_enum(:each, chunk_size) unless block_given? return unless @readable boundary_marker = "\r\n--#{@boundary}" # Stream data in chunks using read_until with a limit while @readable if chunk = @readable.read_until(boundary_marker, limit: chunk_size, chomp: true) # We found the boundary, check if it's a closing boundary: if suffix = @readable.read_until("\r\n", chomp: true) @is_closing = (suffix == "--") @ended = true @readable = nil else @readable = nil raise EOFError, "Unexpected end of stream while reading part data!" end else chunk = @readable.read(chunk_size) end if chunk yield chunk unless chunk.empty? else # No more data to read, break the loop: break end end end |
#ended? ⇒ Boolean
Checks if this part has been completely read.
149 150 151 |
# File 'lib/protocol/multipart/parser.rb', line 149 def ended? @ended end |
#finish ⇒ Object
Finishes reading this part's data and advances to the next boundary.
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/protocol/multipart/parser.rb', line 119 def finish return unless @readable # Read all data until boundary data = @readable.read_until("\r\n--#{@boundary}", chomp: true) self.read_boundary_suffix return data end |
#read_boundary_suffix ⇒ Object
Reads the suffix after a boundary to determine if it's a closing boundary.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/protocol/multipart/parser.rb', line 99 def read_boundary_suffix # Read the rest of the boundary line to check if it's closing: boundary_suffix = @readable.read(2) if boundary_suffix == "--" @is_closing = true @ended = true @readable = nil elsif boundary_suffix == "\r\n" @is_closing = false @ended = true @readable = nil else @readable = nil raise EOFError, "Unexpected end of stream while reading part data!" end end |
#read_empty_boundary? ⇒ Boolean
Checks if the next content is an empty boundary (part with no content).
86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/protocol/multipart/parser.rb', line 86 def read_empty_boundary? boundary_marker = "--#{@boundary}" if @readable.peek(boundary_marker.bytesize) == boundary_marker @readable.read(boundary_marker.bytesize) self.read_boundary_suffix return true end return false end |