Class: Rack::Multipart::Parser

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

Constant Summary collapse

BUFSIZE =
16384
DUMMY =
Struct.new(:parse).new

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(boundary, io, content_length, env) ⇒ Parser

Returns a new instance of Parser.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/rack/multipart/parser.rb', line 21

def initialize(boundary, io, content_length, env)
  @buf            = ""

  if @buf.respond_to? :force_encoding
    @buf.force_encoding Encoding::ASCII_8BIT
  end

  @params         = Utils::KeySpaceConstrainedParams.new
  @boundary       = "--#{boundary}"
  @io             = io
  @content_length = content_length
  @boundary_size  = Utils.bytesize(@boundary) + EOL.size
  @env = env

  if @content_length
    @content_length -= @boundary_size
  end

  @rx = /(?:#{EOL})?#{Regexp.quote(@boundary)}(#{EOL}|--)/n
  @full_boundary = @boundary + EOL
end

Class Method Details

.create(env) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/rack/multipart/parser.rb', line 9

def self.create(env)
  return DUMMY unless env["CONTENT_TYPE"] =~ MULTIPART

  io = env["rack.input"]
  io.rewind

  content_length = env["CONTENT_LENGTH"]
  content_length = content_length.to_i if content_length

  new($1, io, content_length, env)
end

Instance Method Details

#parseObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rack/multipart/parser.rb', line 43

def parse
  fast_forward_to_first_boundary

  loop do
    head, filename, content_type, name, body =
      get_current_head_and_filename_and_content_type_and_name_and_body

    # Save the rest.
    if i = @buf.index(rx)
      body << @buf.slice!(0, i)
      @buf.slice!(0, @boundary_size+2)

      @content_length = -1  if $1 == "--"
    end

    get_data(filename, body, content_type, name, head) do |data|
      tag_multipart_encoding(filename, content_type, name, data)

      Utils.normalize_params(@params, name, data)
    end

    # break if we're at the end of a buffer, but not if it is the end of a field
    break if (@buf.empty? && $1 != EOL) || @content_length == -1
  end

  @io.rewind

  @params.to_params_hash
end