faraday 0.12.2 → 1.3.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.
Files changed (105) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +350 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +22 -325
  5. data/Rakefile +7 -0
  6. data/examples/client_spec.rb +65 -0
  7. data/examples/client_test.rb +79 -0
  8. data/lib/faraday.rb +120 -188
  9. data/lib/faraday/adapter.rb +84 -22
  10. data/lib/faraday/adapter/em_http.rb +150 -104
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  12. data/lib/faraday/adapter/em_synchrony.rb +110 -63
  13. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  14. data/lib/faraday/adapter/excon.rb +98 -54
  15. data/lib/faraday/adapter/httpclient.rb +83 -59
  16. data/lib/faraday/adapter/net_http_persistent.rb +68 -27
  17. data/lib/faraday/adapter/patron.rb +86 -37
  18. data/lib/faraday/adapter/rack.rb +30 -13
  19. data/lib/faraday/adapter/test.rb +103 -62
  20. data/lib/faraday/adapter/typhoeus.rb +7 -115
  21. data/lib/faraday/adapter_registry.rb +30 -0
  22. data/lib/faraday/autoload.rb +46 -36
  23. data/lib/faraday/connection.rb +336 -177
  24. data/lib/faraday/dependency_loader.rb +37 -0
  25. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  26. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  27. data/lib/faraday/error.rb +126 -37
  28. data/lib/faraday/file_part.rb +128 -0
  29. data/lib/faraday/logging/formatter.rb +105 -0
  30. data/lib/faraday/methods.rb +6 -0
  31. data/lib/faraday/middleware.rb +19 -25
  32. data/lib/faraday/middleware_registry.rb +129 -0
  33. data/lib/faraday/options.rb +39 -193
  34. data/lib/faraday/options/connection_options.rb +22 -0
  35. data/lib/faraday/options/env.rb +181 -0
  36. data/lib/faraday/options/proxy_options.rb +28 -0
  37. data/lib/faraday/options/request_options.rb +22 -0
  38. data/lib/faraday/options/ssl_options.rb +59 -0
  39. data/lib/faraday/param_part.rb +53 -0
  40. data/lib/faraday/parameters.rb +4 -196
  41. data/lib/faraday/rack_builder.rb +77 -63
  42. data/lib/faraday/request.rb +94 -32
  43. data/lib/faraday/request/authorization.rb +44 -30
  44. data/lib/faraday/request/basic_authentication.rb +14 -7
  45. data/lib/faraday/request/instrumentation.rb +45 -27
  46. data/lib/faraday/request/multipart.rb +86 -48
  47. data/lib/faraday/request/retry.rb +209 -134
  48. data/lib/faraday/request/token_authentication.rb +15 -10
  49. data/lib/faraday/request/url_encoded.rb +43 -23
  50. data/lib/faraday/response.rb +27 -23
  51. data/lib/faraday/response/logger.rb +22 -69
  52. data/lib/faraday/response/raise_error.rb +49 -14
  53. data/lib/faraday/utils.rb +38 -247
  54. data/lib/faraday/utils/headers.rb +139 -0
  55. data/lib/faraday/utils/params_hash.rb +61 -0
  56. data/lib/faraday/version.rb +5 -0
  57. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  58. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  59. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  60. data/spec/faraday/adapter/excon_spec.rb +49 -0
  61. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  62. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  63. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  64. data/spec/faraday/adapter/patron_spec.rb +18 -0
  65. data/spec/faraday/adapter/rack_spec.rb +8 -0
  66. data/spec/faraday/adapter/test_spec.rb +260 -0
  67. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  68. data/spec/faraday/adapter_registry_spec.rb +28 -0
  69. data/spec/faraday/adapter_spec.rb +55 -0
  70. data/spec/faraday/composite_read_io_spec.rb +80 -0
  71. data/spec/faraday/connection_spec.rb +691 -0
  72. data/spec/faraday/error_spec.rb +60 -0
  73. data/spec/faraday/middleware_spec.rb +52 -0
  74. data/spec/faraday/options/env_spec.rb +70 -0
  75. data/spec/faraday/options/options_spec.rb +297 -0
  76. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  77. data/spec/faraday/options/request_options_spec.rb +19 -0
  78. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  79. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  80. data/spec/faraday/rack_builder_spec.rb +345 -0
  81. data/spec/faraday/request/authorization_spec.rb +88 -0
  82. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  83. data/spec/faraday/request/multipart_spec.rb +302 -0
  84. data/spec/faraday/request/retry_spec.rb +242 -0
  85. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  86. data/spec/faraday/request_spec.rb +120 -0
  87. data/spec/faraday/response/logger_spec.rb +220 -0
  88. data/spec/faraday/response/middleware_spec.rb +68 -0
  89. data/spec/faraday/response/raise_error_spec.rb +169 -0
  90. data/spec/faraday/response_spec.rb +75 -0
  91. data/spec/faraday/utils/headers_spec.rb +82 -0
  92. data/spec/faraday/utils_spec.rb +56 -0
  93. data/spec/faraday_spec.rb +37 -0
  94. data/spec/spec_helper.rb +132 -0
  95. data/spec/support/disabling_stub.rb +14 -0
  96. data/spec/support/fake_safe_buffer.rb +15 -0
  97. data/spec/support/helper_methods.rb +133 -0
  98. data/spec/support/shared_examples/adapter.rb +105 -0
  99. data/spec/support/shared_examples/params_encoder.rb +18 -0
  100. data/spec/support/shared_examples/request_method.rb +262 -0
  101. data/spec/support/streaming_response_checker.rb +35 -0
  102. data/spec/support/webmock_rack_app.rb +68 -0
  103. metadata +109 -10
  104. data/lib/faraday/adapter/net_http.rb +0 -135
  105. data/lib/faraday/upload_io.rb +0 -67
@@ -1,43 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'openssl'
2
4
  require 'em-http'
3
5
 
6
+ # EventMachine patch to make SSL work.
4
7
  module EmHttpSslPatch
5
8
  def ssl_verify_peer(cert_string)
6
- cert = nil
7
9
  begin
8
- cert = OpenSSL::X509::Certificate.new(cert_string)
10
+ @last_seen_cert = OpenSSL::X509::Certificate.new(cert_string)
9
11
  rescue OpenSSL::X509::CertificateError
10
12
  return false
11
13
  end
12
14
 
13
- @last_seen_cert = cert
14
-
15
- if certificate_store.verify(@last_seen_cert)
16
- begin
17
- certificate_store.add_cert(@last_seen_cert)
18
- rescue OpenSSL::X509::StoreError => e
19
- raise e unless e.message == 'cert already in hash table'
20
- end
21
- true
22
- else
23
- raise OpenSSL::SSL::SSLError.new(%(unable to verify the server certificate for "#{host}"))
15
+ unless certificate_store.verify(@last_seen_cert)
16
+ raise OpenSSL::SSL::SSLError,
17
+ %(unable to verify the server certificate for "#{host}")
18
+ end
19
+
20
+ begin
21
+ certificate_store.add_cert(@last_seen_cert)
22
+ rescue OpenSSL::X509::StoreError => e
23
+ raise e unless e.message == 'cert already in hash table'
24
24
  end
25
+ true
25
26
  end
26
27
 
27
28
  def ssl_handshake_completed
28
29
  return true unless verify_peer?
29
30
 
30
- unless OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
31
- raise OpenSSL::SSL::SSLError.new(%(host "#{host}" does not match the server certificate))
32
- else
33
- true
31
+ unless verified_cert_identity?
32
+ raise OpenSSL::SSL::SSLError,
33
+ %(host "#{host}" does not match the server certificate)
34
34
  end
35
+
36
+ true
35
37
  end
36
38
 
37
39
  def verify_peer?
38
40
  parent.connopts.tls[:verify_peer]
39
41
  end
40
42
 
43
+ def verified_cert_identity?
44
+ OpenSSL::SSL.verify_certificate_identity(@last_seen_cert, host)
45
+ end
46
+
41
47
  def host
42
48
  parent.uri.host
43
49
  end
@@ -53,4 +59,4 @@ module EmHttpSslPatch
53
59
  end
54
60
  end
55
61
 
56
- EventMachine::HttpStubConnection.send(:include, EmHttpSslPatch)
62
+ EventMachine::HttpStubConnection.include(EmHttpSslPatch)
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
 
3
5
  module Faraday
4
6
  class Adapter
7
+ # EventMachine Synchrony adapter.
5
8
  class EMSynchrony < Faraday::Adapter
6
9
  include EMHttp::Options
7
10
 
@@ -9,11 +12,28 @@ module Faraday
9
12
  require 'em-synchrony/em-http'
10
13
  require 'em-synchrony/em-multi'
11
14
  require 'fiber'
15
+
16
+ require 'faraday/adapter/em_synchrony/parallel_manager'
17
+
18
+ if Faraday::Adapter::EMSynchrony.loaded?
19
+ begin
20
+ require 'openssl'
21
+ rescue LoadError
22
+ warn 'Warning: no such file to load -- openssl. ' \
23
+ 'Make sure it is installed if you want HTTPS support'
24
+ else
25
+ require 'em-http/version'
26
+ if EventMachine::HttpRequest::VERSION < '1.1.6'
27
+ require 'faraday/adapter/em_http_ssl_patch'
28
+ end
29
+ end
30
+ end
12
31
  end
13
32
 
14
33
  self.supports_parallel = true
15
34
 
16
- def self.setup_parallel_manager(options = {})
35
+ # @return [ParallelManager]
36
+ def self.setup_parallel_manager(_options = nil)
17
37
  ParallelManager.new
18
38
  end
19
39
 
@@ -23,84 +43,111 @@ module Faraday
23
43
 
24
44
  http_method = env[:method].to_s.downcase.to_sym
25
45
 
26
- # Queue requests for parallel execution.
27
46
  if env[:parallel_manager]
28
- env[:parallel_manager].add(request, http_method, request_config(env)) do |resp|
29
- save_response(env, resp.response_header.status, resp.response) do |resp_headers|
30
- resp.response_header.each do |name, value|
31
- resp_headers[name.to_sym] = value
32
- end
33
- end
47
+ # Queue requests for parallel execution.
48
+ execute_parallel_request(env, request, http_method)
49
+ else
50
+ # Execute single request.
51
+ execute_single_request(env, request, http_method)
52
+ end
34
53
 
35
- # Finalize the response object with values from `env`.
36
- env[:response].finish(env)
37
- end
54
+ @app.call env
55
+ rescue Errno::ECONNREFUSED
56
+ raise Faraday::ConnectionFailed, $ERROR_INFO
57
+ rescue EventMachine::Connectify::CONNECTError => e
58
+ if e.message.include?('Proxy Authentication Required')
59
+ raise Faraday::ConnectionFailed,
60
+ %(407 "Proxy Authentication Required")
61
+ end
38
62
 
39
- # Execute single request.
40
- else
41
- client = nil
42
- block = lambda { request.send(http_method, request_config(env)) }
43
-
44
- if !EM.reactor_running?
45
- EM.run do
46
- Fiber.new {
47
- client = block.call
48
- EM.stop
49
- }.resume
50
- end
51
- else
52
- client = block.call
53
- end
63
+ raise Faraday::ConnectionFailed, e
64
+ rescue Errno::ETIMEDOUT => e
65
+ raise Faraday::TimeoutError, e
66
+ rescue RuntimeError => e
67
+ if e.message == 'connection closed by server'
68
+ raise Faraday::ConnectionFailed, e
69
+ end
70
+
71
+ raise Faraday::TimeoutError, e if e.message.include?('timeout error')
72
+
73
+ raise
74
+ rescue StandardError => e
75
+ if defined?(OpenSSL) && e.is_a?(OpenSSL::SSL::SSLError)
76
+ raise Faraday::SSLError, e
77
+ end
78
+
79
+ raise
80
+ end
81
+
82
+ def create_request(env)
83
+ EventMachine::HttpRequest.new(
84
+ Utils::URI(env[:url].to_s),
85
+ connection_config(env).merge(@connection_options)
86
+ )
87
+ end
88
+
89
+ private
54
90
 
55
- raise client.error if client.error
91
+ def execute_parallel_request(env, request, http_method)
92
+ env[:parallel_manager].add(request, http_method,
93
+ request_config(env)) do |resp|
94
+ if (req = env[:request]).stream_response?
95
+ warn "Streaming downloads for #{self.class.name} " \
96
+ 'are not yet implemented.'
97
+ req.on_data.call(resp.response, resp.response.bytesize)
98
+ end
56
99
 
57
- status = client.response_header.status
58
- reason = client.response_header.http_reason
59
- save_response(env, status, client.response, nil, reason) do |resp_headers|
60
- client.response_header.each do |name, value|
100
+ save_response(env, resp.response_header.status,
101
+ resp.response) do |resp_headers|
102
+ resp.response_header.each do |name, value|
61
103
  resp_headers[name.to_sym] = value
62
104
  end
63
105
  end
106
+
107
+ # Finalize the response object with values from `env`.
108
+ env[:response].finish(env)
64
109
  end
110
+ end
65
111
 
66
- @app.call env
67
- rescue Errno::ECONNREFUSED
68
- raise Error::ConnectionFailed, $!
69
- rescue EventMachine::Connectify::CONNECTError => err
70
- if err.message.include?("Proxy Authentication Required")
71
- raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
72
- else
73
- raise Error::ConnectionFailed, err
112
+ def execute_single_request(env, request, http_method)
113
+ block = -> { request.send(http_method, request_config(env)) }
114
+ client = call_block(block)
115
+
116
+ raise client.error if client&.error
117
+
118
+ if env[:request].stream_response?
119
+ warn "Streaming downloads for #{self.class.name} " \
120
+ 'are not yet implemented.'
121
+ env[:request].on_data.call(
122
+ client.response,
123
+ client.response.bytesize
124
+ )
74
125
  end
75
- rescue Errno::ETIMEDOUT => err
76
- raise Error::TimeoutError, err
77
- rescue RuntimeError => err
78
- if err.message == "connection closed by server"
79
- raise Error::ConnectionFailed, err
80
- else
81
- raise
126
+ status = client.response_header.status
127
+ reason = client.response_header.http_reason
128
+ save_response(env, status, client.response, nil, reason) do |headers|
129
+ client.response_header.each do |name, value|
130
+ headers[name.to_sym] = value
131
+ end
82
132
  end
83
- rescue => err
84
- if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
85
- raise Faraday::SSLError, err
133
+ end
134
+
135
+ def call_block(block)
136
+ client = nil
137
+
138
+ if EM.reactor_running?
139
+ client = block.call
86
140
  else
87
- raise
141
+ EM.run do
142
+ Fiber.new do
143
+ client = block.call
144
+ EM.stop
145
+ end.resume
146
+ end
88
147
  end
89
- end
90
148
 
91
- def create_request(env)
92
- EventMachine::HttpRequest.new(Utils::URI(env[:url].to_s), connection_config(env).merge(@connection_options))
149
+ client
93
150
  end
94
151
  end
95
152
  end
96
153
  end
97
-
98
- require 'faraday/adapter/em_synchrony/parallel_manager'
99
-
100
- begin
101
- require 'openssl'
102
- rescue LoadError
103
- warn "Warning: no such file to load -- openssl. Make sure it is installed if you want HTTPS support"
104
- else
105
- require 'faraday/adapter/em_http_ssl_patch'
106
- end if Faraday::Adapter::EMSynchrony.loaded?
@@ -1,16 +1,21 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
5
  class EMSynchrony < Faraday::Adapter
6
+ # A parallel manager for EMSynchrony.
4
7
  class ParallelManager
5
-
6
- # Add requests to queue. The `request` argument should be a
7
- # `EM::HttpRequest` object.
8
+ # Add requests to queue.
9
+ #
10
+ # @param request [EM::HttpRequest]
11
+ # @param method [Symbol, String] HTTP method
12
+ # @param args [Array] the rest of the positional arguments
8
13
  def add(request, method, *args, &block)
9
14
  queue << {
10
- :request => request,
11
- :method => method,
12
- :args => args,
13
- :block => block
15
+ request: request,
16
+ method: method,
17
+ args: args,
18
+ block: block
14
19
  }
15
20
  end
16
21
 
@@ -19,19 +24,18 @@ module Faraday
19
24
  def run
20
25
  result = nil
21
26
  if !EM.reactor_running?
22
- EM.run {
27
+ EM.run do
23
28
  Fiber.new do
24
29
  result = perform
25
30
  EM.stop
26
31
  end.resume
27
- }
32
+ end
28
33
  else
29
34
  result = perform
30
35
  end
31
36
  result
32
37
  end
33
38
 
34
-
35
39
  private
36
40
 
37
41
  # The request queue.
@@ -59,8 +63,7 @@ module Faraday
59
63
  # Block fiber until all requests have returned.
60
64
  multi.perform
61
65
  end
62
-
63
- end # ParallelManager
64
- end # EMSynchrony
65
- end # Adapter
66
- end # Faraday
66
+ end
67
+ end
68
+ end
69
+ end
@@ -1,79 +1,123 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Excon adapter.
3
6
  class Excon < Faraday::Adapter
4
7
  dependency 'excon'
5
8
 
9
+ def build_connection(env)
10
+ opts = opts_from_env(env)
11
+ ::Excon.new(env[:url].to_s, opts.merge(@connection_options))
12
+ end
13
+
6
14
  def call(env)
7
15
  super
8
16
 
9
- opts = {}
10
- if env[:url].scheme == 'https' && ssl = env[:ssl]
11
- opts[:ssl_verify_peer] = !!ssl.fetch(:verify, true)
12
- opts[:ssl_ca_path] = ssl[:ca_path] if ssl[:ca_path]
13
- opts[:ssl_ca_file] = ssl[:ca_file] if ssl[:ca_file]
14
- opts[:client_cert] = ssl[:client_cert] if ssl[:client_cert]
15
- opts[:client_key] = ssl[:client_key] if ssl[:client_key]
16
- opts[:certificate] = ssl[:certificate] if ssl[:certificate]
17
- opts[:private_key] = ssl[:private_key] if ssl[:private_key]
18
-
19
- # https://github.com/geemus/excon/issues/106
20
- # https://github.com/jruby/jruby-ossl/issues/19
21
- opts[:nonblock] = false
22
- end
17
+ req_opts = {
18
+ method: env[:method].to_s.upcase,
19
+ headers: env[:request_headers],
20
+ body: read_body(env)
21
+ }
23
22
 
24
- if ( req = env[:request] )
25
- if req[:timeout]
26
- opts[:read_timeout] = req[:timeout]
27
- opts[:connect_timeout] = req[:timeout]
28
- opts[:write_timeout] = req[:timeout]
23
+ req = env[:request]
24
+ if req&.stream_response?
25
+ total = 0
26
+ req_opts[:response_block] = lambda do |chunk, _remain, _total|
27
+ req.on_data.call(chunk, total += chunk.size)
29
28
  end
29
+ end
30
30
 
31
- if req[:open_timeout]
32
- opts[:connect_timeout] = req[:open_timeout]
33
- opts[:write_timeout] = req[:open_timeout]
34
- end
31
+ resp = connection(env) { |http| http.request(req_opts) }
32
+ save_response(env, resp.status.to_i, resp.body, resp.headers,
33
+ resp.reason_phrase)
35
34
 
36
- if req[:proxy]
37
- opts[:proxy] = {
38
- :host => req[:proxy][:uri].host,
39
- :hostname => req[:proxy][:uri].hostname,
40
- :port => req[:proxy][:uri].port,
41
- :scheme => req[:proxy][:uri].scheme,
42
- :user => req[:proxy][:user],
43
- :password => req[:proxy][:password]
44
- }
45
- end
35
+ @app.call(env)
36
+ rescue ::Excon::Errors::SocketError => e
37
+ raise Faraday::TimeoutError, e if e.message.match?(/\btimeout\b/)
38
+
39
+ raise Faraday::SSLError, e if e.message.match?(/\bcertificate\b/)
40
+
41
+ raise Faraday::ConnectionFailed, e
42
+ rescue ::Excon::Errors::Timeout => e
43
+ raise Faraday::TimeoutError, e
44
+ end
45
+
46
+ # TODO: support streaming requests
47
+ def read_body(env)
48
+ env[:body].respond_to?(:read) ? env[:body].read : env[:body]
49
+ end
50
+
51
+ private
52
+
53
+ def opts_from_env(env)
54
+ opts = {}
55
+ amend_opts_with_ssl!(opts, env[:ssl]) if needs_ssl_settings?(env)
56
+
57
+ if (req = env[:request])
58
+ amend_opts_with_timeouts!(opts, req)
59
+ amend_opts_with_proxy_settings!(opts, req)
46
60
  end
47
61
 
48
- conn = create_connection(env, opts)
62
+ opts
63
+ end
49
64
 
50
- resp = conn.request \
51
- :method => env[:method].to_s.upcase,
52
- :headers => env[:request_headers],
53
- :body => read_body(env)
65
+ def needs_ssl_settings?(env)
66
+ env[:url].scheme == 'https' && env[:ssl]
67
+ end
54
68
 
55
- save_response(env, resp.status.to_i, resp.body, resp.headers, resp.reason_phrase)
69
+ OPTS_KEYS = [
70
+ %i[client_cert client_cert],
71
+ %i[client_key client_key],
72
+ %i[certificate certificate],
73
+ %i[private_key private_key],
74
+ %i[ssl_ca_path ca_path],
75
+ %i[ssl_ca_file ca_file],
76
+ %i[ssl_version version],
77
+ %i[ssl_min_version min_version],
78
+ %i[ssl_max_version max_version]
79
+ ].freeze
56
80
 
57
- @app.call env
58
- rescue ::Excon::Errors::SocketError => err
59
- if err.message =~ /\btimeout\b/
60
- raise Error::TimeoutError, err
61
- elsif err.message =~ /\bcertificate\b/
62
- raise Faraday::SSLError, err
63
- else
64
- raise Error::ConnectionFailed, err
81
+ def amend_opts_with_ssl!(opts, ssl)
82
+ opts[:ssl_verify_peer] = !!ssl.fetch(:verify, true)
83
+ # https://github.com/geemus/excon/issues/106
84
+ # https://github.com/jruby/jruby-ossl/issues/19
85
+ opts[:nonblock] = false
86
+
87
+ OPTS_KEYS.each do |(key_in_opts, key_in_ssl)|
88
+ next unless ssl[key_in_ssl]
89
+
90
+ opts[key_in_opts] = ssl[key_in_ssl]
65
91
  end
66
- rescue ::Excon::Errors::Timeout => err
67
- raise Error::TimeoutError, err
68
92
  end
69
93
 
70
- def create_connection(env, opts)
71
- ::Excon.new(env[:url].to_s, opts.merge(@connection_options))
94
+ def amend_opts_with_timeouts!(opts, req)
95
+ if (sec = request_timeout(:read, req))
96
+ opts[:read_timeout] = sec
97
+ end
98
+
99
+ if (sec = request_timeout(:write, req))
100
+ opts[:write_timeout] = sec
101
+ end
102
+
103
+ return unless (sec = request_timeout(:open, req))
104
+
105
+ opts[:connect_timeout] = sec
72
106
  end
73
107
 
74
- # TODO: support streaming requests
75
- def read_body(env)
76
- env[:body].respond_to?(:read) ? env[:body].read : env[:body]
108
+ def amend_opts_with_proxy_settings!(opts, req)
109
+ opts[:proxy] = proxy_settings_for_opts(req[:proxy]) if req[:proxy]
110
+ end
111
+
112
+ def proxy_settings_for_opts(proxy)
113
+ {
114
+ host: proxy[:uri].host,
115
+ hostname: proxy[:uri].hostname,
116
+ port: proxy[:uri].port,
117
+ scheme: proxy[:uri].scheme,
118
+ user: proxy[:user],
119
+ password: proxy[:password]
120
+ }
77
121
  end
78
122
  end
79
123
  end