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
 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Faraday
         
     | 
| 
      
 4 
     | 
    
         
            +
              # DependencyLoader helps Faraday adapters and middleware load dependencies.
         
     | 
| 
      
 5 
     | 
    
         
            +
              module DependencyLoader
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :load_error
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                # Executes a block which should try to require and reference dependent
         
     | 
| 
      
 9 
     | 
    
         
            +
                # libraries
         
     | 
| 
      
 10 
     | 
    
         
            +
                def dependency(lib = nil)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  lib ? require(lib) : yield
         
     | 
| 
      
 12 
     | 
    
         
            +
                rescue LoadError, NameError => e
         
     | 
| 
      
 13 
     | 
    
         
            +
                  self.load_error = e
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def new(*)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  unless loaded?
         
     | 
| 
      
 18 
     | 
    
         
            +
                    raise "missing dependency for #{self}: #{load_error.message}"
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  super
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def loaded?
         
     | 
| 
      
 25 
     | 
    
         
            +
                  load_error.nil?
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def inherited(subclass)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  super
         
     | 
| 
      
 30 
     | 
    
         
            +
                  subclass.send(:load_error=, load_error)
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                private
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                attr_writer :load_error
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,105 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Faraday
         
     | 
| 
      
 4 
     | 
    
         
            +
              # FlatParamsEncoder manages URI params as a flat hash. Any Array values repeat
         
     | 
| 
      
 5 
     | 
    
         
            +
              # the parameter multiple times.
         
     | 
| 
      
 6 
     | 
    
         
            +
              module FlatParamsEncoder
         
     | 
| 
      
 7 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 8 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 9 
     | 
    
         
            +
                  def_delegators :'Faraday::Utils', :escape, :unescape
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                # Encode converts the given param into a URI querystring. Keys and values
         
     | 
| 
      
 13 
     | 
    
         
            +
                # will converted to strings and appropriately escaped for the URI.
         
     | 
| 
      
 14 
     | 
    
         
            +
                #
         
     | 
| 
      
 15 
     | 
    
         
            +
                # @param params [Hash] query arguments to convert.
         
     | 
| 
      
 16 
     | 
    
         
            +
                #
         
     | 
| 
      
 17 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 18 
     | 
    
         
            +
                #
         
     | 
| 
      
 19 
     | 
    
         
            +
                #   encode({a: %w[one two three], b: true, c: "C"})
         
     | 
| 
      
 20 
     | 
    
         
            +
                #   # => 'a=one&a=two&a=three&b=true&c=C'
         
     | 
| 
      
 21 
     | 
    
         
            +
                #
         
     | 
| 
      
 22 
     | 
    
         
            +
                # @return [String] the URI querystring (without the leading '?')
         
     | 
| 
      
 23 
     | 
    
         
            +
                def self.encode(params)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  return nil if params.nil?
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  unless params.is_a?(Array)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    unless params.respond_to?(:to_hash)
         
     | 
| 
      
 28 
     | 
    
         
            +
                      raise TypeError,
         
     | 
| 
      
 29 
     | 
    
         
            +
                            "Can't convert #{params.class} into Hash."
         
     | 
| 
      
 30 
     | 
    
         
            +
                    end
         
     | 
| 
      
 31 
     | 
    
         
            +
                    params = params.to_hash
         
     | 
| 
      
 32 
     | 
    
         
            +
                    params = params.map do |key, value|
         
     | 
| 
      
 33 
     | 
    
         
            +
                      key = key.to_s if key.is_a?(Symbol)
         
     | 
| 
      
 34 
     | 
    
         
            +
                      [key, value]
         
     | 
| 
      
 35 
     | 
    
         
            +
                    end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                    # Only to be used for non-Array inputs. Arrays should preserve order.
         
     | 
| 
      
 38 
     | 
    
         
            +
                    params.sort! if @sort_params
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  # The params have form [['key1', 'value1'], ['key2', 'value2']].
         
     | 
| 
      
 42 
     | 
    
         
            +
                  buffer = +''
         
     | 
| 
      
 43 
     | 
    
         
            +
                  params.each do |key, value|
         
     | 
| 
      
 44 
     | 
    
         
            +
                    encoded_key = escape(key)
         
     | 
| 
      
 45 
     | 
    
         
            +
                    if value.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                      buffer << "#{encoded_key}&"
         
     | 
| 
      
 47 
     | 
    
         
            +
                    elsif value.is_a?(Array)
         
     | 
| 
      
 48 
     | 
    
         
            +
                      if value.empty?
         
     | 
| 
      
 49 
     | 
    
         
            +
                        buffer << "#{encoded_key}=&"
         
     | 
| 
      
 50 
     | 
    
         
            +
                      else
         
     | 
| 
      
 51 
     | 
    
         
            +
                        value.each do |sub_value|
         
     | 
| 
      
 52 
     | 
    
         
            +
                          encoded_value = escape(sub_value)
         
     | 
| 
      
 53 
     | 
    
         
            +
                          buffer << "#{encoded_key}=#{encoded_value}&"
         
     | 
| 
      
 54 
     | 
    
         
            +
                        end
         
     | 
| 
      
 55 
     | 
    
         
            +
                      end
         
     | 
| 
      
 56 
     | 
    
         
            +
                    else
         
     | 
| 
      
 57 
     | 
    
         
            +
                      encoded_value = escape(value)
         
     | 
| 
      
 58 
     | 
    
         
            +
                      buffer << "#{encoded_key}=#{encoded_value}&"
         
     | 
| 
      
 59 
     | 
    
         
            +
                    end
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  buffer.chop
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                # Decode converts the given URI querystring into a hash.
         
     | 
| 
      
 65 
     | 
    
         
            +
                #
         
     | 
| 
      
 66 
     | 
    
         
            +
                # @param query [String] query arguments to parse.
         
     | 
| 
      
 67 
     | 
    
         
            +
                #
         
     | 
| 
      
 68 
     | 
    
         
            +
                # @example
         
     | 
| 
      
 69 
     | 
    
         
            +
                #
         
     | 
| 
      
 70 
     | 
    
         
            +
                #   decode('a=one&a=two&a=three&b=true&c=C')
         
     | 
| 
      
 71 
     | 
    
         
            +
                #   # => {"a"=>["one", "two", "three"], "b"=>"true", "c"=>"C"}
         
     | 
| 
      
 72 
     | 
    
         
            +
                #
         
     | 
| 
      
 73 
     | 
    
         
            +
                # @return [Hash] parsed keys and value strings from the querystring.
         
     | 
| 
      
 74 
     | 
    
         
            +
                def self.decode(query)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  return nil if query.nil?
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  empty_accumulator = {}
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                  split_query = (query.split('&').map do |pair|
         
     | 
| 
      
 80 
     | 
    
         
            +
                    pair.split('=', 2) if pair && !pair.empty?
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end).compact
         
     | 
| 
      
 82 
     | 
    
         
            +
                  split_query.each_with_object(empty_accumulator.dup) do |pair, accu|
         
     | 
| 
      
 83 
     | 
    
         
            +
                    pair[0] = unescape(pair[0])
         
     | 
| 
      
 84 
     | 
    
         
            +
                    pair[1] = true if pair[1].nil?
         
     | 
| 
      
 85 
     | 
    
         
            +
                    if pair[1].respond_to?(:to_str)
         
     | 
| 
      
 86 
     | 
    
         
            +
                      pair[1] = unescape(pair[1].to_str.tr('+', ' '))
         
     | 
| 
      
 87 
     | 
    
         
            +
                    end
         
     | 
| 
      
 88 
     | 
    
         
            +
                    if accu[pair[0]].is_a?(Array)
         
     | 
| 
      
 89 
     | 
    
         
            +
                      accu[pair[0]] << pair[1]
         
     | 
| 
      
 90 
     | 
    
         
            +
                    elsif accu[pair[0]]
         
     | 
| 
      
 91 
     | 
    
         
            +
                      accu[pair[0]] = [accu[pair[0]], pair[1]]
         
     | 
| 
      
 92 
     | 
    
         
            +
                    else
         
     | 
| 
      
 93 
     | 
    
         
            +
                      accu[pair[0]] = pair[1]
         
     | 
| 
      
 94 
     | 
    
         
            +
                    end
         
     | 
| 
      
 95 
     | 
    
         
            +
                  end
         
     | 
| 
      
 96 
     | 
    
         
            +
                end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 99 
     | 
    
         
            +
                  attr_accessor :sort_params
         
     | 
| 
      
 100 
     | 
    
         
            +
                end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                # Useful default for OAuth and caching.
         
     | 
| 
      
 103 
     | 
    
         
            +
                @sort_params = true
         
     | 
| 
      
 104 
     | 
    
         
            +
              end
         
     | 
| 
      
 105 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,176 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Faraday
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Sub-module for encoding parameters into query-string.
         
     | 
| 
      
 5 
     | 
    
         
            +
              module EncodeMethods
         
     | 
| 
      
 6 
     | 
    
         
            +
                # @param params [nil, Array, #to_hash] parameters to be encoded
         
     | 
| 
      
 7 
     | 
    
         
            +
                #
         
     | 
| 
      
 8 
     | 
    
         
            +
                # @return [String] the encoded params
         
     | 
| 
      
 9 
     | 
    
         
            +
                #
         
     | 
| 
      
 10 
     | 
    
         
            +
                # @raise [TypeError] if params can not be converted to a Hash
         
     | 
| 
      
 11 
     | 
    
         
            +
                def encode(params)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  return nil if params.nil?
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  unless params.is_a?(Array)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    unless params.respond_to?(:to_hash)
         
     | 
| 
      
 16 
     | 
    
         
            +
                      raise TypeError, "Can't convert #{params.class} into Hash."
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    params = params.to_hash
         
     | 
| 
      
 20 
     | 
    
         
            +
                    params = params.map do |key, value|
         
     | 
| 
      
 21 
     | 
    
         
            +
                      key = key.to_s if key.is_a?(Symbol)
         
     | 
| 
      
 22 
     | 
    
         
            +
                      [key, value]
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    # Only to be used for non-Array inputs. Arrays should preserve order.
         
     | 
| 
      
 26 
     | 
    
         
            +
                    params.sort! if @sort_params
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  # The params have form [['key1', 'value1'], ['key2', 'value2']].
         
     | 
| 
      
 30 
     | 
    
         
            +
                  buffer = +''
         
     | 
| 
      
 31 
     | 
    
         
            +
                  params.each do |parent, value|
         
     | 
| 
      
 32 
     | 
    
         
            +
                    encoded_parent = escape(parent)
         
     | 
| 
      
 33 
     | 
    
         
            +
                    buffer << "#{encode_pair(encoded_parent, value)}&"
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
                  buffer.chop
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                protected
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def encode_pair(parent, value)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  if value.is_a?(Hash)
         
     | 
| 
      
 42 
     | 
    
         
            +
                    encode_hash(parent, value)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  elsif value.is_a?(Array)
         
     | 
| 
      
 44 
     | 
    
         
            +
                    encode_array(parent, value)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  elsif value.nil?
         
     | 
| 
      
 46 
     | 
    
         
            +
                    parent
         
     | 
| 
      
 47 
     | 
    
         
            +
                  else
         
     | 
| 
      
 48 
     | 
    
         
            +
                    encoded_value = escape(value)
         
     | 
| 
      
 49 
     | 
    
         
            +
                    "#{parent}=#{encoded_value}"
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def encode_hash(parent, value)
         
     | 
| 
      
 54 
     | 
    
         
            +
                  value = value.map { |key, val| [escape(key), val] }.sort
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                  buffer = +''
         
     | 
| 
      
 57 
     | 
    
         
            +
                  value.each do |key, val|
         
     | 
| 
      
 58 
     | 
    
         
            +
                    new_parent = "#{parent}%5B#{key}%5D"
         
     | 
| 
      
 59 
     | 
    
         
            +
                    buffer << "#{encode_pair(new_parent, val)}&"
         
     | 
| 
      
 60 
     | 
    
         
            +
                  end
         
     | 
| 
      
 61 
     | 
    
         
            +
                  buffer.chop
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def encode_array(parent, value)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  new_parent = "#{parent}%5B%5D"
         
     | 
| 
      
 66 
     | 
    
         
            +
                  return new_parent if value.empty?
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  buffer = +''
         
     | 
| 
      
 69 
     | 
    
         
            +
                  value.each { |val| buffer << "#{encode_pair(new_parent, val)}&" }
         
     | 
| 
      
 70 
     | 
    
         
            +
                  buffer.chop
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              # Sub-module for decoding query-string into parameters.
         
     | 
| 
      
 75 
     | 
    
         
            +
              module DecodeMethods
         
     | 
| 
      
 76 
     | 
    
         
            +
                # @param query [nil, String]
         
     | 
| 
      
 77 
     | 
    
         
            +
                #
         
     | 
| 
      
 78 
     | 
    
         
            +
                # @return [Array<Array, String>] the decoded params
         
     | 
| 
      
 79 
     | 
    
         
            +
                #
         
     | 
| 
      
 80 
     | 
    
         
            +
                # @raise [TypeError] if the nesting is incorrect
         
     | 
| 
      
 81 
     | 
    
         
            +
                def decode(query)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  return nil if query.nil?
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  params = {}
         
     | 
| 
      
 85 
     | 
    
         
            +
                  query.split('&').each do |pair|
         
     | 
| 
      
 86 
     | 
    
         
            +
                    next if pair.empty?
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                    key, value = pair.split('=', 2)
         
     | 
| 
      
 89 
     | 
    
         
            +
                    key = unescape(key)
         
     | 
| 
      
 90 
     | 
    
         
            +
                    value = unescape(value.tr('+', ' ')) if value
         
     | 
| 
      
 91 
     | 
    
         
            +
                    decode_pair(key, value, params)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  end
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  dehash(params, 0)
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                protected
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])?/.freeze
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                def decode_pair(key, value, context)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  subkeys = key.scan(SUBKEYS_REGEX)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  subkeys.each_with_index do |subkey, i|
         
     | 
| 
      
 104 
     | 
    
         
            +
                    is_array = subkey =~ /[\[\]]+\Z/
         
     | 
| 
      
 105 
     | 
    
         
            +
                    subkey = $` if is_array
         
     | 
| 
      
 106 
     | 
    
         
            +
                    last_subkey = i == subkeys.length - 1
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                    context = prepare_context(context, subkey, is_array, last_subkey)
         
     | 
| 
      
 109 
     | 
    
         
            +
                    add_to_context(is_array, context, value, subkey) if last_subkey
         
     | 
| 
      
 110 
     | 
    
         
            +
                  end
         
     | 
| 
      
 111 
     | 
    
         
            +
                end
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                def prepare_context(context, subkey, is_array, last_subkey)
         
     | 
| 
      
 114 
     | 
    
         
            +
                  if !last_subkey || is_array
         
     | 
| 
      
 115 
     | 
    
         
            +
                    context = new_context(subkey, is_array, context)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  end
         
     | 
| 
      
 117 
     | 
    
         
            +
                  if context.is_a?(Array) && !is_array
         
     | 
| 
      
 118 
     | 
    
         
            +
                    context = match_context(context, subkey)
         
     | 
| 
      
 119 
     | 
    
         
            +
                  end
         
     | 
| 
      
 120 
     | 
    
         
            +
                  context
         
     | 
| 
      
 121 
     | 
    
         
            +
                end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
                def new_context(subkey, is_array, context)
         
     | 
| 
      
 124 
     | 
    
         
            +
                  value_type = is_array ? Array : Hash
         
     | 
| 
      
 125 
     | 
    
         
            +
                  if context[subkey] && !context[subkey].is_a?(value_type)
         
     | 
| 
      
 126 
     | 
    
         
            +
                    raise TypeError, "expected #{value_type.name} " \
         
     | 
| 
      
 127 
     | 
    
         
            +
                      "(got #{context[subkey].class.name}) for param `#{subkey}'"
         
     | 
| 
      
 128 
     | 
    
         
            +
                  end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  context[subkey] ||= value_type.new
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
                def match_context(context, subkey)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  context << {} if !context.last.is_a?(Hash) || context.last.key?(subkey)
         
     | 
| 
      
 135 
     | 
    
         
            +
                  context.last
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                def add_to_context(is_array, context, value, subkey)
         
     | 
| 
      
 139 
     | 
    
         
            +
                  is_array ? context << value : context[subkey] = value
         
     | 
| 
      
 140 
     | 
    
         
            +
                end
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                # Internal: convert a nested hash with purely numeric keys into an array.
         
     | 
| 
      
 143 
     | 
    
         
            +
                # FIXME: this is not compatible with Rack::Utils.parse_nested_query
         
     | 
| 
      
 144 
     | 
    
         
            +
                # @!visibility private
         
     | 
| 
      
 145 
     | 
    
         
            +
                def dehash(hash, depth)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  hash.each do |key, value|
         
     | 
| 
      
 147 
     | 
    
         
            +
                    hash[key] = dehash(value, depth + 1) if value.is_a?(Hash)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  end
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
      
 150 
     | 
    
         
            +
                  if depth.positive? && !hash.empty? && hash.keys.all? { |k| k =~ /^\d+$/ }
         
     | 
| 
      
 151 
     | 
    
         
            +
                    hash.sort.map(&:last)
         
     | 
| 
      
 152 
     | 
    
         
            +
                  else
         
     | 
| 
      
 153 
     | 
    
         
            +
                    hash
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
              end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
              # This is the default encoder for Faraday requests.
         
     | 
| 
      
 159 
     | 
    
         
            +
              # Using this encoder, parameters will be encoded respecting their structure,
         
     | 
| 
      
 160 
     | 
    
         
            +
              # so you can send objects such as Arrays or Hashes as parameters
         
     | 
| 
      
 161 
     | 
    
         
            +
              # for your requests.
         
     | 
| 
      
 162 
     | 
    
         
            +
              module NestedParamsEncoder
         
     | 
| 
      
 163 
     | 
    
         
            +
                class << self
         
     | 
| 
      
 164 
     | 
    
         
            +
                  attr_accessor :sort_params
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                  extend Forwardable
         
     | 
| 
      
 167 
     | 
    
         
            +
                  def_delegators :'Faraday::Utils', :escape, :unescape
         
     | 
| 
      
 168 
     | 
    
         
            +
                end
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                # Useful default for OAuth and caching.
         
     | 
| 
      
 171 
     | 
    
         
            +
                @sort_params = true
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                extend EncodeMethods
         
     | 
| 
      
 174 
     | 
    
         
            +
                extend DecodeMethods
         
     | 
| 
      
 175 
     | 
    
         
            +
              end
         
     | 
| 
      
 176 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/faraday/error.rb
    CHANGED
    
    | 
         @@ -1,23 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # Faraday namespace.
         
     | 
| 
       1 
4 
     | 
    
         
             
            module Faraday
         
     | 
| 
       2 
     | 
    
         
            -
               
     | 
| 
       3 
     | 
    
         
            -
              class  
     | 
| 
      
 5 
     | 
    
         
            +
              # Faraday error base class.
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Error < StandardError
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :response, :wrapped_exception
         
     | 
| 
       4 
8 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
                  @wrapped_exception = nil
         
     | 
| 
       10 
     | 
    
         
            -
                  @response = response
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
                  if ex.respond_to?(:backtrace)
         
     | 
| 
       13 
     | 
    
         
            -
                    super(ex.message)
         
     | 
| 
       14 
     | 
    
         
            -
                    @wrapped_exception = ex
         
     | 
| 
       15 
     | 
    
         
            -
                  elsif ex.respond_to?(:each_key)
         
     | 
| 
       16 
     | 
    
         
            -
                    super("the server responded with status #{ex[:status]}")
         
     | 
| 
       17 
     | 
    
         
            -
                    @response = ex
         
     | 
| 
       18 
     | 
    
         
            -
                  else
         
     | 
| 
       19 
     | 
    
         
            -
                    super(ex.to_s)
         
     | 
| 
       20 
     | 
    
         
            -
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(exc, response = nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @wrapped_exception = nil unless defined?(@wrapped_exception)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @response = nil unless defined?(@response)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  super(exc_msg_and_response!(exc, response))
         
     | 
| 
       21 
13 
     | 
    
         
             
                end
         
     | 
| 
       22 
14 
     | 
    
         | 
| 
       23 
15 
     | 
    
         
             
                def backtrace
         
     | 
| 
         @@ -29,35 +21,132 @@ module Faraday 
     | 
|
| 
       29 
21 
     | 
    
         
             
                end
         
     | 
| 
       30 
22 
     | 
    
         | 
| 
       31 
23 
     | 
    
         
             
                def inspect
         
     | 
| 
       32 
     | 
    
         
            -
                  inner = ''
         
     | 
| 
       33 
     | 
    
         
            -
                  if @wrapped_exception
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                   
     | 
| 
       36 
     | 
    
         
            -
                  if @response
         
     | 
| 
       37 
     | 
    
         
            -
                    inner << " response=#{@response.inspect}"
         
     | 
| 
       38 
     | 
    
         
            -
                  end
         
     | 
| 
       39 
     | 
    
         
            -
                  if inner.empty?
         
     | 
| 
       40 
     | 
    
         
            -
                    inner << " #{super}"
         
     | 
| 
       41 
     | 
    
         
            -
                  end
         
     | 
| 
      
 24 
     | 
    
         
            +
                  inner = +''
         
     | 
| 
      
 25 
     | 
    
         
            +
                  inner << " wrapped=#{@wrapped_exception.inspect}" if @wrapped_exception
         
     | 
| 
      
 26 
     | 
    
         
            +
                  inner << " response=#{@response.inspect}" if @response
         
     | 
| 
      
 27 
     | 
    
         
            +
                  inner << " #{super}" if inner.empty?
         
     | 
| 
       42 
28 
     | 
    
         
             
                  %(#<#{self.class}#{inner}>)
         
     | 
| 
       43 
29 
     | 
    
         
             
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def response_status
         
     | 
| 
      
 32 
     | 
    
         
            +
                  @response[:status] if @response
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def response_headers
         
     | 
| 
      
 36 
     | 
    
         
            +
                  @response[:headers] if @response
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                def response_body
         
     | 
| 
      
 40 
     | 
    
         
            +
                  @response[:body] if @response
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                protected
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                # Pulls out potential parent exception and response hash, storing them in
         
     | 
| 
      
 46 
     | 
    
         
            +
                # instance variables.
         
     | 
| 
      
 47 
     | 
    
         
            +
                # exc      - Either an Exception, a string message, or a response hash.
         
     | 
| 
      
 48 
     | 
    
         
            +
                # response - Hash
         
     | 
| 
      
 49 
     | 
    
         
            +
                #              :status  - Optional integer HTTP response status
         
     | 
| 
      
 50 
     | 
    
         
            +
                #              :headers - String key/value hash of HTTP response header
         
     | 
| 
      
 51 
     | 
    
         
            +
                #                         values.
         
     | 
| 
      
 52 
     | 
    
         
            +
                #              :body    - Optional string HTTP response body.
         
     | 
| 
      
 53 
     | 
    
         
            +
                #              :request - Hash
         
     | 
| 
      
 54 
     | 
    
         
            +
                #                           :method   - Symbol with the request HTTP method.
         
     | 
| 
      
 55 
     | 
    
         
            +
                #                           :url_path - String with the url path requested.
         
     | 
| 
      
 56 
     | 
    
         
            +
                #                           :params   - String key/value hash of query params
         
     | 
| 
      
 57 
     | 
    
         
            +
                #                                     present in the request.
         
     | 
| 
      
 58 
     | 
    
         
            +
                #                           :headers  - String key/value hash of HTTP request
         
     | 
| 
      
 59 
     | 
    
         
            +
                #                                     header values.
         
     | 
| 
      
 60 
     | 
    
         
            +
                #                           :body     - String HTTP request body.
         
     | 
| 
      
 61 
     | 
    
         
            +
                #
         
     | 
| 
      
 62 
     | 
    
         
            +
                # If a subclass has to call this, then it should pass a string message
         
     | 
| 
      
 63 
     | 
    
         
            +
                # to `super`. See NilStatusError.
         
     | 
| 
      
 64 
     | 
    
         
            +
                def exc_msg_and_response!(exc, response = nil)
         
     | 
| 
      
 65 
     | 
    
         
            +
                  if @response.nil? && @wrapped_exception.nil?
         
     | 
| 
      
 66 
     | 
    
         
            +
                    @wrapped_exception, msg, @response = exc_msg_and_response(exc, response)
         
     | 
| 
      
 67 
     | 
    
         
            +
                    return msg
         
     | 
| 
      
 68 
     | 
    
         
            +
                  end
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  exc.to_s
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                # Pulls out potential parent exception and response hash.
         
     | 
| 
      
 74 
     | 
    
         
            +
                def exc_msg_and_response(exc, response = nil)
         
     | 
| 
      
 75 
     | 
    
         
            +
                  return [exc, exc.message, response] if exc.respond_to?(:backtrace)
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                  return [nil, "the server responded with status #{exc[:status]}", exc] \
         
     | 
| 
      
 78 
     | 
    
         
            +
                    if exc.respond_to?(:each_key)
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  [nil, exc.to_s, response]
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
              # Faraday client error class. Represents 4xx status responses.
         
     | 
| 
      
 85 
     | 
    
         
            +
              class ClientError < Error
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 400 response.
         
     | 
| 
      
 89 
     | 
    
         
            +
              class BadRequestError < ClientError
         
     | 
| 
      
 90 
     | 
    
         
            +
              end
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 401 response.
         
     | 
| 
      
 93 
     | 
    
         
            +
              class UnauthorizedError < ClientError
         
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 403 response.
         
     | 
| 
      
 97 
     | 
    
         
            +
              class ForbiddenError < ClientError
         
     | 
| 
      
 98 
     | 
    
         
            +
              end
         
     | 
| 
      
 99 
     | 
    
         
            +
             
     | 
| 
      
 100 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 404 response.
         
     | 
| 
      
 101 
     | 
    
         
            +
              class ResourceNotFound < ClientError
         
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 407 response.
         
     | 
| 
      
 105 
     | 
    
         
            +
              class ProxyAuthError < ClientError
         
     | 
| 
       44 
106 
     | 
    
         
             
              end
         
     | 
| 
       45 
107 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
               
     | 
| 
       47 
     | 
    
         
            -
              class  
     | 
| 
       48 
     | 
    
         
            -
               
     | 
| 
      
 108 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 409 response.
         
     | 
| 
      
 109 
     | 
    
         
            +
              class ConflictError < ClientError
         
     | 
| 
      
 110 
     | 
    
         
            +
              end
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a 422 response.
         
     | 
| 
      
 113 
     | 
    
         
            +
              class UnprocessableEntityError < ClientError
         
     | 
| 
      
 114 
     | 
    
         
            +
              end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
              # Faraday server error class. Represents 5xx status responses.
         
     | 
| 
      
 117 
     | 
    
         
            +
              class ServerError < Error
         
     | 
| 
      
 118 
     | 
    
         
            +
              end
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
              # A unified client error for timeouts.
         
     | 
| 
      
 121 
     | 
    
         
            +
              class TimeoutError < ServerError
         
     | 
| 
      
 122 
     | 
    
         
            +
                def initialize(exc = 'timeout', response = nil)
         
     | 
| 
      
 123 
     | 
    
         
            +
                  super(exc, response)
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
       49 
126 
     | 
    
         | 
| 
       50 
     | 
    
         
            -
               
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
     | 
    
         
            -
             
     | 
| 
      
 127 
     | 
    
         
            +
              # Raised by Faraday::Response::RaiseError in case of a nil status in response.
         
     | 
| 
      
 128 
     | 
    
         
            +
              class NilStatusError < ServerError
         
     | 
| 
      
 129 
     | 
    
         
            +
                def initialize(exc, response = nil)
         
     | 
| 
      
 130 
     | 
    
         
            +
                  exc_msg_and_response!(exc, response)
         
     | 
| 
      
 131 
     | 
    
         
            +
                  super('http status could not be derived from the server response')
         
     | 
| 
       53 
132 
     | 
    
         
             
                end
         
     | 
| 
       54 
133 
     | 
    
         
             
              end
         
     | 
| 
       55 
134 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
               
     | 
| 
      
 135 
     | 
    
         
            +
              # A unified error for failed connections.
         
     | 
| 
      
 136 
     | 
    
         
            +
              class ConnectionFailed < Error
         
     | 
| 
      
 137 
     | 
    
         
            +
              end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
              # A unified client error for SSL errors.
         
     | 
| 
      
 140 
     | 
    
         
            +
              class SSLError < Error
         
     | 
| 
      
 141 
     | 
    
         
            +
              end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
              # Raised by FaradayMiddleware::ResponseMiddleware
         
     | 
| 
      
 144 
     | 
    
         
            +
              class ParsingError < Error
         
     | 
| 
       57 
145 
     | 
    
         
             
              end
         
     | 
| 
       58 
146 
     | 
    
         | 
| 
       59 
     | 
    
         
            -
               
     | 
| 
       60 
     | 
    
         
            -
             
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 147 
     | 
    
         
            +
              # Exception used to control the Retry middleware.
         
     | 
| 
      
 148 
     | 
    
         
            +
              #
         
     | 
| 
      
 149 
     | 
    
         
            +
              # @see Faraday::Request::Retry
         
     | 
| 
      
 150 
     | 
    
         
            +
              class RetriableResponse < Error
         
     | 
| 
       62 
151 
     | 
    
         
             
              end
         
     | 
| 
       63 
152 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,128 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'stringio'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            # multipart-post gem
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'composite_io'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'parts'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            module Faraday
         
     | 
| 
      
 10 
     | 
    
         
            +
              # Multipart value used to POST a binary data from a file or
         
     | 
| 
      
 11 
     | 
    
         
            +
              #
         
     | 
| 
      
 12 
     | 
    
         
            +
              # @example
         
     | 
| 
      
 13 
     | 
    
         
            +
              #   payload = { file: Faraday::FilePart.new("file_name.ext", "content/type") }
         
     | 
| 
      
 14 
     | 
    
         
            +
              #   http.post("/upload", payload)
         
     | 
| 
      
 15 
     | 
    
         
            +
              #
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
              # @!method initialize(filename_or_io, content_type, filename = nil, opts = {})
         
     | 
| 
      
 18 
     | 
    
         
            +
              #
         
     | 
| 
      
 19 
     | 
    
         
            +
              #   @param filename_or_io [String, IO] Either a String filename to a local
         
     | 
| 
      
 20 
     | 
    
         
            +
              #     file or an open IO object.
         
     | 
| 
      
 21 
     | 
    
         
            +
              #   @param content_type [String] String content type of the file data.
         
     | 
| 
      
 22 
     | 
    
         
            +
              #   @param filename [String] Optional String filename, usually to add context
         
     | 
| 
      
 23 
     | 
    
         
            +
              #     to a given IO object.
         
     | 
| 
      
 24 
     | 
    
         
            +
              #   @param opts [Hash] Optional Hash of String key/value pairs to describethis
         
     | 
| 
      
 25 
     | 
    
         
            +
              #     this uploaded file. Expected Header keys include:
         
     | 
| 
      
 26 
     | 
    
         
            +
              #     * Content-Transfer-Encoding - Defaults to "binary"
         
     | 
| 
      
 27 
     | 
    
         
            +
              #     * Content-Disposition - Defaults to "form-data"
         
     | 
| 
      
 28 
     | 
    
         
            +
              #     * Content-Type - Defaults to the content_type argument.
         
     | 
| 
      
 29 
     | 
    
         
            +
              #     * Content-ID - Optional.
         
     | 
| 
      
 30 
     | 
    
         
            +
              #
         
     | 
| 
      
 31 
     | 
    
         
            +
              # @return [Faraday::FilePart]
         
     | 
| 
      
 32 
     | 
    
         
            +
              #
         
     | 
| 
      
 33 
     | 
    
         
            +
              # @!attribute [r] content_type
         
     | 
| 
      
 34 
     | 
    
         
            +
              # The uploaded binary data's content type.
         
     | 
| 
      
 35 
     | 
    
         
            +
              #
         
     | 
| 
      
 36 
     | 
    
         
            +
              # @return [String]
         
     | 
| 
      
 37 
     | 
    
         
            +
              #
         
     | 
| 
      
 38 
     | 
    
         
            +
              # @!attribute [r] original_filename
         
     | 
| 
      
 39 
     | 
    
         
            +
              # The base filename, taken either from the filename_or_io or filename
         
     | 
| 
      
 40 
     | 
    
         
            +
              # arguments in #initialize.
         
     | 
| 
      
 41 
     | 
    
         
            +
              #
         
     | 
| 
      
 42 
     | 
    
         
            +
              # @return [String]
         
     | 
| 
      
 43 
     | 
    
         
            +
              #
         
     | 
| 
      
 44 
     | 
    
         
            +
              # @!attribute [r] opts
         
     | 
| 
      
 45 
     | 
    
         
            +
              # Extra String key/value pairs to make up the header for this uploaded file.
         
     | 
| 
      
 46 
     | 
    
         
            +
              #
         
     | 
| 
      
 47 
     | 
    
         
            +
              # @return [Hash]
         
     | 
| 
      
 48 
     | 
    
         
            +
              #
         
     | 
| 
      
 49 
     | 
    
         
            +
              # @!attribute [r] io
         
     | 
| 
      
 50 
     | 
    
         
            +
              # The open IO object for the uploaded file.
         
     | 
| 
      
 51 
     | 
    
         
            +
              #
         
     | 
| 
      
 52 
     | 
    
         
            +
              # @return [IO]
         
     | 
| 
      
 53 
     | 
    
         
            +
              FilePart = ::UploadIO
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              # Multipart value used to POST a file.
         
     | 
| 
      
 56 
     | 
    
         
            +
              #
         
     | 
| 
      
 57 
     | 
    
         
            +
              # @deprecated Use FilePart instead of this class. It behaves identically, with
         
     | 
| 
      
 58 
     | 
    
         
            +
              #   a matching name to ParamPart.
         
     | 
| 
      
 59 
     | 
    
         
            +
              UploadIO = ::UploadIO
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              Parts = ::Parts
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              # Similar to, but not compatible with CompositeReadIO provided by the
         
     | 
| 
      
 64 
     | 
    
         
            +
              # multipart-post gem.
         
     | 
| 
      
 65 
     | 
    
         
            +
              # https://github.com/nicksieger/multipart-post/blob/master/lib/composite_io.rb
         
     | 
| 
      
 66 
     | 
    
         
            +
              class CompositeReadIO
         
     | 
| 
      
 67 
     | 
    
         
            +
                def initialize(*parts)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @parts = parts.flatten
         
     | 
| 
      
 69 
     | 
    
         
            +
                  @ios = @parts.map(&:to_io)
         
     | 
| 
      
 70 
     | 
    
         
            +
                  @index = 0
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                # @return [Integer] sum of the lengths of all the parts
         
     | 
| 
      
 74 
     | 
    
         
            +
                def length
         
     | 
| 
      
 75 
     | 
    
         
            +
                  @parts.inject(0) { |sum, part| sum + part.length }
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                # Rewind each of the IOs and reset the index to 0.
         
     | 
| 
      
 79 
     | 
    
         
            +
                #
         
     | 
| 
      
 80 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 81 
     | 
    
         
            +
                def rewind
         
     | 
| 
      
 82 
     | 
    
         
            +
                  @ios.each(&:rewind)
         
     | 
| 
      
 83 
     | 
    
         
            +
                  @index = 0
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                # Read from IOs in order until `length` bytes have been received.
         
     | 
| 
      
 87 
     | 
    
         
            +
                #
         
     | 
| 
      
 88 
     | 
    
         
            +
                # @param length [Integer, nil]
         
     | 
| 
      
 89 
     | 
    
         
            +
                # @param outbuf [String, nil]
         
     | 
| 
      
 90 
     | 
    
         
            +
                def read(length = nil, outbuf = nil)
         
     | 
| 
      
 91 
     | 
    
         
            +
                  got_result = false
         
     | 
| 
      
 92 
     | 
    
         
            +
                  outbuf = outbuf ? (+outbuf).replace('') : +''
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
                  while (io = current_io)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    if (result = io.read(length))
         
     | 
| 
      
 96 
     | 
    
         
            +
                      got_result ||= !result.nil?
         
     | 
| 
      
 97 
     | 
    
         
            +
                      result.force_encoding('BINARY') if result.respond_to?(:force_encoding)
         
     | 
| 
      
 98 
     | 
    
         
            +
                      outbuf << result
         
     | 
| 
      
 99 
     | 
    
         
            +
                      length -= result.length if length
         
     | 
| 
      
 100 
     | 
    
         
            +
                      break if length&.zero?
         
     | 
| 
      
 101 
     | 
    
         
            +
                    end
         
     | 
| 
      
 102 
     | 
    
         
            +
                    advance_io
         
     | 
| 
      
 103 
     | 
    
         
            +
                  end
         
     | 
| 
      
 104 
     | 
    
         
            +
                  !got_result && length ? nil : outbuf
         
     | 
| 
      
 105 
     | 
    
         
            +
                end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                # Close each of the IOs.
         
     | 
| 
      
 108 
     | 
    
         
            +
                #
         
     | 
| 
      
 109 
     | 
    
         
            +
                # @return [void]
         
     | 
| 
      
 110 
     | 
    
         
            +
                def close
         
     | 
| 
      
 111 
     | 
    
         
            +
                  @ios.each(&:close)
         
     | 
| 
      
 112 
     | 
    
         
            +
                end
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                def ensure_open_and_readable
         
     | 
| 
      
 115 
     | 
    
         
            +
                  # Rubinius compatibility
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                private
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                def current_io
         
     | 
| 
      
 121 
     | 
    
         
            +
                  @ios[@index]
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                def advance_io
         
     | 
| 
      
 125 
     | 
    
         
            +
                  @index += 1
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
              end
         
     | 
| 
      
 128 
     | 
    
         
            +
            end
         
     |