lib/httpx/plugins/digest_authentication.rb in httpx-0.14.5 vs lib/httpx/plugins/digest_authentication.rb in httpx-0.15.0

- old
+ new

@@ -8,20 +8,22 @@ # This plugin adds helper methods to implement HTTP Digest Auth (https://tools.ietf.org/html/rfc7616) # # https://gitlab.com/honeyryderchuck/httpx/wikis/Authentication#authentication # module DigestAuthentication + using RegexpExtensions unless Regexp.method_defined?(:match?) + DigestError = Class.new(Error) def self.extra_options(options) Class.new(options.class) do def_option(:digest, <<-OUT) raise Error, ":digest must be a Digest" unless value.is_a?(#{Digest}) value OUT - end.new(options) + end.new(options).merge(max_concurrent_requests: 1) end def self.load_dependencies(*) require "securerandom" require "digest" @@ -32,37 +34,33 @@ with(digest: Digest.new(user, password)) end alias_method :digest_auth, :digest_authentication - def request(*args, **options) - requests = build_requests(*args, options) - probe_request = requests.first - digest = probe_request.options.digest + def send_requests(*requests, options) + requests.flat_map do |request| + digest = request.options.digest - return super unless digest + if digest + probe_response = wrap { super(request, options).first } - prev_response = wrap { send_requests(*probe_request, options).first } + if digest && !probe_response.is_a?(ErrorResponse) && + probe_response.status == 401 && probe_response.headers.key?("www-authenticate") && + /Digest .*/.match?(probe_response.headers["www-authenticate"]) - raise Error, "request doesn't require authentication (status: #{prev_response.status})" unless prev_response.status == 401 + request.transition(:idle) - probe_request.transition(:idle) + token = digest.generate_header(request, probe_response) + request.headers["authorization"] = "Digest #{token}" - responses = [] - - while (request = requests.shift) - token = digest.generate_header(request, prev_response) - request.headers["authorization"] = "Digest #{token}" - response = if requests.empty? - send_requests(*request, options).first + super(request, options) + else + probe_response + end else - wrap { send_requests(*request, options).first } + super(request, options) end - responses << response - prev_response = response end - - responses.size == 1 ? responses.first : responses end end class Digest def initialize(user, password)