class HTTPX::Plugins::DigestAuthentication::Digest

  1. lib/httpx/plugins/digest_authentication.rb
Superclass: Object

Methods

Public Class

  1. new

Public Instance

  1. generate_header

Public Class methods

new (user, password)
[show source]
   # File lib/httpx/plugins/digest_authentication.rb
69 def initialize(user, password)
70   @user = user
71   @password = password
72   @nonce = 0
73 end

Public Instance methods

generate_header (request, response, _iis = false)
[show source]
    # File lib/httpx/plugins/digest_authentication.rb
 75 def generate_header(request, response, _iis = false)
 76   meth = request.verb.to_s.upcase
 77   www = response.headers["www-authenticate"]
 78 
 79   # discard first token, it's Digest
 80   auth_info = www[/^(\w+) (.*)/, 2]
 81 
 82   uri = request.path
 83 
 84   params = Hash[auth_info.scan(/(\w+)="(.*?)"/)]
 85 
 86   nonce = params["nonce"]
 87   nc = next_nonce
 88 
 89   # verify qop
 90   qop = params["qop"]
 91 
 92   if params["algorithm"] =~ /(.*?)(-sess)?$/
 93     algorithm = case Regexp.last_match(1)
 94                 when "MD5"    then ::Digest::MD5
 95                 when "SHA1"   then ::Digest::SHA1
 96                 when "SHA2"   then ::Digest::SHA2
 97                 when "SHA256" then ::Digest::SHA256
 98                 when "SHA384" then ::Digest::SHA384
 99                 when "SHA512" then ::Digest::SHA512
100                 when "RMD160" then ::Digest::RMD160
101                 else raise DigestError, "unknown algorithm \"#{Regexp.last_match(1)}\""
102     end
103     sess = Regexp.last_match(2)
104   else
105     algorithm = ::Digest::MD5
106   end
107 
108   if qop || sess
109     cnonce = make_cnonce
110     nc = format("%08x", nc)
111   end
112 
113   a1 = if sess
114     [algorithm.hexdigest("#{@user}:#{params["realm"]}:#{@password}"),
115      nonce,
116      cnonce].join ":"
117   else
118     "#{@user}:#{params["realm"]}:#{@password}"
119   end
120 
121   ha1 = algorithm.hexdigest(a1)
122   ha2 = algorithm.hexdigest("#{meth}:#{uri}")
123   request_digest = [ha1, nonce]
124   request_digest.push(nc, cnonce, qop) if qop
125   request_digest << ha2
126   request_digest = request_digest.join(":")
127 
128   header = [
129     %(username="#{@user}"),
130     %(nonce="#{nonce}"),
131     %(uri="#{uri}"),
132     %(response="#{algorithm.hexdigest(request_digest)}"),
133   ]
134   header << %(realm="#{params["realm"]}") if params.key?("realm")
135   header << %(algorithm=#{params["algorithm"]}") if params.key?("algorithm")
136   header << %(opaque="#{params["opaque"]}") if params.key?("opaque")
137   header << %(cnonce="#{cnonce}") if cnonce
138   header << %(nc=#{nc})
139   header << %(qop=#{qop}) if qop
140   header.join ", "
141 end