class Mechanize::HTTP::ContentDispositionParser
Parser Content-Disposition headers that loosely follows RFC 2183.
Beyond RFC 2183, this parser allows:
-
Missing disposition-type
-
Multiple semicolons
-
Whitespace around semicolons
-
Dates in ISO 8601 format
Public Class Methods
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 40 def initialize @scanner = nil end
Creates a new parser Content-Disposition headers
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 32 def self.parse content_disposition @parser ||= self.new @parser.parse content_disposition end
Parses the disposition type and params in the content_disposition
string. The “Content-Disposition:” must be removed.
Public Instance Methods
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 48 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/i) 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
Parses the content_disposition
header. If header
is set to true the “Content-Disposition:” portion will be parsed
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 86 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 date = rfc_2045_quoted_string begin Time.rfc822 date rescue ArgumentError begin Time.iso8601 date rescue ArgumentError nil end end 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
Extracts disposition-param and returns a Hash.
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 137 def rfc_2045_quoted_string return nil unless @scanner.scan(/"/) text = String.new 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(2) then @scanner.skip(/\\/) text << @scanner.get_byte elsif '"' == @scanner.peek(1) then @scanner.get_byte break else return nil end end end text end
quoted-string = <"> *(qtext/quoted-pair) <"> qtext = <any CHAR excepting <">, "\" & CR, and including linear-white-space quoted-pair = "\" CHAR
Parses an RFC 2045 quoted-string
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 176 def rfc_2045_token @scanner.scan(/[^\000-\037\177()<>@,;:\\"\/\[\]?= ]+/) end
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs, or tspecials>
Parses an RFC 2045 token
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 185 def rfc_2045_value if @scanner.peek(1) == '"' then rfc_2045_quoted_string else rfc_2045_token end end
value := token / quoted-string
Parses an RFC 2045 value
Source
# File lib/mechanize/http/content_disposition_parser.rb, line 198 def spaces @scanner.scan(/ +/) end
1*SP
Parses spaces