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.split(/ *, */)
 85                          .map { |val| val.split("=") }
 86                          .map { |k, v| [k, v.delete("\"")] }]
 87   nonce = params["nonce"]
 88   nc = next_nonce
 89 
 90   # verify qop
 91   qop = params["qop"]
 92 
 93   if params["algorithm"] =~ /(.*?)(-sess)?$/
 94     alg = Regexp.last_match(1)
 95     algorithm = ::Digest.const_get(alg)
 96     raise DigestError, "unknown algorithm \"#{alg}\"" unless algorithm
 97 
 98     sess = Regexp.last_match(2)
 99     params.delete("algorithm")
100   else
101     algorithm = ::Digest::MD5
102   end
103 
104   if qop || sess
105     cnonce = make_cnonce
106     nc = format("%<nonce>08x", nonce: nc)
107   end
108 
109   a1 = if sess
110     [algorithm.hexdigest("#{@user}:#{params["realm"]}:#{@password}"),
111      nonce,
112      cnonce].join ":"
113   else
114     "#{@user}:#{params["realm"]}:#{@password}"
115   end
116 
117   ha1 = algorithm.hexdigest(a1)
118   ha2 = algorithm.hexdigest("#{meth}:#{uri}")
119   request_digest = [ha1, nonce]
120   request_digest.push(nc, cnonce, qop) if qop
121   request_digest << ha2
122   request_digest = request_digest.join(":")
123 
124   header = [
125     %(username="#{@user}"),
126     %(nonce="#{nonce}"),
127     %(uri="#{uri}"),
128     %(response="#{algorithm.hexdigest(request_digest)}"),
129   ]
130   header << %(realm="#{params["realm"]}") if params.key?("realm")
131   header << %(algorithm=#{params["algorithm"]}") if params.key?("algorithm")
132   header << %(opaque="#{params["opaque"]}") if params.key?("opaque")
133   header << %(cnonce="#{cnonce}") if cnonce
134   header << %(nc=#{nc})
135   header << %(qop=#{qop}) if qop
136   header.join ", "
137 end