Commit cdd8c674 authored by HoneyryderChuck's avatar HoneyryderChuck
Browse files

Merge branch 'auth-401-retry' into 'master'

Auth plugin: Retry on 401 errors

See merge request !430
parents 70e3e394 e2c4c054
Loading
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ module HTTPX
      end

      def altsvc_match?(uri, other_uri)
        other_uri = URI(other_uri)
        other_uri = URI(other_uri) #: http_uri

        uri.origin == other_uri.origin || begin
          case uri.scheme
+21 −2
Original line number Diff line number Diff line
@@ -81,10 +81,14 @@ module HTTPX
        def generate_auth_token
          return unless (auth_value = @options.auth_header_value)

          auth_value = auth_value.call(self) if auth_value.respond_to?(:call)
          auth_value = auth_value.call(self) if dynamic_auth_token?(auth_value)

          auth_value
        end

        def dynamic_auth_token?(auth_header_value)
          auth_header_value&.respond_to?(:call)
        end
      end

      module RequestMethods
@@ -99,14 +103,29 @@ module HTTPX

      module AuthRetries
        module InstanceMethods
          private

          def retryable_request?(request, response, options)
            super || auth_error?(response, options)
          end

          def retryable_response?(response, options)
            auth_error?(response, options) || super
          end

          def prepare_to_retry(request, response)
            super

            return unless @options.generate_auth_value_on_retry && @options.generate_auth_value_on_retry.call(response)
            return unless auth_error?(response, request.options) ||
                          (@options.generate_auth_value_on_retry && @options.generate_auth_value_on_retry.call(response))

            request.headers.get("authorization").pop
            @auth_header_value = generate_auth_token
          end

          def auth_error?(response, options)
            response.is_a?(Response) && response.status == 401 && dynamic_auth_token?(options.auth_header_value)
          end
        end
      end
    end
+7 −18
Original line number Diff line number Diff line
@@ -259,29 +259,18 @@ module HTTPX

          @oauth_session.fetch_access_token(self)
        end
      end

      module OAuthRetries
        class << self
          def extra_options(options)
            options.merge(
              retry_on: method(:response_oauth_error?),
              generate_auth_value_on_retry: method(:response_oauth_error?)
            )
          end

          def response_oauth_error?(res)
            res.is_a?(Response) && res.status == 401
        def dynamic_auth_token?(_)
          @oauth_session
        end
      end

      module OAuthRetries
        module InstanceMethods
          def prepare_to_retry(_request, response)
            unless @oauth_session && @options.generate_auth_value_on_retry && @options.generate_auth_value_on_retry.call(response)
              return super
            end
          private

            @oauth_session.reset!
          def prepare_to_retry(_request, response)
            @oauth_session.reset! if @oauth_session

            super
          end
+3 −5
Original line number Diff line number Diff line
@@ -55,10 +55,8 @@ module HTTPX

        private

        def repeatable_request?(request, _)
        def retryable_request?(request, response, *)
          super || begin
            response = request.response

            return false unless response && response.is_a?(ErrorResponse)

            error = response.error
@@ -67,13 +65,13 @@ module HTTPX
          end
        end

        def retryable_error?(ex)
        def retryable_error?(ex, options)
          super &&
            # under the persistent plugin rules, requests are only retried for connection related errors,
            # which do not include request timeout related errors. This only gets overriden if the end user
            # manually changed +:max_retries+ to something else, which means it is aware of the
            # consequences.
            (!ex.is_a?(RequestTimeoutError) || @options.max_retries != 1)
            (!ex.is_a?(RequestTimeoutError) || options.max_retries != 1)
        end
      end
    end
+3 −1
Original line number Diff line number Diff line
@@ -326,7 +326,9 @@ module HTTPX

      module ProxyRetries
        module InstanceMethods
          def retryable_error?(ex)
          private

          def retryable_error?(ex, *)
            super || ex.is_a?(ProxyConnectionError)
          end
        end
Loading