faraday 0.11.0 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
 - data/CHANGELOG.md +380 -0
 - data/LICENSE.md +1 -1
 - data/README.md +25 -229
 - data/Rakefile +7 -0
 - data/examples/client_spec.rb +65 -0
 - data/examples/client_test.rb +79 -0
 - data/lib/faraday/adapter/httpclient.rb +83 -59
 - data/lib/faraday/adapter/patron.rb +92 -36
 - data/lib/faraday/adapter/rack.rb +30 -13
 - data/lib/faraday/adapter/test.rb +103 -62
 - data/lib/faraday/adapter/typhoeus.rb +7 -115
 - data/lib/faraday/adapter.rb +77 -22
 - data/lib/faraday/adapter_registry.rb +30 -0
 - data/lib/faraday/autoload.rb +42 -36
 - data/lib/faraday/connection.rb +351 -167
 - data/lib/faraday/dependency_loader.rb +37 -0
 - data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
 - data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
 - data/lib/faraday/error.rb +127 -38
 - data/lib/faraday/file_part.rb +128 -0
 - data/lib/faraday/logging/formatter.rb +105 -0
 - data/lib/faraday/methods.rb +6 -0
 - data/lib/faraday/middleware.rb +19 -25
 - data/lib/faraday/middleware_registry.rb +129 -0
 - data/lib/faraday/options/connection_options.rb +22 -0
 - data/lib/faraday/options/env.rb +181 -0
 - data/lib/faraday/options/proxy_options.rb +32 -0
 - data/lib/faraday/options/request_options.rb +22 -0
 - data/lib/faraday/options/ssl_options.rb +59 -0
 - data/lib/faraday/options.rb +58 -207
 - data/lib/faraday/param_part.rb +53 -0
 - data/lib/faraday/parameters.rb +4 -196
 - data/lib/faraday/rack_builder.rb +84 -48
 - data/lib/faraday/request/authorization.rb +44 -30
 - data/lib/faraday/request/basic_authentication.rb +14 -7
 - data/lib/faraday/request/instrumentation.rb +45 -27
 - data/lib/faraday/request/multipart.rb +88 -45
 - data/lib/faraday/request/retry.rb +211 -126
 - data/lib/faraday/request/token_authentication.rb +15 -10
 - data/lib/faraday/request/url_encoded.rb +43 -23
 - data/lib/faraday/request.rb +94 -32
 - data/lib/faraday/response/logger.rb +22 -69
 - data/lib/faraday/response/raise_error.rb +49 -14
 - data/lib/faraday/response.rb +27 -23
 - data/lib/faraday/utils/headers.rb +139 -0
 - data/lib/faraday/utils/params_hash.rb +61 -0
 - data/lib/faraday/utils.rb +38 -238
 - data/lib/faraday/version.rb +5 -0
 - data/lib/faraday.rb +124 -187
 - data/spec/external_adapters/faraday_specs_setup.rb +14 -0
 - data/spec/faraday/adapter/em_http_spec.rb +47 -0
 - data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
 - data/spec/faraday/adapter/excon_spec.rb +49 -0
 - data/spec/faraday/adapter/httpclient_spec.rb +73 -0
 - data/spec/faraday/adapter/net_http_spec.rb +64 -0
 - data/spec/faraday/adapter/patron_spec.rb +18 -0
 - data/spec/faraday/adapter/rack_spec.rb +8 -0
 - data/spec/faraday/adapter/test_spec.rb +260 -0
 - data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
 - data/spec/faraday/adapter_registry_spec.rb +28 -0
 - data/spec/faraday/adapter_spec.rb +55 -0
 - data/spec/faraday/composite_read_io_spec.rb +80 -0
 - data/spec/faraday/connection_spec.rb +736 -0
 - data/spec/faraday/error_spec.rb +60 -0
 - data/spec/faraday/middleware_spec.rb +52 -0
 - data/spec/faraday/options/env_spec.rb +70 -0
 - data/spec/faraday/options/options_spec.rb +297 -0
 - data/spec/faraday/options/proxy_options_spec.rb +44 -0
 - data/spec/faraday/options/request_options_spec.rb +19 -0
 - data/spec/faraday/params_encoders/flat_spec.rb +42 -0
 - data/spec/faraday/params_encoders/nested_spec.rb +142 -0
 - data/spec/faraday/rack_builder_spec.rb +345 -0
 - data/spec/faraday/request/authorization_spec.rb +88 -0
 - data/spec/faraday/request/instrumentation_spec.rb +76 -0
 - data/spec/faraday/request/multipart_spec.rb +302 -0
 - data/spec/faraday/request/retry_spec.rb +242 -0
 - data/spec/faraday/request/url_encoded_spec.rb +83 -0
 - data/spec/faraday/request_spec.rb +120 -0
 - data/spec/faraday/response/logger_spec.rb +220 -0
 - data/spec/faraday/response/middleware_spec.rb +68 -0
 - data/spec/faraday/response/raise_error_spec.rb +169 -0
 - data/spec/faraday/response_spec.rb +75 -0
 - data/spec/faraday/utils/headers_spec.rb +82 -0
 - data/spec/faraday/utils_spec.rb +56 -0
 - data/spec/faraday_spec.rb +37 -0
 - data/spec/spec_helper.rb +132 -0
 - data/spec/support/disabling_stub.rb +14 -0
 - data/spec/support/fake_safe_buffer.rb +15 -0
 - data/spec/support/helper_methods.rb +133 -0
 - data/spec/support/shared_examples/adapter.rb +105 -0
 - data/spec/support/shared_examples/params_encoder.rb +18 -0
 - data/spec/support/shared_examples/request_method.rb +262 -0
 - data/spec/support/streaming_response_checker.rb +35 -0
 - data/spec/support/webmock_rack_app.rb +68 -0
 - metadata +164 -16
 - data/lib/faraday/adapter/em_http.rb +0 -243
 - data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
 - data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
 - data/lib/faraday/adapter/em_synchrony.rb +0 -106
 - data/lib/faraday/adapter/excon.rb +0 -80
 - data/lib/faraday/adapter/net_http.rb +0 -135
 - data/lib/faraday/adapter/net_http_persistent.rb +0 -50
 - data/lib/faraday/upload_io.rb +0 -67
 
| 
         @@ -1,154 +1,239 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Faraday
         
     | 
| 
       2 
     | 
    
         
            -
               
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                 
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
              class Request
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Catches exceptions and retries each request a limited number of times.
         
     | 
| 
      
 6 
     | 
    
         
            +
                #
         
     | 
| 
      
 7 
     | 
    
         
            +
                # By default, it retries 2 times and handles only timeout exceptions. It can
         
     | 
| 
      
 8 
     | 
    
         
            +
                # be configured with an arbitrary number of retries, a list of exceptions to
         
     | 
| 
      
 9 
     | 
    
         
            +
                # handle, a retry interval, a percentage of randomness to add to the retry
         
     | 
| 
      
 10 
     | 
    
         
            +
                # interval, and a backoff factor.
         
     | 
| 
      
 11 
     | 
    
         
            +
                #
         
     | 
| 
      
 12 
     | 
    
         
            +
                # @example Configure Retry middleware using intervals
         
     | 
| 
      
 13 
     | 
    
         
            +
                #   Faraday.new do |conn|
         
     | 
| 
      
 14 
     | 
    
         
            +
                #     conn.request(:retry, max: 2,
         
     | 
| 
      
 15 
     | 
    
         
            +
                #                          interval: 0.05,
         
     | 
| 
      
 16 
     | 
    
         
            +
                #                          interval_randomness: 0.5,
         
     | 
| 
      
 17 
     | 
    
         
            +
                #                          backoff_factor: 2,
         
     | 
| 
      
 18 
     | 
    
         
            +
                #                          exceptions: [CustomException, 'Timeout::Error'])
         
     | 
| 
      
 19 
     | 
    
         
            +
                #
         
     | 
| 
      
 20 
     | 
    
         
            +
                #     conn.adapter(:net_http) # NB: Last middleware must be the adapter
         
     | 
| 
      
 21 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 22 
     | 
    
         
            +
                #
         
     | 
| 
      
 23 
     | 
    
         
            +
                # This example will result in a first interval that is random between 0.05
         
     | 
| 
      
 24 
     | 
    
         
            +
                # and 0.075 and a second interval that is random between 0.1 and 0.125.
         
     | 
| 
      
 25 
     | 
    
         
            +
                class Retry < Faraday::Middleware
         
     | 
| 
      
 26 
     | 
    
         
            +
                  DEFAULT_EXCEPTIONS = [
         
     | 
| 
      
 27 
     | 
    
         
            +
                    Errno::ETIMEDOUT, 'Timeout::Error',
         
     | 
| 
      
 28 
     | 
    
         
            +
                    Faraday::TimeoutError, Faraday::RetriableResponse
         
     | 
| 
      
 29 
     | 
    
         
            +
                  ].freeze
         
     | 
| 
      
 30 
     | 
    
         
            +
                  IDEMPOTENT_METHODS = %i[delete get head options put].freeze
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                  # Options contains the configurable parameters for the Retry middleware.
         
     | 
| 
      
 33 
     | 
    
         
            +
                  class Options < Faraday::Options.new(:max, :interval, :max_interval,
         
     | 
| 
      
 34 
     | 
    
         
            +
                                                       :interval_randomness,
         
     | 
| 
      
 35 
     | 
    
         
            +
                                                       :backoff_factor, :exceptions,
         
     | 
| 
      
 36 
     | 
    
         
            +
                                                       :methods, :retry_if, :retry_block,
         
     | 
| 
      
 37 
     | 
    
         
            +
                                                       :retry_statuses)
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                    DEFAULT_CHECK = ->(_env, _exception) { false }
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                    def self.from(value)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      if value.is_a?(Integer)
         
     | 
| 
      
 43 
     | 
    
         
            +
                        new(value)
         
     | 
| 
      
 44 
     | 
    
         
            +
                      else
         
     | 
| 
      
 45 
     | 
    
         
            +
                        super(value)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      end
         
     | 
| 
       34 
47 
     | 
    
         
             
                    end
         
     | 
| 
       35 
     | 
    
         
            -
                  end
         
     | 
| 
       36 
48 
     | 
    
         | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
             
     | 
| 
      
 49 
     | 
    
         
            +
                    def max
         
     | 
| 
      
 50 
     | 
    
         
            +
                      (self[:max] ||= 2).to_i
         
     | 
| 
      
 51 
     | 
    
         
            +
                    end
         
     | 
| 
       40 
52 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
             
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
             
     | 
| 
      
 53 
     | 
    
         
            +
                    def interval
         
     | 
| 
      
 54 
     | 
    
         
            +
                      (self[:interval] ||= 0).to_f
         
     | 
| 
      
 55 
     | 
    
         
            +
                    end
         
     | 
| 
       44 
56 
     | 
    
         | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
             
     | 
| 
      
 57 
     | 
    
         
            +
                    def max_interval
         
     | 
| 
      
 58 
     | 
    
         
            +
                      (self[:max_interval] ||= Float::MAX).to_f
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
       48 
60 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
      
 61 
     | 
    
         
            +
                    def interval_randomness
         
     | 
| 
      
 62 
     | 
    
         
            +
                      (self[:interval_randomness] ||= 0).to_f
         
     | 
| 
      
 63 
     | 
    
         
            +
                    end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                    def backoff_factor
         
     | 
| 
      
 66 
     | 
    
         
            +
                      (self[:backoff_factor] ||= 1).to_f
         
     | 
| 
      
 67 
     | 
    
         
            +
                    end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                    def exceptions
         
     | 
| 
      
 70 
     | 
    
         
            +
                      Array(self[:exceptions] ||= DEFAULT_EXCEPTIONS)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                    def methods
         
     | 
| 
      
 74 
     | 
    
         
            +
                      Array(self[:methods] ||= IDEMPOTENT_METHODS)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                    def retry_if
         
     | 
| 
      
 78 
     | 
    
         
            +
                      self[:retry_if] ||= DEFAULT_CHECK
         
     | 
| 
      
 79 
     | 
    
         
            +
                    end
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
                    def retry_block
         
     | 
| 
      
 82 
     | 
    
         
            +
                      self[:retry_block] ||= proc {}
         
     | 
| 
      
 83 
     | 
    
         
            +
                    end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                    def retry_statuses
         
     | 
| 
      
 86 
     | 
    
         
            +
                      Array(self[:retry_statuses] ||= [])
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
       51 
88 
     | 
    
         
             
                  end
         
     | 
| 
       52 
89 
     | 
    
         | 
| 
       53 
     | 
    
         
            -
                   
     | 
| 
       54 
     | 
    
         
            -
             
     | 
| 
      
 90 
     | 
    
         
            +
                  # @param app [#call]
         
     | 
| 
      
 91 
     | 
    
         
            +
                  # @param options [Hash]
         
     | 
| 
      
 92 
     | 
    
         
            +
                  # @option options [Integer] :max (2) Maximum number of retries
         
     | 
| 
      
 93 
     | 
    
         
            +
                  # @option options [Integer] :interval (0) Pause in seconds between retries
         
     | 
| 
      
 94 
     | 
    
         
            +
                  # @option options [Integer] :interval_randomness (0) The maximum random
         
     | 
| 
      
 95 
     | 
    
         
            +
                  #   interval amount expressed as a float between
         
     | 
| 
      
 96 
     | 
    
         
            +
                  #   0 and 1 to use in addition to the interval.
         
     | 
| 
      
 97 
     | 
    
         
            +
                  # @option options [Integer] :max_interval (Float::MAX) An upper limit
         
     | 
| 
      
 98 
     | 
    
         
            +
                  #   for the interval
         
     | 
| 
      
 99 
     | 
    
         
            +
                  # @option options [Integer] :backoff_factor (1) The amount to multiply
         
     | 
| 
      
 100 
     | 
    
         
            +
                  #   each successive retry's interval amount by in order to provide backoff
         
     | 
| 
      
 101 
     | 
    
         
            +
                  # @option options [Array] :exceptions ([ Errno::ETIMEDOUT,
         
     | 
| 
      
 102 
     | 
    
         
            +
                  #   'Timeout::Error', Faraday::TimeoutError, Faraday::RetriableResponse])
         
     | 
| 
      
 103 
     | 
    
         
            +
                  #   The list of exceptions to handle. Exceptions can be given as
         
     | 
| 
      
 104 
     | 
    
         
            +
                  #   Class, Module, or String.
         
     | 
| 
      
 105 
     | 
    
         
            +
                  # @option options [Array] :methods (the idempotent HTTP methods
         
     | 
| 
      
 106 
     | 
    
         
            +
                  #   in IDEMPOTENT_METHODS) A list of HTTP methods to retry without
         
     | 
| 
      
 107 
     | 
    
         
            +
                  #   calling retry_if. Pass an empty Array to call retry_if
         
     | 
| 
      
 108 
     | 
    
         
            +
                  #   for all exceptions.
         
     | 
| 
      
 109 
     | 
    
         
            +
                  # @option options [Block] :retry_if (false) block that will receive
         
     | 
| 
      
 110 
     | 
    
         
            +
                  #   the env object and the exception raised
         
     | 
| 
      
 111 
     | 
    
         
            +
                  #   and should decide if the code should retry still the action or
         
     | 
| 
      
 112 
     | 
    
         
            +
                  #   not independent of the retry count. This would be useful
         
     | 
| 
      
 113 
     | 
    
         
            +
                  #   if the exception produced is non-recoverable or if the
         
     | 
| 
      
 114 
     | 
    
         
            +
                  #   the HTTP method called is not idempotent.
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # @option options [Block] :retry_block block that is executed before
         
     | 
| 
      
 116 
     | 
    
         
            +
                  #   every retry. Request environment, middleware options, current number
         
     | 
| 
      
 117 
     | 
    
         
            +
                  #   of retries and the exception is passed to the block as parameters.
         
     | 
| 
      
 118 
     | 
    
         
            +
                  # @option options [Array] :retry_statuses Array of Integer HTTP status
         
     | 
| 
      
 119 
     | 
    
         
            +
                  #   codes or a single Integer value that determines whether to raise
         
     | 
| 
      
 120 
     | 
    
         
            +
                  #   a Faraday::RetriableResponse exception based on the HTTP status code
         
     | 
| 
      
 121 
     | 
    
         
            +
                  #   of an HTTP response.
         
     | 
| 
      
 122 
     | 
    
         
            +
                  def initialize(app, options = nil)
         
     | 
| 
      
 123 
     | 
    
         
            +
                    super(app)
         
     | 
| 
      
 124 
     | 
    
         
            +
                    @options = Options.from(options)
         
     | 
| 
      
 125 
     | 
    
         
            +
                    @errmatch = build_exception_matcher(@options.exceptions)
         
     | 
| 
       55 
126 
     | 
    
         
             
                  end
         
     | 
| 
       56 
127 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                  def  
     | 
| 
       58 
     | 
    
         
            -
                     
     | 
| 
       59 
     | 
    
         
            -
             
     | 
| 
      
 128 
     | 
    
         
            +
                  def calculate_sleep_amount(retries, env)
         
     | 
| 
      
 129 
     | 
    
         
            +
                    retry_after = calculate_retry_after(env)
         
     | 
| 
      
 130 
     | 
    
         
            +
                    retry_interval = calculate_retry_interval(retries)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                    return if retry_after && retry_after > @options.max_interval
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                    if retry_after && retry_after >= retry_interval
         
     | 
| 
      
 135 
     | 
    
         
            +
                      retry_after
         
     | 
| 
      
 136 
     | 
    
         
            +
                    else
         
     | 
| 
      
 137 
     | 
    
         
            +
                      retry_interval
         
     | 
| 
      
 138 
     | 
    
         
            +
                    end
         
     | 
| 
       60 
139 
     | 
    
         
             
                  end
         
     | 
| 
       61 
140 
     | 
    
         | 
| 
       62 
     | 
    
         
            -
                   
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
      
 141 
     | 
    
         
            +
                  # @param env [Faraday::Env]
         
     | 
| 
      
 142 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 143 
     | 
    
         
            +
                    retries = @options.max
         
     | 
| 
      
 144 
     | 
    
         
            +
                    request_body = env[:body]
         
     | 
| 
      
 145 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 146 
     | 
    
         
            +
                      # after failure env[:body] is set to the response body
         
     | 
| 
      
 147 
     | 
    
         
            +
                      env[:body] = request_body
         
     | 
| 
      
 148 
     | 
    
         
            +
                      @app.call(env).tap do |resp|
         
     | 
| 
      
 149 
     | 
    
         
            +
                        if @options.retry_statuses.include?(resp.status)
         
     | 
| 
      
 150 
     | 
    
         
            +
                          raise Faraday::RetriableResponse.new(nil, resp)
         
     | 
| 
      
 151 
     | 
    
         
            +
                        end
         
     | 
| 
      
 152 
     | 
    
         
            +
                      end
         
     | 
| 
      
 153 
     | 
    
         
            +
                    rescue @errmatch => e
         
     | 
| 
      
 154 
     | 
    
         
            +
                      if retries.positive? && retry_request?(env, e)
         
     | 
| 
      
 155 
     | 
    
         
            +
                        retries -= 1
         
     | 
| 
      
 156 
     | 
    
         
            +
                        rewind_files(request_body)
         
     | 
| 
      
 157 
     | 
    
         
            +
                        @options.retry_block.call(env, @options, retries, e)
         
     | 
| 
      
 158 
     | 
    
         
            +
                        if (sleep_amount = calculate_sleep_amount(retries + 1, env))
         
     | 
| 
      
 159 
     | 
    
         
            +
                          sleep sleep_amount
         
     | 
| 
      
 160 
     | 
    
         
            +
                          retry
         
     | 
| 
      
 161 
     | 
    
         
            +
                        end
         
     | 
| 
      
 162 
     | 
    
         
            +
                      end
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                      raise unless e.is_a?(Faraday::RetriableResponse)
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                      e.response
         
     | 
| 
      
 167 
     | 
    
         
            +
                    end
         
     | 
| 
       64 
168 
     | 
    
         
             
                  end
         
     | 
| 
       65 
169 
     | 
    
         | 
| 
       66 
     | 
    
         
            -
                   
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
      
 170 
     | 
    
         
            +
                  # An exception matcher for the rescue clause can usually be any object
         
     | 
| 
      
 171 
     | 
    
         
            +
                  # that responds to `===`, but for Ruby 1.8 it has to be a Class or Module.
         
     | 
| 
      
 172 
     | 
    
         
            +
                  #
         
     | 
| 
      
 173 
     | 
    
         
            +
                  # @param exceptions [Array]
         
     | 
| 
      
 174 
     | 
    
         
            +
                  # @api private
         
     | 
| 
      
 175 
     | 
    
         
            +
                  # @return [Module] an exception matcher
         
     | 
| 
      
 176 
     | 
    
         
            +
                  def build_exception_matcher(exceptions)
         
     | 
| 
      
 177 
     | 
    
         
            +
                    matcher = Module.new
         
     | 
| 
      
 178 
     | 
    
         
            +
                    (
         
     | 
| 
      
 179 
     | 
    
         
            +
                    class << matcher
         
     | 
| 
      
 180 
     | 
    
         
            +
                      self
         
     | 
| 
      
 181 
     | 
    
         
            +
                    end).class_eval do
         
     | 
| 
      
 182 
     | 
    
         
            +
                      define_method(:===) do |error|
         
     | 
| 
      
 183 
     | 
    
         
            +
                        exceptions.any? do |ex|
         
     | 
| 
      
 184 
     | 
    
         
            +
                          if ex.is_a? Module
         
     | 
| 
      
 185 
     | 
    
         
            +
                            error.is_a? ex
         
     | 
| 
      
 186 
     | 
    
         
            +
                          else
         
     | 
| 
      
 187 
     | 
    
         
            +
                            error.class.to_s == ex.to_s
         
     | 
| 
      
 188 
     | 
    
         
            +
                          end
         
     | 
| 
      
 189 
     | 
    
         
            +
                        end
         
     | 
| 
      
 190 
     | 
    
         
            +
                      end
         
     | 
| 
      
 191 
     | 
    
         
            +
                    end
         
     | 
| 
      
 192 
     | 
    
         
            +
                    matcher
         
     | 
| 
       68 
193 
     | 
    
         
             
                  end
         
     | 
| 
       69 
194 
     | 
    
         | 
| 
       70 
     | 
    
         
            -
             
     | 
| 
      
 195 
     | 
    
         
            +
                  private
         
     | 
| 
       71 
196 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
             
     | 
| 
       73 
     | 
    
         
            -
             
     | 
| 
       74 
     | 
    
         
            -
             
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
       76 
     | 
    
         
            -
                # interval            - Pause in seconds between retries (default: 0)
         
     | 
| 
       77 
     | 
    
         
            -
                # interval_randomness - The maximum random interval amount expressed
         
     | 
| 
       78 
     | 
    
         
            -
                #                       as a float between 0 and 1 to use in addition to the
         
     | 
| 
       79 
     | 
    
         
            -
                #                       interval. (default: 0)
         
     | 
| 
       80 
     | 
    
         
            -
                # max_interval        - An upper limit for the interval (default: Float::MAX)
         
     | 
| 
       81 
     | 
    
         
            -
                # backoff_factor      - The amount to multiple each successive retry's
         
     | 
| 
       82 
     | 
    
         
            -
                #                       interval amount by in order to provide backoff
         
     | 
| 
       83 
     | 
    
         
            -
                #                       (default: 1)
         
     | 
| 
       84 
     | 
    
         
            -
                # exceptions          - The list of exceptions to handle. Exceptions can be
         
     | 
| 
       85 
     | 
    
         
            -
                #                       given as Class, Module, or String. (default:
         
     | 
| 
       86 
     | 
    
         
            -
                #                       [Errno::ETIMEDOUT, Timeout::Error,
         
     | 
| 
       87 
     | 
    
         
            -
                #                       Error::TimeoutError])
         
     | 
| 
       88 
     | 
    
         
            -
                # methods             - A list of HTTP methods to retry without calling retry_if.  Pass
         
     | 
| 
       89 
     | 
    
         
            -
                #                       an empty Array to call retry_if for all exceptions.
         
     | 
| 
       90 
     | 
    
         
            -
                #                       (defaults to the idempotent HTTP methods in IDEMPOTENT_METHODS)
         
     | 
| 
       91 
     | 
    
         
            -
                # retry_if            - block that will receive the env object and the exception raised
         
     | 
| 
       92 
     | 
    
         
            -
                #                       and should decide if the code should retry still the action or
         
     | 
| 
       93 
     | 
    
         
            -
                #                       not independent of the retry count. This would be useful
         
     | 
| 
       94 
     | 
    
         
            -
                #                       if the exception produced is non-recoverable or if the
         
     | 
| 
       95 
     | 
    
         
            -
                #                       the HTTP method called is not idempotent.
         
     | 
| 
       96 
     | 
    
         
            -
                #                       (defaults to return false)
         
     | 
| 
       97 
     | 
    
         
            -
                def initialize(app, options = nil)
         
     | 
| 
       98 
     | 
    
         
            -
                  super(app)
         
     | 
| 
       99 
     | 
    
         
            -
                  @options = Options.from(options)
         
     | 
| 
       100 
     | 
    
         
            -
                  @errmatch = build_exception_matcher(@options.exceptions)
         
     | 
| 
       101 
     | 
    
         
            -
                end
         
     | 
| 
      
 197 
     | 
    
         
            +
                  def retry_request?(env, exception)
         
     | 
| 
      
 198 
     | 
    
         
            +
                    @options.methods.include?(env[:method]) ||
         
     | 
| 
      
 199 
     | 
    
         
            +
                      @options.retry_if.call(env, exception)
         
     | 
| 
      
 200 
     | 
    
         
            +
                  end
         
     | 
| 
       102 
201 
     | 
    
         | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
       105 
     | 
    
         
            -
                  current_interval = @options.interval * (@options.backoff_factor ** retry_index)
         
     | 
| 
       106 
     | 
    
         
            -
                  current_interval = [current_interval, @options.max_interval].min
         
     | 
| 
       107 
     | 
    
         
            -
                  random_interval  = rand * @options.interval_randomness.to_f * @options.interval
         
     | 
| 
       108 
     | 
    
         
            -
                  current_interval + random_interval
         
     | 
| 
       109 
     | 
    
         
            -
                end
         
     | 
| 
      
 202 
     | 
    
         
            +
                  def rewind_files(body)
         
     | 
| 
      
 203 
     | 
    
         
            +
                    return unless body.is_a?(Hash)
         
     | 
| 
       110 
204 
     | 
    
         | 
| 
       111 
     | 
    
         
            -
             
     | 
| 
       112 
     | 
    
         
            -
             
     | 
| 
       113 
     | 
    
         
            -
             
     | 
| 
       114 
     | 
    
         
            -
                  begin
         
     | 
| 
       115 
     | 
    
         
            -
                    env[:body] = request_body # after failure env[:body] is set to the response body
         
     | 
| 
       116 
     | 
    
         
            -
                    @app.call(env)
         
     | 
| 
       117 
     | 
    
         
            -
                  rescue @errmatch => exception
         
     | 
| 
       118 
     | 
    
         
            -
                    if retries > 0 && retry_request?(env, exception)
         
     | 
| 
       119 
     | 
    
         
            -
                      retries -= 1
         
     | 
| 
       120 
     | 
    
         
            -
                      sleep sleep_amount(retries + 1)
         
     | 
| 
       121 
     | 
    
         
            -
                      retry
         
     | 
| 
       122 
     | 
    
         
            -
                    end
         
     | 
| 
       123 
     | 
    
         
            -
                    raise
         
     | 
| 
      
 205 
     | 
    
         
            +
                    body.each do |_, value|
         
     | 
| 
      
 206 
     | 
    
         
            +
                      value.rewind if value.is_a?(UploadIO)
         
     | 
| 
      
 207 
     | 
    
         
            +
                    end
         
     | 
| 
       124 
208 
     | 
    
         
             
                  end
         
     | 
| 
       125 
     | 
    
         
            -
                end
         
     | 
| 
       126 
209 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
             
     | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
       129 
     | 
    
         
            -
             
     | 
| 
       130 
     | 
    
         
            -
             
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
       135 
     | 
    
         
            -
             
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
       137 
     | 
    
         
            -
             
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
                      end
         
     | 
| 
      
 210 
     | 
    
         
            +
                  # MDN spec for Retry-After header:
         
     | 
| 
      
 211 
     | 
    
         
            +
                  # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
         
     | 
| 
      
 212 
     | 
    
         
            +
                  def calculate_retry_after(env)
         
     | 
| 
      
 213 
     | 
    
         
            +
                    response_headers = env[:response_headers]
         
     | 
| 
      
 214 
     | 
    
         
            +
                    return unless response_headers
         
     | 
| 
      
 215 
     | 
    
         
            +
             
     | 
| 
      
 216 
     | 
    
         
            +
                    retry_after_value = env[:response_headers]['Retry-After']
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                    # Try to parse date from the header value
         
     | 
| 
      
 219 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 220 
     | 
    
         
            +
                      datetime = DateTime.rfc2822(retry_after_value)
         
     | 
| 
      
 221 
     | 
    
         
            +
                      datetime.to_time - Time.now.utc
         
     | 
| 
      
 222 
     | 
    
         
            +
                    rescue ArgumentError
         
     | 
| 
      
 223 
     | 
    
         
            +
                      retry_after_value.to_f
         
     | 
| 
       142 
224 
     | 
    
         
             
                    end
         
     | 
| 
       143 
225 
     | 
    
         
             
                  end
         
     | 
| 
       144 
     | 
    
         
            -
                  matcher
         
     | 
| 
       145 
     | 
    
         
            -
                end
         
     | 
| 
       146 
226 
     | 
    
         | 
| 
       147 
     | 
    
         
            -
             
     | 
| 
      
 227 
     | 
    
         
            +
                  def calculate_retry_interval(retries)
         
     | 
| 
      
 228 
     | 
    
         
            +
                    retry_index = @options.max - retries
         
     | 
| 
      
 229 
     | 
    
         
            +
                    current_interval = @options.interval *
         
     | 
| 
      
 230 
     | 
    
         
            +
                                       (@options.backoff_factor**retry_index)
         
     | 
| 
      
 231 
     | 
    
         
            +
                    current_interval = [current_interval, @options.max_interval].min
         
     | 
| 
      
 232 
     | 
    
         
            +
                    random_interval = rand * @options.interval_randomness.to_f *
         
     | 
| 
      
 233 
     | 
    
         
            +
                                      @options.interval
         
     | 
| 
       148 
234 
     | 
    
         | 
| 
       149 
     | 
    
         
            -
             
     | 
| 
       150 
     | 
    
         
            -
                   
     | 
| 
      
 235 
     | 
    
         
            +
                    current_interval + random_interval
         
     | 
| 
      
 236 
     | 
    
         
            +
                  end
         
     | 
| 
       151 
237 
     | 
    
         
             
                end
         
     | 
| 
       152 
     | 
    
         
            -
             
     | 
| 
       153 
238 
     | 
    
         
             
              end
         
     | 
| 
       154 
239 
     | 
    
         
             
            end
         
     | 
| 
         @@ -1,15 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Faraday
         
     | 
| 
       2 
     | 
    
         
            -
              class Request 
     | 
| 
       3 
     | 
    
         
            -
                #  
     | 
| 
       4 
     | 
    
         
            -
                 
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
                   
     | 
| 
       7 
     | 
    
         
            -
                   
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 4 
     | 
    
         
            +
              class Request
         
     | 
| 
      
 5 
     | 
    
         
            +
                # TokenAuthentication is a middleware that adds a 'Token' header to a
         
     | 
| 
      
 6 
     | 
    
         
            +
                # Faraday request.
         
     | 
| 
      
 7 
     | 
    
         
            +
                class TokenAuthentication < load_middleware(:authorization)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  # Public
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def self.header(token, options = nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                    options ||= {}
         
     | 
| 
      
 11 
     | 
    
         
            +
                    options[:token] = token
         
     | 
| 
      
 12 
     | 
    
         
            +
                    super(:Token, options)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
       9 
14 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def initialize(app, token, options = nil)
         
     | 
| 
      
 16 
     | 
    
         
            +
                    super(app, token, options)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
       12 
18 
     | 
    
         
             
                end
         
     | 
| 
       13 
19 
     | 
    
         
             
              end
         
     | 
| 
       14 
20 
     | 
    
         
             
            end
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
         @@ -1,36 +1,56 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Faraday
         
     | 
| 
       2 
     | 
    
         
            -
              class Request 
     | 
| 
       3 
     | 
    
         
            -
                 
     | 
| 
      
 4 
     | 
    
         
            +
              class Request
         
     | 
| 
      
 5 
     | 
    
         
            +
                # Middleware for supporting urlencoded requests.
         
     | 
| 
      
 6 
     | 
    
         
            +
                class UrlEncoded < Faraday::Middleware
         
     | 
| 
      
 7 
     | 
    
         
            +
                  unless defined?(::Faraday::Request::UrlEncoded::CONTENT_TYPE)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    CONTENT_TYPE = 'Content-Type'
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
       4 
10 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
                  class << self
         
     | 
| 
      
 12 
     | 
    
         
            +
                    attr_accessor :mime_type
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                  self.mime_type = 'application/x-www-form-urlencoded'
         
     | 
| 
       9 
15 
     | 
    
         | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
                  # Encodes as "application/x-www-form-urlencoded" if not already encoded or
         
     | 
| 
      
 17 
     | 
    
         
            +
                  # of another type.
         
     | 
| 
      
 18 
     | 
    
         
            +
                  #
         
     | 
| 
      
 19 
     | 
    
         
            +
                  # @param env [Faraday::Env]
         
     | 
| 
      
 20 
     | 
    
         
            +
                  def call(env)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    match_content_type(env) do |data|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      params = Faraday::Utils::ParamsHash[data]
         
     | 
| 
      
 23 
     | 
    
         
            +
                      env.body = params.to_query(env.params_encoder)
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                    @app.call env
         
     | 
| 
       14 
26 
     | 
    
         
             
                  end
         
     | 
| 
       15 
     | 
    
         
            -
                  @app.call env
         
     | 
| 
       16 
     | 
    
         
            -
                end
         
     | 
| 
       17 
27 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
                   
     | 
| 
      
 28 
     | 
    
         
            +
                  # @param env [Faraday::Env]
         
     | 
| 
      
 29 
     | 
    
         
            +
                  # @yield [request_body] Body of the request
         
     | 
| 
      
 30 
     | 
    
         
            +
                  def match_content_type(env)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    return unless process_request?(env)
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
       20 
33 
     | 
    
         
             
                    env.request_headers[CONTENT_TYPE] ||= self.class.mime_type
         
     | 
| 
       21 
34 
     | 
    
         
             
                    yield(env.body) unless env.body.respond_to?(:to_str)
         
     | 
| 
       22 
35 
     | 
    
         
             
                  end
         
     | 
| 
       23 
     | 
    
         
            -
                end
         
     | 
| 
       24 
36 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
                   
     | 
| 
       27 
     | 
    
         
            -
                   
     | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 37 
     | 
    
         
            +
                  # @param env [Faraday::Env]
         
     | 
| 
      
 38 
     | 
    
         
            +
                  #
         
     | 
| 
      
 39 
     | 
    
         
            +
                  # @return [Boolean] True if the request has a body and its Content-Type is
         
     | 
| 
      
 40 
     | 
    
         
            +
                  #                   urlencoded.
         
     | 
| 
      
 41 
     | 
    
         
            +
                  def process_request?(env)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    type = request_type(env)
         
     | 
| 
      
 43 
     | 
    
         
            +
                    env.body && (type.empty? || (type == self.class.mime_type))
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
       29 
45 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
                   
     | 
| 
       32 
     | 
    
         
            -
                   
     | 
| 
       33 
     | 
    
         
            -
                   
     | 
| 
      
 46 
     | 
    
         
            +
                  # @param env [Faraday::Env]
         
     | 
| 
      
 47 
     | 
    
         
            +
                  #
         
     | 
| 
      
 48 
     | 
    
         
            +
                  # @return [String]
         
     | 
| 
      
 49 
     | 
    
         
            +
                  def request_type(env)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    type = env.request_headers[CONTENT_TYPE].to_s
         
     | 
| 
      
 51 
     | 
    
         
            +
                    type = type.split(';', 2).first if type.index(';')
         
     | 
| 
      
 52 
     | 
    
         
            +
                    type
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
       34 
54 
     | 
    
         
             
                end
         
     | 
| 
       35 
55 
     | 
    
         
             
              end
         
     | 
| 
       36 
56 
     | 
    
         
             
            end
         
     | 
    
        data/lib/faraday/request.rb
    CHANGED
    
    | 
         @@ -1,6 +1,9 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module Faraday
         
     | 
| 
       2 
     | 
    
         
            -
              # Used to setup  
     | 
| 
      
 4 
     | 
    
         
            +
              # Used to setup URLs, params, headers, and the request body in a sane manner.
         
     | 
| 
       3 
5 
     | 
    
         
             
              #
         
     | 
| 
      
 6 
     | 
    
         
            +
              # @example
         
     | 
| 
       4 
7 
     | 
    
         
             
              #   @connection.post do |req|
         
     | 
| 
       5 
8 
     | 
    
         
             
              #     req.url 'http://localhost', 'a' => '1' # 'http://localhost?a=1'
         
     | 
| 
       6 
9 
     | 
    
         
             
              #     req.headers['b'] = '2' # Header
         
     | 
| 
         @@ -9,25 +12,63 @@ module Faraday 
     | 
|
| 
       9 
12 
     | 
    
         
             
              #     req.body = 'abc'
         
     | 
| 
       10 
13 
     | 
    
         
             
              #   end
         
     | 
| 
       11 
14 
     | 
    
         
             
              #
         
     | 
| 
       12 
     | 
    
         
            -
               
     | 
| 
      
 15 
     | 
    
         
            +
              # @!attribute http_method
         
     | 
| 
      
 16 
     | 
    
         
            +
              #   @return [Symbol] the HTTP method of the Request
         
     | 
| 
      
 17 
     | 
    
         
            +
              # @!attribute path
         
     | 
| 
      
 18 
     | 
    
         
            +
              #   @return [URI, String] the path
         
     | 
| 
      
 19 
     | 
    
         
            +
              # @!attribute params
         
     | 
| 
      
 20 
     | 
    
         
            +
              #   @return [Hash] query parameters
         
     | 
| 
      
 21 
     | 
    
         
            +
              # @!attribute headers
         
     | 
| 
      
 22 
     | 
    
         
            +
              #   @return [Faraday::Utils::Headers] headers
         
     | 
| 
      
 23 
     | 
    
         
            +
              # @!attribute body
         
     | 
| 
      
 24 
     | 
    
         
            +
              #   @return [Hash] body
         
     | 
| 
      
 25 
     | 
    
         
            +
              # @!attribute options
         
     | 
| 
      
 26 
     | 
    
         
            +
              #   @return [RequestOptions] options
         
     | 
| 
      
 27 
     | 
    
         
            +
              #
         
     | 
| 
      
 28 
     | 
    
         
            +
              # rubocop:disable Style/StructInheritance
         
     | 
| 
      
 29 
     | 
    
         
            +
              class Request < Struct.new(
         
     | 
| 
      
 30 
     | 
    
         
            +
                :http_method, :path, :params, :headers, :body, :options
         
     | 
| 
      
 31 
     | 
    
         
            +
              )
         
     | 
| 
      
 32 
     | 
    
         
            +
                # rubocop:enable Style/StructInheritance
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
       13 
34 
     | 
    
         
             
                extend MiddlewareRegistry
         
     | 
| 
       14 
35 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
                register_middleware File.expand_path(' 
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
                register_middleware File.expand_path('request', __dir__),
         
     | 
| 
      
 37 
     | 
    
         
            +
                                    url_encoded: [:UrlEncoded, 'url_encoded'],
         
     | 
| 
      
 38 
     | 
    
         
            +
                                    multipart: [:Multipart, 'multipart'],
         
     | 
| 
      
 39 
     | 
    
         
            +
                                    retry: [:Retry, 'retry'],
         
     | 
| 
      
 40 
     | 
    
         
            +
                                    authorization: [:Authorization, 'authorization'],
         
     | 
| 
      
 41 
     | 
    
         
            +
                                    basic_auth: [
         
     | 
| 
      
 42 
     | 
    
         
            +
                                      :BasicAuthentication,
         
     | 
| 
      
 43 
     | 
    
         
            +
                                      'basic_authentication'
         
     | 
| 
      
 44 
     | 
    
         
            +
                                    ],
         
     | 
| 
      
 45 
     | 
    
         
            +
                                    token_auth: [
         
     | 
| 
      
 46 
     | 
    
         
            +
                                      :TokenAuthentication,
         
     | 
| 
      
 47 
     | 
    
         
            +
                                      'token_authentication'
         
     | 
| 
      
 48 
     | 
    
         
            +
                                    ],
         
     | 
| 
      
 49 
     | 
    
         
            +
                                    instrumentation: [:Instrumentation, 'instrumentation']
         
     | 
| 
       23 
50 
     | 
    
         | 
| 
      
 51 
     | 
    
         
            +
                # @param request_method [String]
         
     | 
| 
      
 52 
     | 
    
         
            +
                # @yield [request] for block customization, if block given
         
     | 
| 
      
 53 
     | 
    
         
            +
                # @yieldparam request [Request]
         
     | 
| 
      
 54 
     | 
    
         
            +
                # @return [Request]
         
     | 
| 
       24 
55 
     | 
    
         
             
                def self.create(request_method)
         
     | 
| 
       25 
56 
     | 
    
         
             
                  new(request_method).tap do |request|
         
     | 
| 
       26 
57 
     | 
    
         
             
                    yield(request) if block_given?
         
     | 
| 
       27 
58 
     | 
    
         
             
                  end
         
     | 
| 
       28 
59 
     | 
    
         
             
                end
         
     | 
| 
       29 
60 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                 
     | 
| 
      
 61 
     | 
    
         
            +
                def method
         
     | 
| 
      
 62 
     | 
    
         
            +
                  warn <<~TEXT
         
     | 
| 
      
 63 
     | 
    
         
            +
                    WARNING: `Faraday::Request##{__method__}` is deprecated; use `#http_method` instead. It will be removed in or after version 2.0.
         
     | 
| 
      
 64 
     | 
    
         
            +
                    `Faraday::Request##{__method__}` called from #{caller_locations(1..1).first}
         
     | 
| 
      
 65 
     | 
    
         
            +
                  TEXT
         
     | 
| 
      
 66 
     | 
    
         
            +
                  http_method
         
     | 
| 
      
 67 
     | 
    
         
            +
                end
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
                # Replace params, preserving the existing hash type.
         
     | 
| 
      
 70 
     | 
    
         
            +
                #
         
     | 
| 
      
 71 
     | 
    
         
            +
                # @param hash [Hash] new params
         
     | 
| 
       31 
72 
     | 
    
         
             
                def params=(hash)
         
     | 
| 
       32 
73 
     | 
    
         
             
                  if params
         
     | 
| 
       33 
74 
     | 
    
         
             
                    params.replace hash
         
     | 
| 
         @@ -36,7 +77,9 @@ module Faraday 
     | 
|
| 
       36 
77 
     | 
    
         
             
                  end
         
     | 
| 
       37 
78 
     | 
    
         
             
                end
         
     | 
| 
       38 
79 
     | 
    
         | 
| 
       39 
     | 
    
         
            -
                #  
     | 
| 
      
 80 
     | 
    
         
            +
                # Replace request headers, preserving the existing hash type.
         
     | 
| 
      
 81 
     | 
    
         
            +
                #
         
     | 
| 
      
 82 
     | 
    
         
            +
                # @param hash [Hash] new headers
         
     | 
| 
       40 
83 
     | 
    
         
             
                def headers=(hash)
         
     | 
| 
       41 
84 
     | 
    
         
             
                  if headers
         
     | 
| 
       42 
85 
     | 
    
         
             
                    headers.replace hash
         
     | 
| 
         @@ -45,9 +88,14 @@ module Faraday 
     | 
|
| 
       45 
88 
     | 
    
         
             
                  end
         
     | 
| 
       46 
89 
     | 
    
         
             
                end
         
     | 
| 
       47 
90 
     | 
    
         | 
| 
      
 91 
     | 
    
         
            +
                # Update path and params.
         
     | 
| 
      
 92 
     | 
    
         
            +
                #
         
     | 
| 
      
 93 
     | 
    
         
            +
                # @param path [URI, String]
         
     | 
| 
      
 94 
     | 
    
         
            +
                # @param params [Hash, nil]
         
     | 
| 
      
 95 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
       48 
96 
     | 
    
         
             
                def url(path, params = nil)
         
     | 
| 
       49 
97 
     | 
    
         
             
                  if path.respond_to? :query
         
     | 
| 
       50 
     | 
    
         
            -
                    if query = path.query
         
     | 
| 
      
 98 
     | 
    
         
            +
                    if (query = path.query)
         
     | 
| 
       51 
99 
     | 
    
         
             
                      path = path.dup
         
     | 
| 
       52 
100 
     | 
    
         
             
                      path.query = nil
         
     | 
| 
       53 
101 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -61,34 +109,48 @@ module Faraday 
     | 
|
| 
       61 
109 
     | 
    
         
             
                  self.params.update(params) if params
         
     | 
| 
       62 
110 
     | 
    
         
             
                end
         
     | 
| 
       63 
111 
     | 
    
         | 
| 
      
 112 
     | 
    
         
            +
                # @param key [Object] key to look up in headers
         
     | 
| 
      
 113 
     | 
    
         
            +
                # @return [Object] value of the given header name
         
     | 
| 
       64 
114 
     | 
    
         
             
                def [](key)
         
     | 
| 
       65 
115 
     | 
    
         
             
                  headers[key]
         
     | 
| 
       66 
116 
     | 
    
         
             
                end
         
     | 
| 
       67 
117 
     | 
    
         | 
| 
      
 118 
     | 
    
         
            +
                # @param key [Object] key of header to write
         
     | 
| 
      
 119 
     | 
    
         
            +
                # @param value [Object] value of header
         
     | 
| 
       68 
120 
     | 
    
         
             
                def []=(key, value)
         
     | 
| 
       69 
121 
     | 
    
         
             
                  headers[key] = value
         
     | 
| 
       70 
122 
     | 
    
         
             
                end
         
     | 
| 
       71 
123 
     | 
    
         | 
| 
       72 
     | 
    
         
            -
                #  
     | 
| 
       73 
     | 
    
         
            -
                # 
     | 
| 
       74 
     | 
    
         
            -
                #  
     | 
| 
       75 
     | 
    
         
            -
                 
     | 
| 
       76 
     | 
    
         
            -
             
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
             
     | 
| 
       79 
     | 
    
         
            -
             
     | 
| 
       80 
     | 
    
         
            -
             
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
       83 
     | 
    
         
            -
             
     | 
| 
       84 
     | 
    
         
            -
                 
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
                # 
     | 
| 
       87 
     | 
    
         
            -
                #  
     | 
| 
      
 124 
     | 
    
         
            +
                # Marshal serialization support.
         
     | 
| 
      
 125 
     | 
    
         
            +
                #
         
     | 
| 
      
 126 
     | 
    
         
            +
                # @return [Hash] the hash ready to be serialized in Marshal.
         
     | 
| 
      
 127 
     | 
    
         
            +
                def marshal_dump
         
     | 
| 
      
 128 
     | 
    
         
            +
                  {
         
     | 
| 
      
 129 
     | 
    
         
            +
                    http_method: http_method,
         
     | 
| 
      
 130 
     | 
    
         
            +
                    body: body,
         
     | 
| 
      
 131 
     | 
    
         
            +
                    headers: headers,
         
     | 
| 
      
 132 
     | 
    
         
            +
                    path: path,
         
     | 
| 
      
 133 
     | 
    
         
            +
                    params: params,
         
     | 
| 
      
 134 
     | 
    
         
            +
                    options: options
         
     | 
| 
      
 135 
     | 
    
         
            +
                  }
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                # Marshal serialization support.
         
     | 
| 
      
 139 
     | 
    
         
            +
                # Restores the instance variables according to the +serialised+.
         
     | 
| 
      
 140 
     | 
    
         
            +
                # @param serialised [Hash] the serialised object.
         
     | 
| 
      
 141 
     | 
    
         
            +
                def marshal_load(serialised)
         
     | 
| 
      
 142 
     | 
    
         
            +
                  self.http_method = serialised[:http_method]
         
     | 
| 
      
 143 
     | 
    
         
            +
                  self.body        = serialised[:body]
         
     | 
| 
      
 144 
     | 
    
         
            +
                  self.headers     = serialised[:headers]
         
     | 
| 
      
 145 
     | 
    
         
            +
                  self.path        = serialised[:path]
         
     | 
| 
      
 146 
     | 
    
         
            +
                  self.params      = serialised[:params]
         
     | 
| 
      
 147 
     | 
    
         
            +
                  self.options     = serialised[:options]
         
     | 
| 
      
 148 
     | 
    
         
            +
                end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                # @return [Env] the Env for this Request
         
     | 
| 
       88 
151 
     | 
    
         
             
                def to_env(connection)
         
     | 
| 
       89 
     | 
    
         
            -
                  Env.new( 
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
      
 152 
     | 
    
         
            +
                  Env.new(http_method, body, connection.build_exclusive_url(path, params),
         
     | 
| 
      
 153 
     | 
    
         
            +
                          options, headers, connection.ssl, connection.parallel_manager)
         
     | 
| 
       91 
154 
     | 
    
         
             
                end
         
     | 
| 
       92 
155 
     | 
    
         
             
              end
         
     | 
| 
       93 
156 
     | 
    
         
             
            end
         
     | 
| 
       94 
     | 
    
         
            -
             
     |