faraday 0.9.1 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.md +1 -1
  3. data/README.md +30 -195
  4. data/lib/faraday/adapter/em_http.rb +148 -99
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  6. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  7. data/lib/faraday/adapter/em_synchrony.rb +107 -49
  8. data/lib/faraday/adapter/excon.rb +102 -55
  9. data/lib/faraday/adapter/httpclient.rb +80 -36
  10. data/lib/faraday/adapter/net_http.rb +119 -44
  11. data/lib/faraday/adapter/net_http_persistent.rb +68 -27
  12. data/lib/faraday/adapter/patron.rb +76 -34
  13. data/lib/faraday/adapter/rack.rb +28 -12
  14. data/lib/faraday/adapter/test.rb +136 -52
  15. data/lib/faraday/adapter/typhoeus.rb +7 -115
  16. data/lib/faraday/adapter.rb +43 -20
  17. data/lib/faraday/adapter_registry.rb +28 -0
  18. data/lib/faraday/autoload.rb +47 -36
  19. data/lib/faraday/connection.rb +359 -165
  20. data/lib/faraday/dependency_loader.rb +37 -0
  21. data/lib/faraday/encoders/flat_params_encoder.rb +94 -0
  22. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  23. data/lib/faraday/error.rb +71 -24
  24. data/lib/faraday/file_part.rb +128 -0
  25. data/lib/faraday/logging/formatter.rb +92 -0
  26. data/lib/faraday/middleware.rb +4 -28
  27. data/lib/faraday/middleware_registry.rb +129 -0
  28. data/lib/faraday/options/connection_options.rb +22 -0
  29. data/lib/faraday/options/env.rb +181 -0
  30. data/lib/faraday/options/proxy_options.rb +28 -0
  31. data/lib/faraday/options/request_options.rb +21 -0
  32. data/lib/faraday/options/ssl_options.rb +59 -0
  33. data/lib/faraday/options.rb +57 -185
  34. data/lib/faraday/param_part.rb +53 -0
  35. data/lib/faraday/parameters.rb +4 -180
  36. data/lib/faraday/rack_builder.rb +74 -38
  37. data/lib/faraday/request/authorization.rb +42 -31
  38. data/lib/faraday/request/basic_authentication.rb +14 -7
  39. data/lib/faraday/request/instrumentation.rb +45 -27
  40. data/lib/faraday/request/multipart.rb +81 -45
  41. data/lib/faraday/request/retry.rb +212 -121
  42. data/lib/faraday/request/token_authentication.rb +15 -10
  43. data/lib/faraday/request/url_encoded.rb +41 -23
  44. data/lib/faraday/request.rb +84 -30
  45. data/lib/faraday/response/logger.rb +22 -48
  46. data/lib/faraday/response/raise_error.rb +36 -14
  47. data/lib/faraday/response.rb +29 -18
  48. data/lib/faraday/utils/headers.rb +139 -0
  49. data/lib/faraday/utils/params_hash.rb +61 -0
  50. data/lib/faraday/utils.rb +28 -216
  51. data/lib/faraday.rb +102 -204
  52. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  53. metadata +24 -94
  54. data/.document +0 -6
  55. data/CHANGELOG.md +0 -20
  56. data/CONTRIBUTING.md +0 -36
  57. data/Gemfile +0 -25
  58. data/Rakefile +0 -71
  59. data/faraday.gemspec +0 -34
  60. data/lib/faraday/upload_io.rb +0 -67
  61. data/script/cached-bundle +0 -46
  62. data/script/console +0 -7
  63. data/script/generate_certs +0 -42
  64. data/script/package +0 -7
  65. data/script/proxy-server +0 -42
  66. data/script/release +0 -17
  67. data/script/s3-put +0 -71
  68. data/script/server +0 -36
  69. data/script/test +0 -172
  70. data/test/adapters/default_test.rb +0 -14
  71. data/test/adapters/em_http_test.rb +0 -20
  72. data/test/adapters/em_synchrony_test.rb +0 -20
  73. data/test/adapters/excon_test.rb +0 -20
  74. data/test/adapters/httpclient_test.rb +0 -21
  75. data/test/adapters/integration.rb +0 -254
  76. data/test/adapters/logger_test.rb +0 -82
  77. data/test/adapters/net_http_persistent_test.rb +0 -20
  78. data/test/adapters/net_http_test.rb +0 -14
  79. data/test/adapters/patron_test.rb +0 -20
  80. data/test/adapters/rack_test.rb +0 -31
  81. data/test/adapters/test_middleware_test.rb +0 -114
  82. data/test/adapters/typhoeus_test.rb +0 -28
  83. data/test/authentication_middleware_test.rb +0 -65
  84. data/test/composite_read_io_test.rb +0 -111
  85. data/test/connection_test.rb +0 -522
  86. data/test/env_test.rb +0 -218
  87. data/test/helper.rb +0 -81
  88. data/test/live_server.rb +0 -67
  89. data/test/middleware/instrumentation_test.rb +0 -88
  90. data/test/middleware/retry_test.rb +0 -177
  91. data/test/middleware_stack_test.rb +0 -173
  92. data/test/multibyte.txt +0 -1
  93. data/test/options_test.rb +0 -252
  94. data/test/parameters_test.rb +0 -64
  95. data/test/request_middleware_test.rb +0 -142
  96. data/test/response_middleware_test.rb +0 -72
  97. data/test/strawberry.rb +0 -2
  98. data/test/utils_test.rb +0 -58
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
5
  # Sends requests to a Rack app.
4
6
  #
5
- # Examples
7
+ # @example
6
8
  #
7
9
  # class MyRackApp
8
10
  # def call(env)
@@ -17,7 +19,7 @@ module Faraday
17
19
  dependency 'rack/test'
18
20
 
19
21
  # not prefixed with "HTTP_"
20
- SPECIAL_HEADERS = %w[ CONTENT_LENGTH CONTENT_TYPE ]
22
+ SPECIAL_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
21
23
 
22
24
  def initialize(faraday_app, rack_app)
23
25
  super(faraday_app)
@@ -27,32 +29,46 @@ module Faraday
27
29
 
28
30
  def call(env)
29
31
  super
30
- rack_env = {
31
- :method => env[:method],
32
- :input => env[:body].respond_to?(:read) ? env[:body].read : env[:body],
33
- 'rack.url_scheme' => env[:url].scheme
34
- }
32
+ rack_env = build_rack_env(env)
35
33
 
36
- env[:request_headers].each do |name, value|
34
+ env[:request_headers]&.each do |name, value|
37
35
  name = name.upcase.tr('-', '_')
38
36
  name = "HTTP_#{name}" unless SPECIAL_HEADERS.include? name
39
37
  rack_env[name] = value
40
- end if env[:request_headers]
38
+ end
41
39
 
42
40
  timeout = env[:request][:timeout] || env[:request][:open_timeout]
43
41
  response = if timeout
44
- Timer.timeout(timeout, Faraday::Error::TimeoutError) { execute_request(env, rack_env) }
45
- else
46
- execute_request(env, rack_env)
42
+ Timer.timeout(timeout, Faraday::TimeoutError) do
43
+ execute_request(env, rack_env)
44
+ end
45
+ else
46
+ execute_request(env, rack_env)
47
+ end
48
+
49
+ if (req = env[:request]).stream_response?
50
+ warn "Streaming downloads for #{self.class.name} " \
51
+ 'are not yet implemented.'
52
+ req.on_data.call(response.body, response.body.bytesize)
47
53
  end
48
54
 
49
55
  save_response(env, response.status, response.body, response.headers)
50
56
  @app.call env
51
57
  end
52
58
 
59
+ private
60
+
53
61
  def execute_request(env, rack_env)
54
62
  @session.request(env[:url].to_s, rack_env)
55
63
  end
64
+
65
+ def build_rack_env(env)
66
+ {
67
+ method: env[:method],
68
+ input: env[:body].respond_to?(:read) ? env[:body].read : env[:body],
69
+ 'rack.url_scheme' => env[:url].scheme
70
+ }
71
+ end
56
72
  end
57
73
  end
58
74
  end
@@ -1,26 +1,56 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # test = Faraday::Connection.new do
4
- # use Faraday::Adapter::Test do |stub|
5
- # stub.get '/nigiri/sake.json' do
6
- # [200, {}, 'hi world']
5
+ # @example
6
+ # test = Faraday::Connection.new do
7
+ # use Faraday::Adapter::Test do |stub|
8
+ # # Define matcher to match the request
9
+ # stub.get '/resource.json' do
10
+ # # return static content
11
+ # [200, {'Content-Type' => 'application/json'}, 'hi world']
12
+ # end
13
+ #
14
+ # # response with content generated based on request
15
+ # stub.get '/showget' do |env|
16
+ # [200, {'Content-Type' => 'text/plain'}, env[:method].to_s]
17
+ # end
18
+ #
19
+ # # A regular expression can be used as matching filter
20
+ # stub.get /\A\/items\/(\d+)\z/ do |env, meta|
21
+ # # in case regular expression is used, an instance of MatchData
22
+ # # can be received
23
+ # [200,
24
+ # {'Content-Type' => 'text/plain'},
25
+ # "showing item: #{meta[:match_data][1]}"
26
+ # ]
27
+ # end
7
28
  # end
8
29
  # end
9
- # end
10
30
  #
11
- # resp = test.get '/nigiri/sake.json'
12
- # resp.body # => 'hi world'
31
+ # resp = test.get '/resource.json'
32
+ # resp.body # => 'hi world'
13
33
  #
34
+ # resp = test.get '/showget'
35
+ # resp.body # => 'get'
36
+ #
37
+ # resp = test.get '/items/1'
38
+ # resp.body # => 'showing item: 1'
39
+ #
40
+ # resp = test.get '/items/2'
41
+ # resp.body # => 'showing item: 2'
14
42
  class Test < Faraday::Adapter
15
43
  attr_accessor :stubs
16
44
 
45
+ # A stack of Stubs
17
46
  class Stubs
18
47
  class NotFound < StandardError
19
48
  end
20
49
 
21
50
  def initialize
22
- # {:get => [Stub, Stub]}
23
- @stack, @consumed = {}, {}
51
+ # { get: [Stub, Stub] }
52
+ @stack = {}
53
+ @consumed = {}
24
54
  yield(self) if block_given?
25
55
  end
26
56
 
@@ -28,17 +58,18 @@ module Faraday
28
58
  @stack.empty?
29
59
  end
30
60
 
31
- def match(request_method, path, headers, body)
32
- return false if !@stack.key?(request_method)
61
+ def match(request_method, host, path, headers, body)
62
+ return false unless @stack.key?(request_method)
63
+
33
64
  stack = @stack[request_method]
34
65
  consumed = (@consumed[request_method] ||= [])
35
66
 
36
- if stub = matches?(stack, path, headers, body)
67
+ stub, meta = matches?(stack, host, path, headers, body)
68
+ if stub
37
69
  consumed << stack.delete(stub)
38
- stub
39
- else
40
- matches?(consumed, path, headers, body)
70
+ return stub, meta
41
71
  end
72
+ matches?(consumed, host, path, headers, body)
42
73
  end
43
74
 
44
75
  def get(path, headers = {}, &block)
@@ -49,15 +80,15 @@ module Faraday
49
80
  new_stub(:head, path, headers, &block)
50
81
  end
51
82
 
52
- def post(path, body=nil, headers = {}, &block)
83
+ def post(path, body = nil, headers = {}, &block)
53
84
  new_stub(:post, path, headers, body, &block)
54
85
  end
55
86
 
56
- def put(path, body=nil, headers = {}, &block)
87
+ def put(path, body = nil, headers = {}, &block)
57
88
  new_stub(:put, path, headers, body, &block)
58
89
  end
59
90
 
60
- def patch(path, body=nil, headers = {}, &block)
91
+ def patch(path, body = nil, headers = {}, &block)
61
92
  new_stub(:patch, path, headers, body, &block)
62
93
  end
63
94
 
@@ -73,45 +104,83 @@ module Faraday
73
104
  def verify_stubbed_calls
74
105
  failed_stubs = []
75
106
  @stack.each do |method, stubs|
76
- unless stubs.size == 0
77
- failed_stubs.concat(stubs.map {|stub|
107
+ next if stubs.empty?
108
+
109
+ failed_stubs.concat(
110
+ stubs.map do |stub|
78
111
  "Expected #{method} #{stub}."
79
- })
80
- end
112
+ end
113
+ )
81
114
  end
82
- raise failed_stubs.join(" ") unless failed_stubs.size == 0
115
+ raise failed_stubs.join(' ') unless failed_stubs.empty?
83
116
  end
84
117
 
85
118
  protected
86
119
 
87
- def new_stub(request_method, path, headers = {}, body=nil, &block)
88
- normalized_path = Faraday::Utils.normalize_path(path)
89
- (@stack[request_method] ||= []) << Stub.new(normalized_path, headers, body, block)
120
+ def new_stub(request_method, path, headers = {}, body = nil, &block)
121
+ normalized_path, host =
122
+ if path.is_a?(Regexp)
123
+ path
124
+ else
125
+ [
126
+ Faraday::Utils.normalize_path(path),
127
+ Faraday::Utils.URI(path).host
128
+ ]
129
+ end
130
+
131
+ stub = Stub.new(host, normalized_path, headers, body, block)
132
+ (@stack[request_method] ||= []) << stub
90
133
  end
91
134
 
92
- def matches?(stack, path, headers, body)
93
- stack.detect { |stub| stub.matches?(path, headers, body) }
135
+ def matches?(stack, host, path, headers, body)
136
+ stack.each do |stub|
137
+ match_result, meta = stub.matches?(host, path, headers, body)
138
+ return stub, meta if match_result
139
+ end
140
+ nil
94
141
  end
95
142
  end
96
143
 
97
- class Stub < Struct.new(:path, :params, :headers, :body, :block)
98
- def initialize(full, headers, body, block)
99
- path, query = full.split('?')
100
- params = query ?
101
- Faraday::Utils.parse_nested_query(query) :
102
- {}
103
- super(path, params, headers, body, block)
144
+ # Stub request
145
+ # rubocop:disable Style/StructInheritance
146
+ class Stub < Struct.new(:host, :path, :params, :headers, :body, :block)
147
+ # rubocop:enable Style/StructInheritance
148
+ def initialize(host, full, headers, body, block)
149
+ path, query = full.respond_to?(:split) ? full.split('?') : full
150
+ params =
151
+ if query
152
+ Faraday::Utils.parse_nested_query(query)
153
+ else
154
+ {}
155
+ end
156
+
157
+ super(host, path, params, headers, body, block)
104
158
  end
105
159
 
106
- def matches?(request_uri, request_headers, request_body)
160
+ def matches?(request_host, request_uri, request_headers, request_body)
107
161
  request_path, request_query = request_uri.split('?')
108
- request_params = request_query ?
109
- Faraday::Utils.parse_nested_query(request_query) :
110
- {}
111
- request_path == path &&
162
+ request_params =
163
+ if request_query
164
+ Faraday::Utils.parse_nested_query(request_query)
165
+ else
166
+ {}
167
+ end
168
+ # meta is a hash used as carrier
169
+ # that will be yielded to consumer block
170
+ meta = {}
171
+ [(host.nil? || host == request_host) &&
172
+ path_match?(request_path, meta) &&
112
173
  params_match?(request_params) &&
113
174
  (body.to_s.size.zero? || request_body == body) &&
114
- headers_match?(request_headers)
175
+ headers_match?(request_headers), meta]
176
+ end
177
+
178
+ def path_match?(request_path, meta)
179
+ if path.is_a?(Regexp)
180
+ !!(meta[:match_data] = path.match(request_path))
181
+ else
182
+ path == request_path
183
+ end
115
184
  end
116
185
 
117
186
  def params_match?(request_params)
@@ -131,7 +200,7 @@ module Faraday
131
200
  end
132
201
  end
133
202
 
134
- def initialize(app, stubs=nil, &block)
203
+ def initialize(app, stubs = nil, &block)
135
204
  super(app)
136
205
  @stubs = stubs || Stubs.new
137
206
  configure(&block) if block
@@ -143,18 +212,33 @@ module Faraday
143
212
 
144
213
  def call(env)
145
214
  super
215
+ host = env[:url].host
146
216
  normalized_path = Faraday::Utils.normalize_path(env[:url])
147
- params_encoder = env.request.params_encoder || Faraday::Utils.default_params_encoder
217
+ params_encoder = env.request.params_encoder ||
218
+ Faraday::Utils.default_params_encoder
219
+
220
+ stub, meta = stubs.match(env[:method], host, normalized_path,
221
+ env.request_headers, env[:body])
222
+
223
+ unless stub
224
+ raise Stubs::NotFound, "no stubbed request for #{env[:method]} "\
225
+ "#{normalized_path} #{env[:body]}"
226
+ end
227
+
228
+ env[:params] = if (query = env[:url].query)
229
+ params_encoder.decode(query)
230
+ else
231
+ {}
232
+ end
233
+ block_arity = stub.block.arity
234
+ status, headers, body =
235
+ if block_arity >= 0
236
+ stub.block.call(*[env, meta].take(block_arity))
237
+ else
238
+ stub.block.call(env, meta)
239
+ end
240
+ save_response(env, status, body, headers)
148
241
 
149
- if stub = stubs.match(env[:method], normalized_path, env.request_headers, env[:body])
150
- env[:params] = (query = env[:url].query) ?
151
- params_encoder.decode(query) :
152
- {}
153
- status, headers, body = stub.block.call(env)
154
- save_response(env, status, body, headers)
155
- else
156
- raise Stubs::NotFound, "no stubbed request for #{env[:method]} #{normalized_path} #{env[:body]}"
157
- end
158
242
  @app.call(env)
159
243
  end
160
244
  end
@@ -1,123 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Typhoeus adapter. This class is just a stub, the real adapter is in
6
+ # https://github.com/philsturgeon/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
3
7
  class Typhoeus < Faraday::Adapter
4
- self.supports_parallel = true
5
-
6
- def self.setup_parallel_manager(options = {})
7
- options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
8
- end
8
+ # Needs to define this method in order to support Typhoeus <= 1.3.0
9
+ def call; end
9
10
 
10
11
  dependency 'typhoeus'
11
-
12
- def call(env)
13
- super
14
- perform_request env
15
- @app.call env
16
- end
17
-
18
- def perform_request(env)
19
- read_body env
20
-
21
- hydra = env[:parallel_manager] || self.class.setup_parallel_manager
22
- hydra.queue request(env)
23
- hydra.run unless parallel?(env)
24
- rescue Errno::ECONNREFUSED
25
- raise Error::ConnectionFailed, $!
26
- end
27
-
28
- # TODO: support streaming requests
29
- def read_body(env)
30
- env[:body] = env[:body].read if env[:body].respond_to? :read
31
- end
32
-
33
- def request(env)
34
- method = env[:method]
35
- # For some reason, prevents Typhoeus from using "100-continue".
36
- # We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
37
- method = method.to_s.upcase if method == :put
38
-
39
- req = ::Typhoeus::Request.new env[:url].to_s,
40
- :method => method,
41
- :body => env[:body],
42
- :headers => env[:request_headers],
43
- :disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
44
-
45
- configure_ssl req, env
46
- configure_proxy req, env
47
- configure_timeout req, env
48
- configure_socket req, env
49
-
50
- req.on_complete do |resp|
51
- if resp.timed_out?
52
- if parallel?(env)
53
- # TODO: error callback in async mode
54
- else
55
- raise Faraday::Error::TimeoutError, "request timed out"
56
- end
57
- end
58
-
59
- case resp.curl_return_code
60
- when 0
61
- # everything OK
62
- when 7
63
- raise Error::ConnectionFailed, resp.curl_error_message
64
- when 60
65
- raise Faraday::SSLError, resp.curl_error_message
66
- else
67
- raise Error::ClientError, resp.curl_error_message
68
- end
69
-
70
- save_response(env, resp.code, resp.body) do |response_headers|
71
- response_headers.parse resp.headers
72
- end
73
- # in async mode, :response is initialized at this point
74
- env[:response].finish(env) if parallel?(env)
75
- end
76
-
77
- req
78
- end
79
-
80
- def configure_ssl(req, env)
81
- ssl = env[:ssl]
82
-
83
- req.ssl_version = ssl[:version] if ssl[:version]
84
- req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
85
- req.ssl_key = ssl[:client_key] if ssl[:client_key]
86
- req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
87
- req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
88
- end
89
-
90
- def configure_proxy(req, env)
91
- proxy = request_options(env)[:proxy]
92
- return unless proxy
93
-
94
- req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
95
-
96
- if proxy[:user] && proxy[:password]
97
- req.proxy_username = proxy[:user]
98
- req.proxy_password = proxy[:password]
99
- end
100
- end
101
-
102
- def configure_timeout(req, env)
103
- env_req = request_options(env)
104
- req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
105
- req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
106
- end
107
-
108
- def configure_socket(req, env)
109
- if bind = request_options(env)[:bind]
110
- req.interface = bind[:host]
111
- end
112
- end
113
-
114
- def request_options(env)
115
- env[:request]
116
- end
117
-
118
- def parallel?(env)
119
- !!env[:parallel_manager]
120
- end
12
+ dependency 'typhoeus/adapters/faraday'
121
13
  end
122
14
  end
123
15
  end
@@ -1,46 +1,69 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- # Public: This is a base class for all Faraday adapters. Adapters are
4
+ # Base class for all Faraday adapters. Adapters are
3
5
  # responsible for fulfilling a Faraday request.
4
- class Adapter < Middleware
5
- CONTENT_LENGTH = 'Content-Length'.freeze
6
-
7
- register_middleware File.expand_path('../adapter', __FILE__),
8
- :test => [:Test, 'test'],
9
- :net_http => [:NetHttp, 'net_http'],
10
- :net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
11
- :typhoeus => [:Typhoeus, 'typhoeus'],
12
- :patron => [:Patron, 'patron'],
13
- :em_synchrony => [:EMSynchrony, 'em_synchrony'],
14
- :em_http => [:EMHttp, 'em_http'],
15
- :excon => [:Excon, 'excon'],
16
- :rack => [:Rack, 'rack'],
17
- :httpclient => [:HTTPClient, 'httpclient']
18
-
19
- # Public: This module marks an Adapter as supporting parallel requests.
6
+ class Adapter
7
+ extend MiddlewareRegistry
8
+ extend DependencyLoader
9
+
10
+ CONTENT_LENGTH = 'Content-Length'
11
+
12
+ register_middleware File.expand_path('adapter', __dir__),
13
+ test: [:Test, 'test'],
14
+ net_http: [:NetHttp, 'net_http'],
15
+ net_http_persistent: [
16
+ :NetHttpPersistent,
17
+ 'net_http_persistent'
18
+ ],
19
+ typhoeus: [:Typhoeus, 'typhoeus'],
20
+ patron: [:Patron, 'patron'],
21
+ em_synchrony: [:EMSynchrony, 'em_synchrony'],
22
+ em_http: [:EMHttp, 'em_http'],
23
+ excon: [:Excon, 'excon'],
24
+ rack: [:Rack, 'rack'],
25
+ httpclient: [:HTTPClient, 'httpclient']
26
+
27
+ # This module marks an Adapter as supporting parallel requests.
20
28
  module Parallelism
21
29
  attr_writer :supports_parallel
22
- def supports_parallel?() @supports_parallel end
30
+ def supports_parallel?
31
+ @supports_parallel
32
+ end
23
33
 
24
34
  def inherited(subclass)
25
35
  super
26
- subclass.supports_parallel = self.supports_parallel?
36
+ subclass.supports_parallel = supports_parallel?
27
37
  end
28
38
  end
29
39
 
30
40
  extend Parallelism
31
41
  self.supports_parallel = false
32
42
 
43
+ def initialize(_app = nil, opts = {}, &block)
44
+ @app = ->(env) { env.response }
45
+ @connection_options = opts
46
+ @config_block = block
47
+ end
48
+
33
49
  def call(env)
34
50
  env.clear_body if env.needs_body?
51
+ env.response = Response.new
35
52
  end
36
53
 
37
- def save_response(env, status, body, headers = nil)
54
+ private
55
+
56
+ def save_response(env, status, body, headers = nil, reason_phrase = nil)
38
57
  env.status = status
39
58
  env.body = body
59
+ env.reason_phrase = reason_phrase&.to_s&.strip
40
60
  env.response_headers = Utils::Headers.new.tap do |response_headers|
41
61
  response_headers.update headers unless headers.nil?
42
62
  yield(response_headers) if block_given?
43
63
  end
64
+
65
+ env.response.finish(env) unless env.parallel?
66
+ env.response
44
67
  end
45
68
  end
46
69
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'monitor'
4
+
5
+ module Faraday
6
+ # AdapterRegistry registers adapter class names so they can be looked up by a
7
+ # String or Symbol name.
8
+ class AdapterRegistry
9
+ def initialize
10
+ @lock = Monitor.new
11
+ @constants = {}
12
+ end
13
+
14
+ def get(name)
15
+ klass = @constants[name]
16
+ return klass if klass
17
+
18
+ Object.const_get(name).tap { |c| set(c, name) }
19
+ end
20
+
21
+ def set(klass, name = nil)
22
+ name ||= klass.to_s
23
+ @lock.synchronize do
24
+ @constants[name] = klass
25
+ end
26
+ end
27
+ end
28
+ end