class HTTP::ContentDispositionParser

Parser Content-Disposition headers that loosely follows RFC 2183.

Beyond RFC 2183, this parser allows:

Public Class Methods

new() click to toggle source

Creates a new parser Content-Disposition headers

# File lib/mechanize/http/content_disposition_parser.rb, line 37
def initialize
  @scanner = nil
end
parse(content_disposition) click to toggle source

Parses the disposition type and params in the content_disposition string. The “Content-Disposition:” must be removed.

# File lib/mechanize/http/content_disposition_parser.rb, line 29
def self.parse content_disposition
  @parser ||= self.new
  @parser.parse content_disposition
end

Public Instance Methods

parse(content_disposition, header = false) click to toggle source

Parses the content_disposition header. If header is set to true the “Content-Disposition:” portion will be parsed

# File lib/mechanize/http/content_disposition_parser.rb, line 45
def parse content_disposition, header = false
  return nil if content_disposition.empty?

  @scanner = StringScanner.new content_disposition

  if header then
    return nil unless @scanner.scan(/Content-Disposition/)
    return nil unless @scanner.scan(/:/)
    spaces
  end

  type = rfc_2045_token
  @scanner.scan(/;+/)

  if @scanner.peek(1) == '=' then
    @scanner.pos = 0
    type = nil
  end

  disposition = Mechanize::HTTP::ContentDisposition.new type

  spaces

  return nil unless parameters = parse_parameters

  disposition.filename          = parameters.delete 'filename'
  disposition.creation_date     = parameters.delete 'creation-date'
  disposition.modification_date = parameters.delete 'modification-date'
  disposition.read_date         = parameters.delete 'read-date'
  disposition.size              = parameters.delete 'size'
  disposition.parameters        = parameters

  disposition
end
parse_parameters() click to toggle source

Extracts disposition-parm and returns a Hash.

# File lib/mechanize/http/content_disposition_parser.rb, line 83
def parse_parameters
  parameters = {}

  while true do
    return nil unless param = rfc_2045_token
    param.downcase!
    return nil unless @scanner.scan(/=/)

    value = case param
            when /^filename$/ then
              rfc_2045_value
            when /^(creation|modification|read)-date$/ then
              Time.rfc822 rfc_2045_quoted_string
            when /^size$/ then
              rfc_2045_value.to_i(10)
            else
              rfc_2045_value
            end

    return nil unless value

    parameters[param] = value

    spaces

    break if @scanner.eos? or not @scanner.scan(/;+/)

    spaces
  end

  parameters
end
rfc_2045_quoted_string() click to toggle source
quoted-string = <"> *(qtext/quoted-pair) <">
qtext         = <any CHAR excepting <">, "\" & CR,
                 and including linear-white-space
quoted-pair   = "\" CHAR

Parses an RFC 2045 quoted-string

# File lib/mechanize/http/content_disposition_parser.rb, line 124
def rfc_2045_quoted_string
  return nil unless @scanner.scan(/"/)

  text = ''

  while true do
    chunk = @scanner.scan(/[\000-\014\016-\041\043-\133\135-\177]+/) # not \r "

    if chunk then
      text << chunk

      if @scanner.peek(1) == '\' then
        @scanner.get_byte
        return nil if @scanner.eos?
        text << @scanner.get_byte
      elsif @scanner.scan(/\r\n[\t ]+/) then
        text << " "
      end
    else
      if '"' == @scanner.peek(1) then
        @scanner.get_byte
        break
      else
        return nil
      end
    end
  end

  text
end
rfc_2045_token() click to toggle source
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>

Parses an RFC 2045 token

# File lib/mechanize/http/content_disposition_parser.rb, line 160
def rfc_2045_token
  @scanner.scan(/[^\000-\037\177()<>@,;:\"\/\[\]?= ]+/)
end
rfc_2045_value() click to toggle source
value := token / quoted-string

Parses an RFC 2045 value

# File lib/mechanize/http/content_disposition_parser.rb, line 169
def rfc_2045_value
  if @scanner.peek(1) == '"' then
    rfc_2045_quoted_string
  else
    rfc_2045_token
  end
end
spaces() click to toggle source
1*SP

Parses spaces

# File lib/mechanize/http/content_disposition_parser.rb, line 182
def spaces
  @scanner.scan(/ +/)
end