class Mechanize::HTTP::WWWAuthenticateParser

Parses the WWW-Authenticate HTTP header into separate challenges.

Public Class Methods

new() click to toggle source

Creates a new header parser for WWW-Authenticate headers

# File lib/mechanize/http/www_authenticate_parser.rb, line 14
def initialize
  @scanner = nil
end

Public Instance Methods

auth_param() click to toggle source
auth-param = token "=" ( token | quoted-string )

Parses an auth parameter

# File lib/mechanize/http/www_authenticate_parser.rb, line 123
def auth_param
  return nil unless name = token
  return nil unless @scanner.scan(%r=/)

  value = if @scanner.peek(1) == '"' then
            quoted_string
          else
            token
          end

  return nil unless value

  return name, value
end
auth_scheme() click to toggle source
auth-scheme = token

Parses an auth scheme (a token)

Alias for: token
parse(www_authenticate) click to toggle source

Parsers the header. Returns an Array of challenges as strings

# File lib/mechanize/http/www_authenticate_parser.rb, line 21
def parse www_authenticate
  challenges = []
  @scanner = StringScanner.new www_authenticate

  while true do
    break if @scanner.eos?
    challenge = Mechanize::HTTP::AuthChallenge.new

    scheme = auth_scheme

    if scheme == 'Negotiate'
      scan_comma_spaces
    end

    next unless scheme
    challenge.scheme = scheme

    space = spaces

    if scheme == 'NTLM' then
      if space then
        challenge.params = @scanner.scan(%r.*/)
      end

      challenges << challenge
      next
    else
      scheme.capitalize!
    end

    next unless space

    params = {}

    while true do
      pos = @scanner.pos
      name, value = auth_param

      name.downcase! if name =~ %r^realm$/

      unless name then
        challenge.params = params
        challenges << challenge
        break if @scanner.eos?

        @scanner.pos = pos # rewind
        challenge = '' # a token should be next, new challenge
        break
      else
        params[name] = value
      end

      spaces

      return nil unless ',' == @scanner.peek(1) or @scanner.eos?

      @scanner.scan(%r(, *)+/)
    end
  end

  challenges
end
quoted_string() click to toggle source
quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
qdtext        = <any TEXT except <">>
quoted-pair   = "\" CHAR

For TEXT, the rules of RFC 2047 are ignored.

# File lib/mechanize/http/www_authenticate_parser.rb, line 145
def quoted_string
  return nil unless @scanner.scan(%r"/)

  text = ''

  while true do
    chunk = @scanner.scan(%r[\r\n \t\0041\0043-\1176\2200-\3377]+/) # not "

    if chunk then
      text << chunk

      text << @scanner.get_byte if
        chunk.end_with? '\' and '"' == @scanner.peek(1)
    else
      if '"' == @scanner.peek(1) then
        @scanner.get_byte
        break
      else
        return nil
      end
    end
  end

  text
end
scan_comma_spaces() click to toggle source

scans a comma followed by spaces needed for Negotiation, NTLM

# File lib/mechanize/http/www_authenticate_parser.rb, line 98
def scan_comma_spaces
  @scanner.scan(%r, +/)
end
spaces() click to toggle source
1*SP

Parses spaces

# File lib/mechanize/http/www_authenticate_parser.rb, line 89
def spaces
  @scanner.scan(%r +/)
end
token() click to toggle source
token = 1*<any CHAR except CTLs or separators>

Parses a token

# File lib/mechanize/http/www_authenticate_parser.rb, line 107
def token
  @scanner.scan(%r[^\0000-\0037\1177()<>@,;:\\"\/\[\]?={} ]+/)
end
Also aliased as: auth_scheme