faraday 0.12.2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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,78 +1,97 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # HTTPClient adapter.
3
6
  class HTTPClient < Faraday::Adapter
4
7
  dependency 'httpclient'
5
8
 
6
- def client
7
- @client ||= ::HTTPClient.new
8
- end
9
-
10
- def call(env)
11
- super
12
-
13
- # enable compression
14
- client.transparent_gzip_decompression = true
9
+ def build_connection(env)
10
+ @client ||= ::HTTPClient.new.tap do |cli|
11
+ # enable compression
12
+ cli.transparent_gzip_decompression = true
13
+ end
15
14
 
16
- if req = env[:request]
17
- if proxy = req[:proxy]
18
- configure_proxy proxy
15
+ if (req = env[:request])
16
+ if (proxy = req[:proxy])
17
+ configure_proxy @client, proxy
19
18
  end
20
19
 
21
- if bind = req[:bind]
22
- configure_socket bind
20
+ if (bind = req[:bind])
21
+ configure_socket @client, bind
23
22
  end
24
23
 
25
- configure_timeouts req
24
+ configure_timeouts @client, req
26
25
  end
27
26
 
28
- if env[:url].scheme == 'https' && ssl = env[:ssl]
29
- configure_ssl ssl
27
+ if env[:url].scheme == 'https' && (ssl = env[:ssl])
28
+ configure_ssl @client, ssl
30
29
  end
31
30
 
32
- configure_client
31
+ configure_client @client
32
+
33
+ @client
34
+ end
33
35
 
34
- # TODO Don't stream yet.
36
+ def call(env)
37
+ super
38
+
39
+ # TODO: Don't stream yet.
35
40
  # https://github.com/nahi/httpclient/pull/90
36
41
  env[:body] = env[:body].read if env[:body].respond_to? :read
37
42
 
38
- resp = client.request env[:method], env[:url],
39
- :body => env[:body],
40
- :header => env[:request_headers]
43
+ connection(env) do |http|
44
+ resp = http.request env[:method], env[:url],
45
+ body: env[:body],
46
+ header: env[:request_headers]
41
47
 
42
- save_response env, resp.status, resp.body, resp.headers, resp.reason
48
+ if (req = env[:request]).stream_response?
49
+ warn "Streaming downloads for #{self.class.name} " \
50
+ 'are not yet implemented.'
51
+ req.on_data.call(resp.body, resp.body.bytesize)
52
+ end
53
+ save_response env, resp.status, resp.body, resp.headers, resp.reason
43
54
 
44
- @app.call env
55
+ @app.call env
56
+ end
45
57
  rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
46
- raise Faraday::Error::TimeoutError, $!
47
- rescue ::HTTPClient::BadResponseError => err
48
- if err.message.include?('status 407')
49
- raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
50
- else
51
- raise Faraday::Error::ClientError, $!
58
+ raise Faraday::TimeoutError, $ERROR_INFO
59
+ rescue ::HTTPClient::BadResponseError => e
60
+ if e.message.include?('status 407')
61
+ raise Faraday::ConnectionFailed,
62
+ %(407 "Proxy Authentication Required ")
52
63
  end
53
- rescue Errno::ECONNREFUSED, IOError, SocketError
54
- raise Faraday::Error::ConnectionFailed, $!
55
- rescue => err
56
- if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
57
- raise Faraday::SSLError, err
58
- else
59
- raise
64
+
65
+ raise Faraday::ClientError, $ERROR_INFO
66
+ rescue Errno::EADDRNOTAVAIL, Errno::ECONNREFUSED, IOError, SocketError
67
+ raise Faraday::ConnectionFailed, $ERROR_INFO
68
+ rescue StandardError => e
69
+ if defined?(::OpenSSL::SSL::SSLError) && \
70
+ e.is_a?(::OpenSSL::SSL::SSLError)
71
+ raise Faraday::SSLError, e
60
72
  end
73
+
74
+ raise
61
75
  end
62
76
 
63
- def configure_socket(bind)
77
+ # @param bind [Hash]
78
+ def configure_socket(client, bind)
64
79
  client.socket_local.host = bind[:host]
65
80
  client.socket_local.port = bind[:port]
66
81
  end
67
82
 
68
- def configure_proxy(proxy)
83
+ # Configure proxy URI and any user credentials.
84
+ #
85
+ # @param proxy [Hash]
86
+ def configure_proxy(client, proxy)
69
87
  client.proxy = proxy[:uri]
70
- if proxy[:user] && proxy[:password]
71
- client.set_proxy_auth proxy[:user], proxy[:password]
72
- end
88
+ return unless proxy[:user] && proxy[:password]
89
+
90
+ client.set_proxy_auth(proxy[:user], proxy[:password])
73
91
  end
74
92
 
75
- def configure_ssl(ssl)
93
+ # @param ssl [Hash]
94
+ def configure_ssl(client, ssl)
76
95
  ssl_config = client.ssl_config
77
96
  ssl_config.verify_mode = ssl_verify_mode(ssl)
78
97
  ssl_config.cert_store = ssl_cert_store(ssl)
@@ -84,40 +103,45 @@ module Faraday
84
103
  ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
85
104
  end
86
105
 
87
- def configure_timeouts(req)
88
- if req[:timeout]
89
- client.connect_timeout = req[:timeout]
90
- client.receive_timeout = req[:timeout]
91
- client.send_timeout = req[:timeout]
106
+ # @param req [Hash]
107
+ def configure_timeouts(client, req)
108
+ if (sec = request_timeout(:open, req))
109
+ client.connect_timeout = sec
92
110
  end
93
111
 
94
- if req[:open_timeout]
95
- client.connect_timeout = req[:open_timeout]
96
- client.send_timeout = req[:open_timeout]
112
+ if (sec = request_timeout(:write, req))
113
+ client.send_timeout = sec
97
114
  end
115
+
116
+ return unless (sec = request_timeout(:read, req))
117
+
118
+ client.receive_timeout = sec
98
119
  end
99
120
 
100
- def configure_client
101
- @config_block.call(client) if @config_block
121
+ def configure_client(client)
122
+ @config_block&.call(client)
102
123
  end
103
124
 
125
+ # @param ssl [Hash]
126
+ # @return [OpenSSL::X509::Store]
104
127
  def ssl_cert_store(ssl)
105
128
  return ssl[:cert_store] if ssl[:cert_store]
129
+
106
130
  # Memoize the cert store so that the same one is passed to
107
- # HTTPClient each time, to avoid resyncing SSL sesions when
131
+ # HTTPClient each time, to avoid resyncing SSL sessions when
108
132
  # it's changed
109
- @cert_store ||= begin
133
+ @ssl_cert_store ||= begin
110
134
  # Use the default cert store by default, i.e. system ca certs
111
- cert_store = OpenSSL::X509::Store.new
112
- cert_store.set_default_paths
113
- cert_store
135
+ OpenSSL::X509::Store.new.tap(&:set_default_paths)
114
136
  end
115
137
  end
116
138
 
139
+ # @param ssl [Hash]
117
140
  def ssl_verify_mode(ssl)
118
141
  ssl[:verify_mode] || begin
119
142
  if ssl.fetch(:verify, true)
120
- OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
143
+ OpenSSL::SSL::VERIFY_PEER |
144
+ OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
121
145
  else
122
146
  OpenSSL::SSL::VERIFY_NONE
123
147
  end
@@ -1,49 +1,90 @@
1
- # Rely on autoloading instead of explicit require; helps avoid the "already
2
- # initialized constant" warning on Ruby 1.8.7 when NetHttp is refereced below.
3
- # require 'faraday/adapter/net_http'
1
+ # frozen_string_literal: true
4
2
 
5
3
  module Faraday
6
4
  class Adapter
5
+ # Net::HTTP::Persistent adapter.
7
6
  class NetHttpPersistent < NetHttp
8
7
  dependency 'net/http/persistent'
9
8
 
9
+ private
10
+
10
11
  def net_http_connection(env)
12
+ @cached_connection ||=
13
+ if Net::HTTP::Persistent.instance_method(:initialize)
14
+ .parameters.first == %i[key name]
15
+ options = { name: 'Faraday' }
16
+ if @connection_options.key?(:pool_size)
17
+ options[:pool_size] = @connection_options[:pool_size]
18
+ end
19
+ Net::HTTP::Persistent.new(**options)
20
+ else
21
+ Net::HTTP::Persistent.new('Faraday')
22
+ end
23
+
24
+ proxy_uri = proxy_uri(env)
25
+ if @cached_connection.proxy_uri != proxy_uri
26
+ @cached_connection.proxy = proxy_uri
27
+ end
28
+ @cached_connection
29
+ end
30
+
31
+ def proxy_uri(env)
32
+ proxy_uri = nil
11
33
  if (proxy = env[:request][:proxy])
12
- proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
34
+ proxy_uri = if proxy[:uri].is_a?(::URI::HTTP)
35
+ proxy[:uri].dup
36
+ else
37
+ ::URI.parse(proxy[:uri].to_s)
38
+ end
13
39
  proxy_uri.user = proxy_uri.password = nil
14
- # awful patch for net-http-persistent 2.8 not unescaping user/password
15
- (class << proxy_uri; self; end).class_eval do
16
- define_method(:user) { proxy[:user] }
17
- define_method(:password) { proxy[:password] }
18
- end if proxy[:user]
19
- return Net::HTTP::Persistent.new 'Faraday', proxy_uri
40
+ # awful patch for net-http-persistent 2.8
41
+ # not unescaping user/password
42
+ if proxy[:user]
43
+ (class << proxy_uri; self; end).class_eval do
44
+ define_method(:user) { proxy[:user] }
45
+ define_method(:password) { proxy[:password] }
46
+ end
47
+ end
20
48
  end
21
-
22
- Net::HTTP::Persistent.new 'Faraday'
49
+ proxy_uri
23
50
  end
24
51
 
25
52
  def perform_request(http, env)
26
53
  http.request env[:url], create_request(env)
27
- rescue Errno::ETIMEDOUT => error
28
- raise Faraday::Error::TimeoutError, error
29
- rescue Net::HTTP::Persistent::Error => error
30
- if error.message.include? 'Timeout'
31
- raise Faraday::Error::TimeoutError, error
32
- elsif error.message.include? 'connection refused'
33
- raise Faraday::Error::ConnectionFailed, error
34
- else
35
- raise
54
+ rescue Errno::ETIMEDOUT, Net::OpenTimeout => e
55
+ raise Faraday::TimeoutError, e
56
+ rescue Net::HTTP::Persistent::Error => e
57
+ raise Faraday::TimeoutError, e if e.message.include? 'Timeout'
58
+
59
+ if e.message.include? 'connection refused'
60
+ raise Faraday::ConnectionFailed, e
36
61
  end
62
+
63
+ raise
37
64
  end
38
65
 
66
+ SSL_CONFIGURATIONS = {
67
+ certificate: :client_cert,
68
+ private_key: :client_key,
69
+ ca_file: :ca_file,
70
+ ssl_version: :version,
71
+ min_version: :min_version,
72
+ max_version: :max_version
73
+ }.freeze
74
+
39
75
  def configure_ssl(http, ssl)
40
- http.verify_mode = ssl_verify_mode(ssl)
41
- http.cert_store = ssl_cert_store(ssl)
76
+ return unless ssl
77
+
78
+ http_set(http, :verify_mode, ssl_verify_mode(ssl))
79
+ http_set(http, :cert_store, ssl_cert_store(ssl))
80
+
81
+ SSL_CONFIGURATIONS
82
+ .select { |_, key| ssl[key] }
83
+ .each { |target, key| http_set(http, target, ssl[key]) }
84
+ end
42
85
 
43
- http.certificate = ssl[:client_cert] if ssl[:client_cert]
44
- http.private_key = ssl[:client_key] if ssl[:client_key]
45
- http.ca_file = ssl[:ca_file] if ssl[:ca_file]
46
- http.ssl_version = ssl[:version] if ssl[:version]
86
+ def http_set(http, attr, value)
87
+ http.send("#{attr}=", value) if http.send(attr) != value
47
88
  end
48
89
  end
49
90
  end
@@ -1,53 +1,66 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Patron adapter.
3
6
  class Patron < Faraday::Adapter
4
7
  dependency 'patron'
5
8
 
9
+ def build_connection(env)
10
+ session = ::Patron::Session.new
11
+ @config_block&.call(session)
12
+ if (env[:url].scheme == 'https') && env[:ssl]
13
+ configure_ssl(session, env[:ssl])
14
+ end
15
+
16
+ if (req = env[:request])
17
+ configure_timeouts(session, req)
18
+ configure_proxy(session, req[:proxy])
19
+ end
20
+
21
+ session
22
+ end
23
+
6
24
  def call(env)
7
25
  super
8
26
  # TODO: support streaming requests
9
27
  env[:body] = env[:body].read if env[:body].respond_to? :read
10
28
 
11
- session = @session ||= create_session
12
- configure_ssl(session, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
13
-
14
- if req = env[:request]
15
- session.timeout = session.connect_timeout = req[:timeout] if req[:timeout]
16
- session.connect_timeout = req[:open_timeout] if req[:open_timeout]
17
-
18
- if proxy = req[:proxy]
19
- proxy_uri = proxy[:uri].dup
20
- proxy_uri.user = proxy[:user] && Utils.escape(proxy[:user]).gsub('+', '%20')
21
- proxy_uri.password = proxy[:password] && Utils.escape(proxy[:password]).gsub('+', '%20')
22
- session.proxy = proxy_uri.to_s
29
+ response = connection(env) do |session|
30
+ begin
31
+ data = env[:body] ? env[:body].to_s : nil
32
+ session.request(env[:method], env[:url].to_s,
33
+ env[:request_headers], data: data)
34
+ rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
35
+ raise Faraday::ConnectionFailed, $ERROR_INFO
23
36
  end
24
37
  end
25
38
 
26
- response = begin
27
- data = env[:body] ? env[:body].to_s : nil
28
- session.request(env[:method], env[:url].to_s, env[:request_headers], :data => data)
29
- rescue Errno::ECONNREFUSED, ::Patron::ConnectionFailed
30
- raise Error::ConnectionFailed, $!
39
+ if (req = env[:request]).stream_response?
40
+ warn "Streaming downloads for #{self.class.name} " \
41
+ 'are not yet implemented.'
42
+ req.on_data.call(response.body, response.body.bytesize)
31
43
  end
32
-
33
44
  # Remove the "HTTP/1.1 200", leaving just the reason phrase
34
45
  reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
35
46
 
36
- save_response(env, response.status, response.body, response.headers, reason_phrase)
47
+ save_response(env, response.status, response.body,
48
+ response.headers, reason_phrase)
37
49
 
38
50
  @app.call env
39
- rescue ::Patron::TimeoutError => err
40
- if err.message == "Connection time-out"
41
- raise Faraday::Error::ConnectionFailed, err
42
- else
43
- raise Faraday::Error::TimeoutError, err
51
+ rescue ::Patron::TimeoutError => e
52
+ if connection_timed_out_message?(e.message)
53
+ raise Faraday::ConnectionFailed, e
44
54
  end
45
- rescue ::Patron::Error => err
46
- if err.message.include?("code 407")
47
- raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
48
- else
49
- raise Error::ConnectionFailed, err
55
+
56
+ raise Faraday::TimeoutError, e
57
+ rescue ::Patron::Error => e
58
+ if e.message.include?('code 407')
59
+ raise Faraday::ConnectionFailed,
60
+ %(407 "Proxy Authentication Required ")
50
61
  end
62
+
63
+ raise Faraday::ConnectionFailed, e
51
64
  end
52
65
 
53
66
  if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
@@ -59,18 +72,12 @@ module Faraday
59
72
  actions << :options unless actions.include? :options
60
73
  else
61
74
  # Patron 0.4.20 and up
62
- actions << "PATCH" unless actions.include? "PATCH"
63
- actions << "OPTIONS" unless actions.include? "OPTIONS"
75
+ actions << 'PATCH' unless actions.include? 'PATCH'
76
+ actions << 'OPTIONS' unless actions.include? 'OPTIONS'
64
77
  end
65
78
  end
66
79
  end
67
80
 
68
- def create_session
69
- session = ::Patron::Session.new
70
- @config_block.call(session) if @config_block
71
- session
72
- end
73
-
74
81
  def configure_ssl(session, ssl)
75
82
  if ssl.fetch(:verify, true)
76
83
  session.cacert = ssl[:ca_file]
@@ -78,6 +85,48 @@ module Faraday
78
85
  session.insecure = true
79
86
  end
80
87
  end
88
+
89
+ def configure_timeouts(session, req)
90
+ return unless req
91
+
92
+ if (sec = request_timeout(:read, req))
93
+ session.timeout = sec
94
+ end
95
+
96
+ return unless (sec = request_timeout(:open, req))
97
+
98
+ session.connect_timeout = sec
99
+ end
100
+
101
+ def configure_proxy(session, proxy)
102
+ return unless proxy
103
+
104
+ proxy_uri = proxy[:uri].dup
105
+ proxy_uri.user = proxy[:user] &&
106
+ Utils.escape(proxy[:user]).gsub('+', '%20')
107
+ proxy_uri.password = proxy[:password] &&
108
+ Utils.escape(proxy[:password]).gsub('+', '%20')
109
+ session.proxy = proxy_uri.to_s
110
+ end
111
+
112
+ private
113
+
114
+ CURL_TIMEOUT_MESSAGES = [
115
+ 'Connection time-out',
116
+ 'Connection timed out',
117
+ 'Timed out before name resolve',
118
+ 'server connect has timed out',
119
+ 'Resolving timed out',
120
+ 'name lookup timed out',
121
+ 'timed out before SSL',
122
+ 'connect() timed out'
123
+ ].freeze
124
+
125
+ def connection_timed_out_message?(message)
126
+ CURL_TIMEOUT_MESSAGES.any? do |curl_message|
127
+ message.include?(curl_message)
128
+ end
129
+ end
81
130
  end
82
131
  end
83
132
  end