faraday 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +347 -18
  4. data/lib/faraday/adapter/em_http.rb +99 -142
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
  6. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
  7. data/lib/faraday/adapter/em_synchrony.rb +60 -104
  8. data/lib/faraday/adapter/excon.rb +55 -100
  9. data/lib/faraday/adapter/httpclient.rb +39 -61
  10. data/lib/faraday/adapter/net_http.rb +51 -104
  11. data/lib/faraday/adapter/net_http_persistent.rb +27 -48
  12. data/lib/faraday/adapter/patron.rb +35 -54
  13. data/lib/faraday/adapter/rack.rb +12 -28
  14. data/lib/faraday/adapter/test.rb +53 -86
  15. data/lib/faraday/adapter/typhoeus.rb +1 -4
  16. data/lib/faraday/adapter.rb +22 -36
  17. data/lib/faraday/autoload.rb +36 -47
  18. data/lib/faraday/connection.rb +179 -321
  19. data/lib/faraday/error.rb +33 -67
  20. data/lib/faraday/middleware.rb +28 -4
  21. data/lib/faraday/options.rb +186 -35
  22. data/lib/faraday/parameters.rb +197 -4
  23. data/lib/faraday/rack_builder.rb +56 -67
  24. data/lib/faraday/request/authorization.rb +30 -42
  25. data/lib/faraday/request/basic_authentication.rb +7 -14
  26. data/lib/faraday/request/instrumentation.rb +27 -45
  27. data/lib/faraday/request/multipart.rb +48 -79
  28. data/lib/faraday/request/retry.rb +170 -197
  29. data/lib/faraday/request/token_authentication.rb +10 -15
  30. data/lib/faraday/request/url_encoded.rb +23 -41
  31. data/lib/faraday/request.rb +36 -68
  32. data/lib/faraday/response/logger.rb +69 -22
  33. data/lib/faraday/response/raise_error.rb +14 -36
  34. data/lib/faraday/response.rb +16 -23
  35. data/lib/faraday/upload_io.rb +67 -0
  36. data/lib/faraday/utils.rb +245 -28
  37. data/lib/faraday.rb +175 -93
  38. metadata +5 -22
  39. data/lib/faraday/adapter_registry.rb +0 -28
  40. data/lib/faraday/dependency_loader.rb +0 -37
  41. data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
  42. data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
  43. data/lib/faraday/file_part.rb +0 -128
  44. data/lib/faraday/logging/formatter.rb +0 -92
  45. data/lib/faraday/middleware_registry.rb +0 -129
  46. data/lib/faraday/options/connection_options.rb +0 -22
  47. data/lib/faraday/options/env.rb +0 -181
  48. data/lib/faraday/options/proxy_options.rb +0 -28
  49. data/lib/faraday/options/request_options.rb +0 -21
  50. data/lib/faraday/options/ssl_options.rb +0 -59
  51. data/lib/faraday/param_part.rb +0 -53
  52. data/lib/faraday/utils/headers.rb +0 -139
  53. data/lib/faraday/utils/params_hash.rb +0 -61
  54. data/spec/external_adapters/faraday_specs_setup.rb +0 -14
@@ -1,129 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'monitor'
4
-
5
- module Faraday
6
- # Adds the ability for other modules to register and lookup
7
- # middleware classes.
8
- module MiddlewareRegistry
9
- # Register middleware class(es) on the current module.
10
- #
11
- # @param autoload_path [String] Middleware autoload path
12
- # @param mapping [Hash{
13
- # Symbol => Module,
14
- # Symbol => Array<Module, Symbol, String>,
15
- # }] Middleware mapping from a lookup symbol to a reference to the
16
- # middleware.
17
- # Classes can be expressed as:
18
- # - a fully qualified constant
19
- # - a Symbol
20
- # - a Proc that will be lazily called to return the former
21
- # - an array is given, its first element is the constant or symbol,
22
- # and its second is a file to `require`.
23
- # @return [void]
24
- #
25
- # @example Lookup by a constant
26
- #
27
- # module Faraday
28
- # class Whatever
29
- # # Middleware looked up by :foo returns Faraday::Whatever::Foo.
30
- # register_middleware foo: Foo
31
- # end
32
- # end
33
- #
34
- # @example Lookup by a symbol
35
- #
36
- # module Faraday
37
- # class Whatever
38
- # # Middleware looked up by :bar returns
39
- # # Faraday::Whatever.const_get(:Bar)
40
- # register_middleware bar: :Bar
41
- # end
42
- # end
43
- #
44
- # @example Lookup by a symbol and string in an array
45
- #
46
- # module Faraday
47
- # class Whatever
48
- # # Middleware looked up by :baz requires 'baz' and returns
49
- # # Faraday::Whatever.const_get(:Baz)
50
- # register_middleware baz: [:Baz, 'baz']
51
- # end
52
- # end
53
- #
54
- def register_middleware(autoload_path = nil, mapping = nil)
55
- if mapping.nil?
56
- mapping = autoload_path
57
- autoload_path = nil
58
- end
59
- middleware_mutex do
60
- @middleware_autoload_path = autoload_path if autoload_path
61
- (@registered_middleware ||= {}).update(mapping)
62
- end
63
- end
64
-
65
- # Unregister a previously registered middleware class.
66
- #
67
- # @param key [Symbol] key for the registered middleware.
68
- def unregister_middleware(key)
69
- @registered_middleware.delete(key)
70
- end
71
-
72
- # Lookup middleware class with a registered Symbol shortcut.
73
- #
74
- # @param key [Symbol] key for the registered middleware.
75
- # @return [Class] a middleware Class.
76
- # @raise [Faraday::Error] if given key is not registered
77
- #
78
- # @example
79
- #
80
- # module Faraday
81
- # class Whatever
82
- # register_middleware foo: Foo
83
- # end
84
- # end
85
- #
86
- # Faraday::Whatever.lookup_middleware(:foo)
87
- # # => Faraday::Whatever::Foo
88
- #
89
- def lookup_middleware(key)
90
- load_middleware(key) ||
91
- raise(Faraday::Error, "#{key.inspect} is not registered on #{self}")
92
- end
93
-
94
- def middleware_mutex(&block)
95
- @middleware_mutex ||= Monitor.new
96
- @middleware_mutex.synchronize(&block)
97
- end
98
-
99
- def fetch_middleware(key)
100
- defined?(@registered_middleware) && @registered_middleware[key]
101
- end
102
-
103
- def load_middleware(key)
104
- value = fetch_middleware(key)
105
- case value
106
- when Module
107
- value
108
- when Symbol, String
109
- middleware_mutex do
110
- @registered_middleware[key] = const_get(value)
111
- end
112
- when Proc
113
- middleware_mutex do
114
- @registered_middleware[key] = value.call
115
- end
116
- when Array
117
- middleware_mutex do
118
- const, path = value
119
- if (root = @middleware_autoload_path)
120
- path = "#{root}/#{path}"
121
- end
122
- require(path)
123
- @registered_middleware[key] = const
124
- end
125
- load_middleware(key)
126
- end
127
- end
128
- end
129
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # ConnectionOptions contains the configurable properties for a Faraday
5
- # connection object.
6
- class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
7
- :parallel_manager, :params, :headers,
8
- :builder_class)
9
-
10
- options request: RequestOptions, ssl: SSLOptions
11
-
12
- memoized(:request) { self.class.options_for(:request).new }
13
-
14
- memoized(:ssl) { self.class.options_for(:ssl).new }
15
-
16
- memoized(:builder_class) { RackBuilder }
17
-
18
- def new_builder(block)
19
- builder_class.new(&block)
20
- end
21
- end
22
- end
@@ -1,181 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # @!attribute method
5
- # @return [Symbol] HTTP method (`:get`, `:post`)
6
- #
7
- # @!attribute body
8
- # @return [String] The request body that will eventually be converted to a
9
- # string.
10
- #
11
- # @!attribute url
12
- # @return [URI] URI instance for the current request.
13
- #
14
- # @!attribute request
15
- # @return [Hash] options for configuring the request.
16
- # Options for configuring the request.
17
- #
18
- # - `:timeout` open/read timeout Integer in seconds
19
- # - `:open_timeout` - read timeout Integer in seconds
20
- # - `:on_data` - Proc for streaming
21
- # - `:proxy` - Hash of proxy options
22
- # - `:uri` - Proxy Server URI
23
- # - `:user` - Proxy server username
24
- # - `:password` - Proxy server password
25
- #
26
- # @!attribute request_headers
27
- # @return [Hash] HTTP Headers to be sent to the server.
28
- #
29
- # @!attribute ssl
30
- # @return [Hash] options for configuring SSL requests
31
- #
32
- # @!attribute parallel_manager
33
- # @return [Object] sent if the connection is in parallel mode
34
- #
35
- # @!attribute params
36
- # @return [Hash]
37
- #
38
- # @!attribute response
39
- # @return [Response]
40
- #
41
- # @!attribute response_headers
42
- # @return [Hash] HTTP headers from the server
43
- #
44
- # @!attribute status
45
- # @return [Integer] HTTP response status code
46
- #
47
- # @!attribute reason_phrase
48
- # @return [String]
49
- class Env < Options.new(:method, :request_body, :url, :request,
50
- :request_headers, :ssl, :parallel_manager, :params,
51
- :response, :response_headers, :status,
52
- :reason_phrase, :response_body)
53
-
54
- # rubocop:disable Naming/ConstantName
55
- ContentLength = 'Content-Length'
56
- StatusesWithoutBody = Set.new [204, 304]
57
- SuccessfulStatuses = (200..299).freeze
58
- # rubocop:enable Naming/ConstantName
59
-
60
- # A Set of HTTP verbs that typically send a body. If no body is set for
61
- # these requests, the Content-Length header is set to 0.
62
- MethodsWithBodies = Set.new(Faraday::METHODS_WITH_BODY.map(&:to_sym))
63
-
64
- options request: RequestOptions,
65
- request_headers: Utils::Headers, response_headers: Utils::Headers
66
-
67
- extend Forwardable
68
-
69
- def_delegators :request, :params_encoder
70
-
71
- # Build a new Env from given value. Respects and updates `custom_members`.
72
- #
73
- # @param value [Object] a value fitting Option.from(v).
74
- # @return [Env] from given value
75
- def self.from(value)
76
- env = super(value)
77
- if value.respond_to?(:custom_members)
78
- env.custom_members.update(value.custom_members)
79
- end
80
- env
81
- end
82
-
83
- # @param key [Object]
84
- def [](key)
85
- return self[current_body] if key == :body
86
-
87
- if in_member_set?(key)
88
- super(key)
89
- else
90
- custom_members[key]
91
- end
92
- end
93
-
94
- # @param key [Object]
95
- # @param value [Object]
96
- def []=(key, value)
97
- if key == :body
98
- super(current_body, value)
99
- return
100
- end
101
-
102
- if in_member_set?(key)
103
- super(key, value)
104
- else
105
- custom_members[key] = value
106
- end
107
- end
108
-
109
- def current_body
110
- !!status ? :response_body : :request_body
111
- end
112
-
113
- def body
114
- self[:body]
115
- end
116
-
117
- def body=(value)
118
- self[:body] = value
119
- end
120
-
121
- # @return [Boolean] true if status is in the set of {SuccessfulStatuses}.
122
- def success?
123
- SuccessfulStatuses.include?(status)
124
- end
125
-
126
- # @return [Boolean] true if there's no body yet, and the method is in the
127
- # set of {MethodsWithBodies}.
128
- def needs_body?
129
- !body && MethodsWithBodies.include?(method)
130
- end
131
-
132
- # Sets content length to zero and the body to the empty string.
133
- def clear_body
134
- request_headers[ContentLength] = '0'
135
- self.body = ''
136
- end
137
-
138
- # @return [Boolean] true if the status isn't in the set of
139
- # {StatusesWithoutBody}.
140
- def parse_body?
141
- !StatusesWithoutBody.include?(status)
142
- end
143
-
144
- # @return [Boolean] true if there is a parallel_manager
145
- def parallel?
146
- !!parallel_manager
147
- end
148
-
149
- def inspect
150
- attrs = [nil]
151
- members.each do |mem|
152
- if (value = send(mem))
153
- attrs << "@#{mem}=#{value.inspect}"
154
- end
155
- end
156
- attrs << "@custom=#{custom_members.inspect}" unless custom_members.empty?
157
- %(#<#{self.class}#{attrs.join(' ')}>)
158
- end
159
-
160
- # @private
161
- def custom_members
162
- @custom_members ||= {}
163
- end
164
-
165
- # @private
166
- if members.first.is_a?(Symbol)
167
- def in_member_set?(key)
168
- self.class.member_set.include?(key.to_sym)
169
- end
170
- else
171
- def in_member_set?(key)
172
- self.class.member_set.include?(key.to_s)
173
- end
174
- end
175
-
176
- # @private
177
- def self.member_set
178
- @member_set ||= Set.new(members)
179
- end
180
- end
181
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # ProxyOptions contains the configurable properties for the proxy
5
- # configuration used when making an HTTP request.
6
- class ProxyOptions < Options.new(:uri, :user, :password)
7
- extend Forwardable
8
- def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=,
9
- :path, :path=
10
-
11
- def self.from(value)
12
- case value
13
- when String
14
- value = { uri: Utils.URI(value) }
15
- when URI
16
- value = { uri: value }
17
- when Hash, Options
18
- if (uri = value.delete(:uri))
19
- value[:uri] = Utils.URI(uri)
20
- end
21
- end
22
- super(value)
23
- end
24
-
25
- memoized(:user) { uri&.user && Utils.unescape(uri.user) }
26
- memoized(:password) { uri&.password && Utils.unescape(uri.password) }
27
- end
28
- end
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # RequestOptions contains the configurable properties for a Faraday request.
5
- class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
6
- :timeout, :open_timeout, :write_timeout,
7
- :boundary, :oauth, :context, :on_data)
8
-
9
- def []=(key, value)
10
- if key && key.to_sym == :proxy
11
- super(key, value ? ProxyOptions.from(value) : nil)
12
- else
13
- super(key, value)
14
- end
15
- end
16
-
17
- def stream_response?
18
- on_data.is_a?(Proc)
19
- end
20
- end
21
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # SSL-related options.
5
- #
6
- # @!attribute verify
7
- # @return [Boolean] whether to verify SSL certificates or not
8
- #
9
- # @!attribute ca_file
10
- # @return [String] CA file
11
- #
12
- # @!attribute ca_path
13
- # @return [String] CA path
14
- #
15
- # @!attribute verify_mode
16
- # @return [Integer] Any `OpenSSL::SSL::` constant (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL.html)
17
- #
18
- # @!attribute cert_store
19
- # @return [OpenSSL::X509::Store] certificate store
20
- #
21
- # @!attribute client_cert
22
- # @return [String, OpenSSL::X509::Certificate] client certificate
23
- #
24
- # @!attribute client_key
25
- # @return [String, OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] client key
26
- #
27
- # @!attribute certificate
28
- # @return [OpenSSL::X509::Certificate] certificate (Excon only)
29
- #
30
- # @!attribute private_key
31
- # @return [OpenSSL::PKey::RSA, OpenSSL::PKey::DSA] private key (Excon only)
32
- #
33
- # @!attribute verify_depth
34
- # @return [Integer] maximum depth for the certificate chain verification
35
- #
36
- # @!attribute version
37
- # @return [String, Symbol] SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-ssl_version-3D)
38
- #
39
- # @!attribute min_version
40
- # @return [String, Symbol] minimum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-min_version-3D)
41
- #
42
- # @!attribute max_version
43
- # @return [String, Symbol] maximum SSL version (see https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html#method-i-max_version-3D)
44
- class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
45
- :cert_store, :client_cert, :client_key,
46
- :certificate, :private_key, :verify_depth,
47
- :version, :min_version, :max_version)
48
-
49
- # @return [Boolean] true if should verify
50
- def verify?
51
- verify != false
52
- end
53
-
54
- # @return [Boolean] true if should not verify
55
- def disable?
56
- !verify?
57
- end
58
- end
59
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # Multipart value used to POST data with a content type.
5
- class ParamPart
6
- # @param value [String] Uploaded content as a String.
7
- # @param content_type [String] String content type of the value.
8
- # @param content_id [String] Optional String of this value's Content-ID.
9
- #
10
- # @return [Faraday::ParamPart]
11
- def initialize(value, content_type, content_id = nil)
12
- @value = value
13
- @content_type = content_type
14
- @content_id = content_id
15
- end
16
-
17
- # Converts this value to a form part.
18
- #
19
- # @param boundary [String] String multipart boundary that must not exist in
20
- # the content exactly.
21
- # @param key [String] String key name for this value.
22
- #
23
- # @return [Faraday::Parts::Part]
24
- def to_part(boundary, key)
25
- Faraday::Parts::Part.new(boundary, key, value, headers)
26
- end
27
-
28
- # Returns a Hash of String key/value pairs.
29
- #
30
- # @return [Hash]
31
- def headers
32
- {
33
- 'Content-Type' => content_type,
34
- 'Content-ID' => content_id
35
- }
36
- end
37
-
38
- # The content to upload.
39
- #
40
- # @return [String]
41
- attr_reader :value
42
-
43
- # The value's content type.
44
- #
45
- # @return [String]
46
- attr_reader :content_type
47
-
48
- # The value's content ID, if given.
49
- #
50
- # @return [String, nil]
51
- attr_reader :content_id
52
- end
53
- end
@@ -1,139 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- module Utils
5
- # A case-insensitive Hash that preserves the original case of a header
6
- # when set.
7
- #
8
- # Adapted from Rack::Utils::HeaderHash
9
- class Headers < ::Hash
10
- def self.from(value)
11
- new(value)
12
- end
13
-
14
- def self.allocate
15
- new_self = super
16
- new_self.initialize_names
17
- new_self
18
- end
19
-
20
- def initialize(hash = nil)
21
- super()
22
- @names = {}
23
- update(hash || {})
24
- end
25
-
26
- def initialize_names
27
- @names = {}
28
- end
29
-
30
- # on dup/clone, we need to duplicate @names hash
31
- def initialize_copy(other)
32
- super
33
- @names = other.names.dup
34
- end
35
-
36
- # need to synchronize concurrent writes to the shared KeyMap
37
- keymap_mutex = Mutex.new
38
-
39
- # symbol -> string mapper + cache
40
- KeyMap = Hash.new do |map, key|
41
- value = if key.respond_to?(:to_str)
42
- key
43
- else
44
- key.to_s.split('_') # user_agent: %w(user agent)
45
- .each(&:capitalize!) # => %w(User Agent)
46
- .join('-') # => "User-Agent"
47
- end
48
- keymap_mutex.synchronize { map[key] = value }
49
- end
50
- KeyMap[:etag] = 'ETag'
51
-
52
- def [](key)
53
- key = KeyMap[key]
54
- super(key) || super(@names[key.downcase])
55
- end
56
-
57
- def []=(key, val)
58
- key = KeyMap[key]
59
- key = (@names[key.downcase] ||= key)
60
- # join multiple values with a comma
61
- val = val.to_ary.join(', ') if val.respond_to?(:to_ary)
62
- super(key, val)
63
- end
64
-
65
- def fetch(key, *args, &block)
66
- key = KeyMap[key]
67
- key = @names.fetch(key.downcase, key)
68
- super(key, *args, &block)
69
- end
70
-
71
- def delete(key)
72
- key = KeyMap[key]
73
- key = @names[key.downcase]
74
- return unless key
75
-
76
- @names.delete key.downcase
77
- super(key)
78
- end
79
-
80
- def include?(key)
81
- @names.include? key.downcase
82
- end
83
-
84
- alias has_key? include?
85
- alias member? include?
86
- alias key? include?
87
-
88
- def merge!(other)
89
- other.each { |k, v| self[k] = v }
90
- self
91
- end
92
-
93
- alias update merge!
94
-
95
- def merge(other)
96
- hash = dup
97
- hash.merge! other
98
- end
99
-
100
- def replace(other)
101
- clear
102
- @names.clear
103
- update other
104
- self
105
- end
106
-
107
- def to_hash
108
- ::Hash.new.update(self)
109
- end
110
-
111
- def parse(header_string)
112
- return unless header_string && !header_string.empty?
113
-
114
- headers = header_string.split(/\r\n/)
115
-
116
- # Find the last set of response headers.
117
- start_index = headers.rindex { |x| x.match(%r{^HTTP/}) } || 0
118
- last_response = headers.slice(start_index, headers.size)
119
-
120
- last_response
121
- .tap { |a| a.shift if a.first.start_with?('HTTP/') }
122
- .map { |h| h.split(/:\s*/, 2) } # split key and value
123
- .reject { |p| p[0].nil? } # ignore blank lines
124
- .each { |key, value| add_parsed(key, value) }
125
- end
126
-
127
- protected
128
-
129
- attr_reader :names
130
-
131
- private
132
-
133
- # Join multiple values with a comma.
134
- def add_parsed(key, value)
135
- self[key] ? self[key] << ', ' << value : self[key] = value
136
- end
137
- end
138
- end
139
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- module Utils
5
- # A hash with stringified keys.
6
- class ParamsHash < Hash
7
- def [](key)
8
- super(convert_key(key))
9
- end
10
-
11
- def []=(key, value)
12
- super(convert_key(key), value)
13
- end
14
-
15
- def delete(key)
16
- super(convert_key(key))
17
- end
18
-
19
- def include?(key)
20
- super(convert_key(key))
21
- end
22
-
23
- alias has_key? include?
24
- alias member? include?
25
- alias key? include?
26
-
27
- def update(params)
28
- params.each do |key, value|
29
- self[key] = value
30
- end
31
- self
32
- end
33
- alias merge! update
34
-
35
- def merge(params)
36
- dup.update(params)
37
- end
38
-
39
- def replace(other)
40
- clear
41
- update(other)
42
- end
43
-
44
- def merge_query(query, encoder = nil)
45
- return self unless query && !query.empty?
46
-
47
- update((encoder || Utils.default_params_encoder).decode(query))
48
- end
49
-
50
- def to_query(encoder = nil)
51
- (encoder || Utils.default_params_encoder).encode(self)
52
- end
53
-
54
- private
55
-
56
- def convert_key(key)
57
- key.to_s
58
- end
59
- end
60
- end
61
- end