Class: Rack::Multipart::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/multipart/parser.rb

Defined Under Namespace

Classes: BoundedIO, Collector, MultipartInfo

Constant Summary collapse

BUFSIZE =
16384
TEXT_PLAIN =
"text/plain"
TEMPFILE_FACTORY =
lambda { |filename, content_type|
  Tempfile.new(["RackMultipart", ::File.extname(filename)])
}
EMPTY =
MultipartInfo.new(nil, [])

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(boundary, tempfile, bufsize, query_parser) ⇒ Parser

Returns a new instance of Parser.



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/rack/multipart/parser.rb', line 167

def initialize(boundary, tempfile, bufsize, query_parser)
  @buf            = "".force_encoding(Encoding::ASCII_8BIT)

  @query_parser   = query_parser
  @params         = query_parser.make_params
  @boundary       = "--#{boundary}"
  @boundary_size  = @boundary.bytesize + EOL.size
  @bufsize        = bufsize

  @rx = /(?:#{EOL})?#{Regexp.quote(@boundary)}(#{EOL}|--)/n
  @full_boundary = @boundary
  @end_boundary = @boundary + '--'
  @state = :FAST_FORWARD
  @mime_index = 0
  @collector = Collector.new tempfile
end

Instance Attribute Details

#stateObject (readonly)

Returns the value of attribute state.



165
166
167
# File 'lib/rack/multipart/parser.rb', line 165

def state
  @state
end

Class Method Details

.parse(io, content_length, content_type, tmpfile, bufsize, qp) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/rack/multipart/parser.rb', line 59

def self.parse(io, content_length, content_type, tmpfile, bufsize, qp)
  return EMPTY if 0 == content_length

  boundary = parse_boundary content_type
  return EMPTY unless boundary

  io = BoundedIO.new(io, content_length) if content_length

  parser = new(boundary, tmpfile, bufsize, qp)
  parser.on_read io.read(bufsize), io.eof?

  loop do
    break if parser.state == :DONE
    parser.on_read io.read(bufsize), io.eof?
  end

  io.rewind
  parser.result
end

.parse_boundary(content_type) ⇒ Object



52
53
54
55
56
57
# File 'lib/rack/multipart/parser.rb', line 52

def self.parse_boundary(content_type)
  return unless content_type
  data = content_type.match(MULTIPART)
  return unless data
  data[1]
end

Instance Method Details

#on_read(content, eof) ⇒ Object



184
185
186
187
188
# File 'lib/rack/multipart/parser.rb', line 184

def on_read content, eof
  handle_empty_content!(content, eof)
  @buf << content
  run_parser
end

#resultObject



190
191
192
193
194
195
196
197
198
199
# File 'lib/rack/multipart/parser.rb', line 190

def result
  @collector.each do |part|
    part.get_data do |data|
      tag_multipart_encoding(part.filename, part.content_type, part.name, data)
      @query_parser.normalize_params(@params, part.name, data, @query_parser.param_depth_limit)
    end
  end

  MultipartInfo.new @params.to_params_hash, @collector.find_all(&:file?).map(&:body)
end