faraday 1.0.0 → 2.9.0
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 +4 -4
- data/CHANGELOG.md +299 -1
- data/LICENSE.md +1 -1
- data/README.md +35 -23
- data/Rakefile +3 -1
- data/examples/client_spec.rb +68 -14
- data/examples/client_test.rb +80 -15
- data/lib/faraday/adapter/test.rb +117 -52
- data/lib/faraday/adapter.rb +6 -20
- data/lib/faraday/adapter_registry.rb +3 -1
- data/lib/faraday/connection.rb +73 -132
- data/lib/faraday/encoders/flat_params_encoder.rb +9 -2
- data/lib/faraday/encoders/nested_params_encoder.rb +20 -8
- data/lib/faraday/error.rb +37 -8
- data/lib/faraday/logging/formatter.rb +28 -15
- data/lib/faraday/methods.rb +6 -0
- data/lib/faraday/middleware.rb +17 -5
- data/lib/faraday/middleware_registry.rb +17 -63
- data/lib/faraday/options/connection_options.rb +7 -6
- data/lib/faraday/options/env.rb +85 -62
- data/lib/faraday/options/proxy_options.rb +11 -3
- data/lib/faraday/options/request_options.rb +7 -6
- data/lib/faraday/options/ssl_options.rb +56 -45
- data/lib/faraday/options.rb +11 -14
- data/lib/faraday/rack_builder.rb +35 -32
- data/lib/faraday/request/authorization.rb +37 -36
- data/lib/faraday/request/instrumentation.rb +5 -1
- data/lib/faraday/request/json.rb +70 -0
- data/lib/faraday/request/url_encoded.rb +8 -2
- data/lib/faraday/request.rb +22 -29
- data/lib/faraday/response/json.rb +73 -0
- data/lib/faraday/response/logger.rb +8 -4
- data/lib/faraday/response/raise_error.rb +41 -3
- data/lib/faraday/response.rb +10 -23
- data/lib/faraday/utils/headers.rb +9 -4
- data/lib/faraday/utils.rb +22 -10
- data/lib/faraday/version.rb +5 -0
- data/lib/faraday.rb +49 -58
- data/spec/faraday/adapter/test_spec.rb +442 -0
- data/spec/faraday/connection_spec.rb +207 -90
- data/spec/faraday/error_spec.rb +45 -5
- data/spec/faraday/middleware_registry_spec.rb +31 -0
- data/spec/faraday/middleware_spec.rb +50 -6
- data/spec/faraday/options/env_spec.rb +8 -2
- data/spec/faraday/options/options_spec.rb +1 -1
- data/spec/faraday/options/proxy_options_spec.rb +15 -0
- data/spec/faraday/params_encoders/flat_spec.rb +8 -0
- data/spec/faraday/params_encoders/nested_spec.rb +16 -0
- data/spec/faraday/rack_builder_spec.rb +171 -50
- data/spec/faraday/request/authorization_spec.rb +54 -24
- data/spec/faraday/request/instrumentation_spec.rb +5 -7
- data/spec/faraday/request/json_spec.rb +199 -0
- data/spec/faraday/request/url_encoded_spec.rb +25 -2
- data/spec/faraday/request_spec.rb +11 -10
- data/spec/faraday/response/json_spec.rb +189 -0
- data/spec/faraday/response/logger_spec.rb +38 -0
- data/spec/faraday/response/raise_error_spec.rb +105 -0
- data/spec/faraday/response_spec.rb +3 -1
- data/spec/faraday/utils/headers_spec.rb +22 -4
- data/spec/faraday/utils_spec.rb +63 -1
- data/spec/faraday_spec.rb +8 -4
- data/spec/spec_helper.rb +6 -5
- data/spec/support/fake_safe_buffer.rb +1 -1
- data/spec/support/helper_methods.rb +0 -37
- data/spec/support/shared_examples/adapter.rb +4 -3
- data/spec/support/shared_examples/request_method.rb +60 -31
- metadata +19 -44
- data/UPGRADING.md +0 -55
- data/lib/faraday/adapter/em_http.rb +0 -285
- data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -62
- data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -69
- data/lib/faraday/adapter/em_synchrony.rb +0 -150
- data/lib/faraday/adapter/excon.rb +0 -124
- data/lib/faraday/adapter/httpclient.rb +0 -151
- data/lib/faraday/adapter/net_http.rb +0 -209
- data/lib/faraday/adapter/net_http_persistent.rb +0 -91
- data/lib/faraday/adapter/patron.rb +0 -132
- data/lib/faraday/adapter/rack.rb +0 -75
- data/lib/faraday/adapter/typhoeus.rb +0 -15
- data/lib/faraday/autoload.rb +0 -95
- data/lib/faraday/dependency_loader.rb +0 -37
- data/lib/faraday/file_part.rb +0 -128
- data/lib/faraday/param_part.rb +0 -53
- data/lib/faraday/request/basic_authentication.rb +0 -20
- data/lib/faraday/request/multipart.rb +0 -99
- data/lib/faraday/request/retry.rb +0 -239
- data/lib/faraday/request/token_authentication.rb +0 -20
- data/spec/faraday/adapter/em_http_spec.rb +0 -47
- data/spec/faraday/adapter/em_synchrony_spec.rb +0 -16
- data/spec/faraday/adapter/excon_spec.rb +0 -49
- data/spec/faraday/adapter/httpclient_spec.rb +0 -73
- data/spec/faraday/adapter/net_http_persistent_spec.rb +0 -57
- data/spec/faraday/adapter/net_http_spec.rb +0 -64
- data/spec/faraday/adapter/patron_spec.rb +0 -18
- data/spec/faraday/adapter/rack_spec.rb +0 -8
- data/spec/faraday/adapter/typhoeus_spec.rb +0 -7
- data/spec/faraday/composite_read_io_spec.rb +0 -80
- data/spec/faraday/request/multipart_spec.rb +0 -274
- data/spec/faraday/request/retry_spec.rb +0 -242
- data/spec/faraday/response/middleware_spec.rb +0 -52
- data/spec/support/webmock_rack_app.rb +0 -68
@@ -6,8 +6,8 @@ module Faraday
|
|
6
6
|
# client or server error responses.
|
7
7
|
class RaiseError < Middleware
|
8
8
|
# rubocop:disable Naming/ConstantName
|
9
|
-
ClientErrorStatuses = (400...500)
|
10
|
-
ServerErrorStatuses = (500...600)
|
9
|
+
ClientErrorStatuses = (400...500)
|
10
|
+
ServerErrorStatuses = (500...600)
|
11
11
|
# rubocop:enable Naming/ConstantName
|
12
12
|
|
13
13
|
def on_complete(env)
|
@@ -24,10 +24,14 @@ module Faraday
|
|
24
24
|
# mimic the behavior that we get with proxy requests with HTTPS
|
25
25
|
msg = %(407 "Proxy Authentication Required")
|
26
26
|
raise Faraday::ProxyAuthError.new(msg, response_values(env))
|
27
|
+
when 408
|
28
|
+
raise Faraday::RequestTimeoutError, response_values(env)
|
27
29
|
when 409
|
28
30
|
raise Faraday::ConflictError, response_values(env)
|
29
31
|
when 422
|
30
32
|
raise Faraday::UnprocessableEntityError, response_values(env)
|
33
|
+
when 429
|
34
|
+
raise Faraday::TooManyRequestsError, response_values(env)
|
31
35
|
when ClientErrorStatuses
|
32
36
|
raise Faraday::ClientError, response_values(env)
|
33
37
|
when ServerErrorStatuses
|
@@ -37,9 +41,43 @@ module Faraday
|
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
44
|
+
# Returns a hash of response data with the following keys:
|
45
|
+
# - status
|
46
|
+
# - headers
|
47
|
+
# - body
|
48
|
+
# - request
|
49
|
+
#
|
50
|
+
# The `request` key is omitted when the middleware is explicitly
|
51
|
+
# configured with the option `include_request: false`.
|
40
52
|
def response_values(env)
|
41
|
-
|
53
|
+
response = {
|
54
|
+
status: env.status,
|
55
|
+
headers: env.response_headers,
|
56
|
+
body: env.body
|
57
|
+
}
|
58
|
+
|
59
|
+
# Include the request data by default. If the middleware was explicitly
|
60
|
+
# configured to _not_ include request data, then omit it.
|
61
|
+
return response unless options.fetch(:include_request, true)
|
62
|
+
|
63
|
+
response.merge(
|
64
|
+
request: {
|
65
|
+
method: env.method,
|
66
|
+
url: env.url,
|
67
|
+
url_path: env.url.path,
|
68
|
+
params: query_params(env),
|
69
|
+
headers: env.request_headers,
|
70
|
+
body: env.request_body
|
71
|
+
}
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def query_params(env)
|
76
|
+
env.request.params_encoder ||= Faraday::Utils.default_params_encoder
|
77
|
+
env.params_encoder.decode(env.url.query)
|
42
78
|
end
|
43
79
|
end
|
44
80
|
end
|
45
81
|
end
|
82
|
+
|
83
|
+
Faraday::Response.register_middleware(raise_error: Faraday::Response::RaiseError)
|
data/lib/faraday/response.rb
CHANGED
@@ -5,28 +5,9 @@ require 'forwardable'
|
|
5
5
|
module Faraday
|
6
6
|
# Response represents an HTTP response from making an HTTP request.
|
7
7
|
class Response
|
8
|
-
# Used for simple response middleware.
|
9
|
-
class Middleware < Faraday::Middleware
|
10
|
-
def call(env)
|
11
|
-
@app.call(env).on_complete do |environment|
|
12
|
-
on_complete(environment)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# Override this to modify the environment after the response has finished.
|
17
|
-
# Calls the `parse` method if defined
|
18
|
-
def on_complete(env)
|
19
|
-
env.body = parse(env.body) if respond_to?(:parse) && env.parse_body?
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
8
|
extend Forwardable
|
24
9
|
extend MiddlewareRegistry
|
25
10
|
|
26
|
-
register_middleware File.expand_path('response', __dir__),
|
27
|
-
raise_error: [:RaiseError, 'raise_error'],
|
28
|
-
logger: [:Logger, 'logger']
|
29
|
-
|
30
11
|
def initialize(env = nil)
|
31
12
|
@env = Env.from(env) if env
|
32
13
|
@on_complete_callbacks = []
|
@@ -45,6 +26,7 @@ module Faraday
|
|
45
26
|
def headers
|
46
27
|
finished? ? env.response_headers : {}
|
47
28
|
end
|
29
|
+
|
48
30
|
def_delegator :headers, :[]
|
49
31
|
|
50
32
|
def body
|
@@ -56,10 +38,10 @@ module Faraday
|
|
56
38
|
end
|
57
39
|
|
58
40
|
def on_complete(&block)
|
59
|
-
if
|
60
|
-
@on_complete_callbacks << block
|
61
|
-
else
|
41
|
+
if finished?
|
62
42
|
yield(env)
|
43
|
+
else
|
44
|
+
@on_complete_callbacks << block
|
63
45
|
end
|
64
46
|
self
|
65
47
|
end
|
@@ -79,7 +61,8 @@ module Faraday
|
|
79
61
|
def to_hash
|
80
62
|
{
|
81
63
|
status: env.status, body: env.body,
|
82
|
-
response_headers: env.response_headers
|
64
|
+
response_headers: env.response_headers,
|
65
|
+
url: env.url
|
83
66
|
}
|
84
67
|
end
|
85
68
|
|
@@ -102,3 +85,7 @@ module Faraday
|
|
102
85
|
end
|
103
86
|
end
|
104
87
|
end
|
88
|
+
|
89
|
+
require 'faraday/response/json'
|
90
|
+
require 'faraday/response/logger'
|
91
|
+
require 'faraday/response/raise_error'
|
@@ -105,16 +105,16 @@ module Faraday
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def to_hash
|
108
|
-
|
108
|
+
{}.update(self)
|
109
109
|
end
|
110
110
|
|
111
111
|
def parse(header_string)
|
112
112
|
return unless header_string && !header_string.empty?
|
113
113
|
|
114
|
-
headers = header_string.split(
|
114
|
+
headers = header_string.split("\r\n")
|
115
115
|
|
116
116
|
# Find the last set of response headers.
|
117
|
-
start_index = headers.rindex { |x| x.
|
117
|
+
start_index = headers.rindex { |x| x.start_with?('HTTP/') } || 0
|
118
118
|
last_response = headers.slice(start_index, headers.size)
|
119
119
|
|
120
120
|
last_response
|
@@ -132,7 +132,12 @@ module Faraday
|
|
132
132
|
|
133
133
|
# Join multiple values with a comma.
|
134
134
|
def add_parsed(key, value)
|
135
|
-
|
135
|
+
if key?(key)
|
136
|
+
self[key] = self[key].to_s
|
137
|
+
self[key] << ', ' << value
|
138
|
+
else
|
139
|
+
self[key] = value
|
140
|
+
end
|
136
141
|
end
|
137
142
|
end
|
138
143
|
end
|
data/lib/faraday/utils.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'uri'
|
3
4
|
require 'faraday/utils/headers'
|
4
5
|
require 'faraday/utils/params_hash'
|
5
6
|
|
@@ -16,19 +17,27 @@ module Faraday
|
|
16
17
|
NestedParamsEncoder.encode(params)
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
+
def default_space_encoding
|
21
|
+
@default_space_encoding ||= '+'
|
22
|
+
end
|
23
|
+
|
24
|
+
class << self
|
25
|
+
attr_writer :default_space_encoding
|
26
|
+
end
|
27
|
+
|
28
|
+
ESCAPE_RE = /[^a-zA-Z0-9 .~_-]/
|
20
29
|
|
21
30
|
def escape(str)
|
22
31
|
str.to_s.gsub(ESCAPE_RE) do |match|
|
23
|
-
|
24
|
-
end.
|
32
|
+
"%#{match.unpack('H2' * match.bytesize).join('%').upcase}"
|
33
|
+
end.gsub(' ', default_space_encoding)
|
25
34
|
end
|
26
35
|
|
27
36
|
def unescape(str)
|
28
37
|
CGI.unescape str.to_s
|
29
38
|
end
|
30
39
|
|
31
|
-
DEFAULT_SEP = /[&;] */n
|
40
|
+
DEFAULT_SEP = /[&;] */n
|
32
41
|
|
33
42
|
# Adapted from Rack
|
34
43
|
def parse_query(query)
|
@@ -43,6 +52,12 @@ module Faraday
|
|
43
52
|
@default_params_encoder ||= NestedParamsEncoder
|
44
53
|
end
|
45
54
|
|
55
|
+
def basic_header_from(login, pass)
|
56
|
+
value = ["#{login}:#{pass}"].pack('m') # Base64 encoding
|
57
|
+
value.delete!("\n")
|
58
|
+
"Basic #{value}"
|
59
|
+
end
|
60
|
+
|
46
61
|
class << self
|
47
62
|
attr_writer :default_params_encoder
|
48
63
|
end
|
@@ -63,10 +78,7 @@ module Faraday
|
|
63
78
|
end
|
64
79
|
|
65
80
|
def default_uri_parser
|
66
|
-
@default_uri_parser ||=
|
67
|
-
require 'uri'
|
68
|
-
Kernel.method(:URI)
|
69
|
-
end
|
81
|
+
@default_uri_parser ||= Kernel.method(:URI)
|
70
82
|
end
|
71
83
|
|
72
84
|
def default_uri_parser=(parser)
|
@@ -81,14 +93,14 @@ module Faraday
|
|
81
93
|
# the path with the query string sorted.
|
82
94
|
def normalize_path(url)
|
83
95
|
url = URI(url)
|
84
|
-
(url.path.start_with?('/') ? url.path :
|
96
|
+
(url.path.start_with?('/') ? url.path : "/#{url.path}") +
|
85
97
|
(url.query ? "?#{sort_query_params(url.query)}" : '')
|
86
98
|
end
|
87
99
|
|
88
100
|
# Recursive hash update
|
89
101
|
def deep_merge!(target, hash)
|
90
102
|
hash.each do |key, value|
|
91
|
-
target[key] = if value.is_a?(Hash) && target[key].is_a?(Hash)
|
103
|
+
target[key] = if value.is_a?(Hash) && (target[key].is_a?(Hash) || target[key].is_a?(Options))
|
92
104
|
deep_merge(target[key], value)
|
93
105
|
else
|
94
106
|
value
|
data/lib/faraday.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'cgi'
|
4
|
+
require 'date'
|
4
5
|
require 'set'
|
5
6
|
require 'forwardable'
|
7
|
+
require 'faraday/version'
|
8
|
+
require 'faraday/methods'
|
9
|
+
require 'faraday/error'
|
6
10
|
require 'faraday/middleware_registry'
|
7
|
-
require 'faraday/
|
8
|
-
|
11
|
+
require 'faraday/utils'
|
12
|
+
require 'faraday/options'
|
13
|
+
require 'faraday/connection'
|
14
|
+
require 'faraday/rack_builder'
|
15
|
+
require 'faraday/parameters'
|
16
|
+
require 'faraday/middleware'
|
17
|
+
require 'faraday/adapter'
|
18
|
+
require 'faraday/request'
|
19
|
+
require 'faraday/response'
|
20
|
+
require 'faraday/net_http'
|
9
21
|
# This is the main namespace for Faraday.
|
10
22
|
#
|
11
23
|
# It provides methods to create {Connection} objects, and HTTP-related
|
@@ -19,9 +31,7 @@ require 'faraday/dependency_loader'
|
|
19
31
|
# conn.get '/'
|
20
32
|
#
|
21
33
|
module Faraday
|
22
|
-
|
23
|
-
METHODS_WITH_QUERY = %w[get head delete trace].freeze
|
24
|
-
METHODS_WITH_BODY = %w[post put patch].freeze
|
34
|
+
CONTENT_TYPE = 'Content-Type'
|
25
35
|
|
26
36
|
class << self
|
27
37
|
# The root path that Faraday is being loaded from.
|
@@ -44,6 +54,10 @@ module Faraday
|
|
44
54
|
# @return [Symbol] the new default_adapter.
|
45
55
|
attr_reader :default_adapter
|
46
56
|
|
57
|
+
# Option for the default_adapter
|
58
|
+
# @return [Hash] default_adapter options
|
59
|
+
attr_accessor :default_adapter_options
|
60
|
+
|
47
61
|
# Documented below, see default_connection
|
48
62
|
attr_writer :default_connection
|
49
63
|
|
@@ -80,23 +94,10 @@ module Faraday
|
|
80
94
|
# params: { page: 1 }
|
81
95
|
# # => Faraday::Connection to http://faraday.com?page=1
|
82
96
|
def new(url = nil, options = {}, &block)
|
83
|
-
options =
|
97
|
+
options = Utils.deep_merge(default_connection_options, options)
|
84
98
|
Faraday::Connection.new(url, options, &block)
|
85
99
|
end
|
86
100
|
|
87
|
-
# @private
|
88
|
-
# Internal: Requires internal Faraday libraries.
|
89
|
-
#
|
90
|
-
# @param libs [Array] one or more relative String names to Faraday classes.
|
91
|
-
# @return [void]
|
92
|
-
def require_libs(*libs)
|
93
|
-
libs.each do |lib|
|
94
|
-
require "#{lib_path}/#{lib}"
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
alias require_lib require_libs
|
99
|
-
|
100
101
|
# Documented elsewhere, see default_adapter reader
|
101
102
|
def default_adapter=(adapter)
|
102
103
|
@default_connection = nil
|
@@ -107,6 +108,34 @@ module Faraday
|
|
107
108
|
default_connection.respond_to?(symbol, include_private) || super
|
108
109
|
end
|
109
110
|
|
111
|
+
# @overload default_connection
|
112
|
+
# Gets the default connection used for simple scripts.
|
113
|
+
# @return [Faraday::Connection] a connection configured with
|
114
|
+
# the default_adapter.
|
115
|
+
# @overload default_connection=(connection)
|
116
|
+
# @param connection [Faraday::Connection]
|
117
|
+
# Sets the default {Faraday::Connection} for simple scripts that
|
118
|
+
# access the Faraday constant directly, such as
|
119
|
+
# <code>Faraday.get "https://faraday.com"</code>.
|
120
|
+
def default_connection
|
121
|
+
@default_connection ||= Connection.new(default_connection_options)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Gets the default connection options used when calling {Faraday#new}.
|
125
|
+
#
|
126
|
+
# @return [Faraday::ConnectionOptions]
|
127
|
+
def default_connection_options
|
128
|
+
@default_connection_options ||= ConnectionOptions.new
|
129
|
+
end
|
130
|
+
|
131
|
+
# Sets the default options used when calling {Faraday#new}.
|
132
|
+
#
|
133
|
+
# @param options [Hash, Faraday::ConnectionOptions]
|
134
|
+
def default_connection_options=(options)
|
135
|
+
@default_connection = nil
|
136
|
+
@default_connection_options = ConnectionOptions.from(options)
|
137
|
+
end
|
138
|
+
|
110
139
|
private
|
111
140
|
|
112
141
|
# Internal: Proxies method calls on the Faraday constant to
|
@@ -124,43 +153,5 @@ module Faraday
|
|
124
153
|
self.root_path = File.expand_path __dir__
|
125
154
|
self.lib_path = File.expand_path 'faraday', __dir__
|
126
155
|
self.default_adapter = :net_http
|
127
|
-
|
128
|
-
# @overload default_connection
|
129
|
-
# Gets the default connection used for simple scripts.
|
130
|
-
# @return [Faraday::Connection] a connection configured with
|
131
|
-
# the default_adapter.
|
132
|
-
# @overload default_connection=(connection)
|
133
|
-
# @param connection [Faraday::Connection]
|
134
|
-
# Sets the default {Faraday::Connection} for simple scripts that
|
135
|
-
# access the Faraday constant directly, such as
|
136
|
-
# <code>Faraday.get "https://faraday.com"</code>.
|
137
|
-
def self.default_connection
|
138
|
-
@default_connection ||= Connection.new(default_connection_options)
|
139
|
-
end
|
140
|
-
|
141
|
-
# Gets the default connection options used when calling {Faraday#new}.
|
142
|
-
#
|
143
|
-
# @return [Faraday::ConnectionOptions]
|
144
|
-
def self.default_connection_options
|
145
|
-
@default_connection_options ||= ConnectionOptions.new
|
146
|
-
end
|
147
|
-
|
148
|
-
# Sets the default options used when calling {Faraday#new}.
|
149
|
-
#
|
150
|
-
# @param options [Hash, Faraday::ConnectionOptions]
|
151
|
-
def self.default_connection_options=(options)
|
152
|
-
@default_connection = nil
|
153
|
-
@default_connection_options = ConnectionOptions.from(options)
|
154
|
-
end
|
155
|
-
|
156
|
-
unless const_defined? :Timer
|
157
|
-
require 'timeout'
|
158
|
-
Timer = Timeout
|
159
|
-
end
|
160
|
-
|
161
|
-
require_libs 'utils', 'options', 'connection', 'rack_builder', 'parameters',
|
162
|
-
'middleware', 'adapter', 'request', 'response', 'error',
|
163
|
-
'file_part', 'param_part'
|
164
|
-
|
165
|
-
require_lib 'autoload' unless ENV['FARADAY_NO_AUTOLOAD']
|
156
|
+
self.default_adapter_options = {}
|
166
157
|
end
|