faraday 0.16.0 → 0.17.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +232 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +358 -18
  5. data/Rakefile +13 -0
  6. data/lib/faraday/adapter/em_http.rb +97 -140
  7. data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
  8. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
  9. data/lib/faraday/adapter/em_synchrony.rb +60 -104
  10. data/lib/faraday/adapter/excon.rb +55 -100
  11. data/lib/faraday/adapter/httpclient.rb +39 -61
  12. data/lib/faraday/adapter/net_http.rb +51 -103
  13. data/lib/faraday/adapter/net_http_persistent.rb +28 -49
  14. data/lib/faraday/adapter/patron.rb +35 -54
  15. data/lib/faraday/adapter/rack.rb +12 -28
  16. data/lib/faraday/adapter/test.rb +53 -86
  17. data/lib/faraday/adapter/typhoeus.rb +1 -4
  18. data/lib/faraday/adapter.rb +22 -36
  19. data/lib/faraday/autoload.rb +36 -47
  20. data/lib/faraday/connection.rb +179 -321
  21. data/lib/faraday/deprecate.rb +109 -0
  22. data/lib/faraday/error.rb +79 -21
  23. data/lib/faraday/middleware.rb +28 -4
  24. data/lib/faraday/options.rb +183 -32
  25. data/lib/faraday/parameters.rb +197 -4
  26. data/lib/faraday/rack_builder.rb +55 -66
  27. data/lib/faraday/request/authorization.rb +30 -42
  28. data/lib/faraday/request/basic_authentication.rb +7 -14
  29. data/lib/faraday/request/instrumentation.rb +27 -45
  30. data/lib/faraday/request/multipart.rb +48 -79
  31. data/lib/faraday/request/retry.rb +171 -197
  32. data/lib/faraday/request/token_authentication.rb +10 -15
  33. data/lib/faraday/request/url_encoded.rb +23 -41
  34. data/lib/faraday/request.rb +36 -68
  35. data/lib/faraday/response/logger.rb +69 -22
  36. data/lib/faraday/response/raise_error.rb +18 -36
  37. data/lib/faraday/response.rb +13 -20
  38. data/lib/faraday/upload_io.rb +67 -0
  39. data/lib/faraday/utils.rb +245 -28
  40. data/lib/faraday.rb +174 -93
  41. data/spec/faraday/deprecate_spec.rb +147 -0
  42. data/spec/faraday/error_spec.rb +102 -0
  43. data/spec/faraday/response/raise_error_spec.rb +106 -0
  44. data/spec/spec_helper.rb +105 -0
  45. data/test/adapters/default_test.rb +14 -0
  46. data/test/adapters/em_http_test.rb +30 -0
  47. data/test/adapters/em_synchrony_test.rb +32 -0
  48. data/test/adapters/excon_test.rb +30 -0
  49. data/test/adapters/httpclient_test.rb +34 -0
  50. data/test/adapters/integration.rb +263 -0
  51. data/test/adapters/logger_test.rb +136 -0
  52. data/test/adapters/net_http_persistent_test.rb +114 -0
  53. data/test/adapters/net_http_test.rb +79 -0
  54. data/test/adapters/patron_test.rb +40 -0
  55. data/test/adapters/rack_test.rb +38 -0
  56. data/test/adapters/test_middleware_test.rb +157 -0
  57. data/test/adapters/typhoeus_test.rb +38 -0
  58. data/test/authentication_middleware_test.rb +65 -0
  59. data/test/composite_read_io_test.rb +109 -0
  60. data/test/connection_test.rb +738 -0
  61. data/test/env_test.rb +268 -0
  62. data/test/helper.rb +75 -0
  63. data/test/live_server.rb +67 -0
  64. data/test/middleware/instrumentation_test.rb +88 -0
  65. data/test/middleware/retry_test.rb +282 -0
  66. data/test/middleware_stack_test.rb +260 -0
  67. data/test/multibyte.txt +1 -0
  68. data/test/options_test.rb +333 -0
  69. data/test/parameters_test.rb +157 -0
  70. data/test/request_middleware_test.rb +126 -0
  71. data/test/response_middleware_test.rb +72 -0
  72. data/test/strawberry.rb +2 -0
  73. data/test/utils_test.rb +98 -0
  74. metadata +50 -25
  75. data/lib/faraday/adapter_registry.rb +0 -28
  76. data/lib/faraday/dependency_loader.rb +0 -37
  77. data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
  78. data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
  79. data/lib/faraday/file_part.rb +0 -128
  80. data/lib/faraday/logging/formatter.rb +0 -92
  81. data/lib/faraday/middleware_registry.rb +0 -129
  82. data/lib/faraday/options/connection_options.rb +0 -22
  83. data/lib/faraday/options/env.rb +0 -181
  84. data/lib/faraday/options/proxy_options.rb +0 -28
  85. data/lib/faraday/options/request_options.rb +0 -21
  86. data/lib/faraday/options/ssl_options.rb +0 -59
  87. data/lib/faraday/param_part.rb +0 -53
  88. data/lib/faraday/utils/headers.rb +0 -139
  89. data/lib/faraday/utils/params_hash.rb +0 -61
  90. data/spec/external_adapters/faraday_specs_setup.rb +0 -14
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'pp'
4
- module Faraday
5
- module Logging
6
- # Serves as an integration point to customize logging
7
- class Formatter
8
- extend Forwardable
9
-
10
- DEFAULT_OPTIONS = { headers: true, bodies: false }.freeze
11
-
12
- def initialize(logger:, options:)
13
- @logger = logger
14
- @filter = []
15
- @options = DEFAULT_OPTIONS.merge(options)
16
- end
17
-
18
- def_delegators :@logger, :debug, :info, :warn, :error, :fatal
19
-
20
- def request(env)
21
- info('request') do
22
- "#{env.method.upcase} #{apply_filters(env.url.to_s)}"
23
- end
24
- if log_headers?(:request)
25
- debug('request') { apply_filters(dump_headers(env.request_headers)) }
26
- end
27
- return unless env[:body] && log_body?(:request)
28
-
29
- debug('request') { apply_filters(dump_body(env[:body])) }
30
- end
31
-
32
- def response(env)
33
- info('response') { "Status #{env.status}" }
34
- if log_headers?(:response)
35
- debug('response') do
36
- apply_filters(dump_headers(env.response_headers))
37
- end
38
- end
39
- return unless env[:body] && log_body?(:response)
40
-
41
- debug('response') { apply_filters(dump_body(env[:body])) }
42
- end
43
-
44
- def filter(filter_word, filter_replacement)
45
- @filter.push([filter_word, filter_replacement])
46
- end
47
-
48
- private
49
-
50
- def dump_headers(headers)
51
- headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
52
- end
53
-
54
- def dump_body(body)
55
- if body.respond_to?(:to_str)
56
- body.to_str
57
- else
58
- pretty_inspect(body)
59
- end
60
- end
61
-
62
- def pretty_inspect(body)
63
- body.pretty_inspect
64
- end
65
-
66
- def log_headers?(type)
67
- case @options[:headers]
68
- when Hash
69
- @options[:headers][type]
70
- else
71
- @options[:headers]
72
- end
73
- end
74
-
75
- def log_body?(type)
76
- case @options[:bodies]
77
- when Hash
78
- @options[:bodies][type]
79
- else
80
- @options[:bodies]
81
- end
82
- end
83
-
84
- def apply_filters(output)
85
- @filter.each do |pattern, replacement|
86
- output = output.to_s.gsub(pattern, replacement)
87
- end
88
- output
89
- end
90
- end
91
- end
92
- end
@@ -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