Class: Mechanize::HTTP::WWWAuthenticateParser

Inherits:
Object
  • Object
show all
Defined in:
lib/mechanize/http/www_authenticate_parser.rb

Overview

Parses the WWW-Authenticate HTTP header into separate challenges.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeWWWAuthenticateParser

Creates a new header parser for WWW-Authenticate headers

[View source]

15
16
17
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 15

def initialize
  @scanner = nil
end

Instance Attribute Details

#scannerObject

:nodoc:


10
11
12
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 10

def scanner
  @scanner
end

Instance Method Details

#auth_paramObject

auth-param = token “=” ( token | quoted-string )

Parses an auth parameter

[View source]

129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 129

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

#parse(www_authenticate) ⇒ Object

Parsers the header. Returns an Array of challenges as strings

[View source]

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 22

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

    break 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_stringObject

quoted-string = ( <“> *(qdtext | quoted-pair ) <”> )

qdtext        = <any TEXT except <">>
quoted-pair   = "\" CHAR

For TEXT, the rules of RFC 2047 are ignored.

[View source]

151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 151

def quoted_string
  return nil unless @scanner.scan(/"/)

  text = String.new

  while true do
    chunk = @scanner.scan(/[\r\n \t\x21\x23-\x7e\u0080-\u00ff]+/) # not " which is \x22

    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_spacesObject

scans a comma followed by spaces needed for Negotiation, NTLM

[View source]

104
105
106
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 104

def scan_comma_spaces
  @scanner.scan(/, +/)
end

#spacesObject

1*SP

Parses spaces

[View source]

95
96
97
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 95

def spaces
  @scanner.scan(/ +/)
end

#tokenObject Also known as: auth_scheme

token = 1*<any CHAR except CTLs or separators>

Parses a token

[View source]

113
114
115
# File 'lib/mechanize/http/www_authenticate_parser.rb', line 113

def token
  @scanner.scan(/[^\000-\037\177()<>@,;:\\"\/\[\]?={} ]+/)
end