class 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 128
def auth_param
  return nil unless name = token
  return nil unless @scanner.scan(/=/)

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

  return nil unless value

  return name, value
end
auth_scheme()
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?
    start = @scanner.pos
    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(/.*/)
      end

      challenge.raw = www_authenticate[start, @scanner.pos]
      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 =~ /^realm$/i

      unless name then
        challenge.params = params
        challenges << challenge

        if @scanner.eos? then
          challenge.raw = www_authenticate[start, @scanner.pos]
          break
        end

        @scanner.pos = pos # rewind
        challenge.raw = www_authenticate[start, @scanner.pos].sub(/(,+)? *$/, '')
        challenge = nil # a token should be next, new challenge
        break
      else
        params[name] = value
      end

      spaces

      @scanner.scan(/(, *)+/)
    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 150
def quoted_string
  return nil unless @scanner.scan(/"/)

  text = ''

  while true do
    chunk = @scanner.scan(/[\r\n \t\041\043-\176\200-\377]+/) # 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 103
def scan_comma_spaces
  @scanner.scan(/, +/)
end
spaces() click to toggle source
1*SP

Parses spaces

# File lib/mechanize/http/www_authenticate_parser.rb, line 94
def spaces
  @scanner.scan(/ +/)
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 112
def token
  @scanner.scan(/[^\000-\037\177()<>@,;:\"\/\[\]?={} ]+/)
end
Also aliased as: auth_scheme