faraday 1.3.0 → 1.5.1

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.
@@ -1,69 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- class EMSynchrony < Faraday::Adapter
6
- # A parallel manager for EMSynchrony.
7
- class ParallelManager
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
13
- def add(request, method, *args, &block)
14
- queue << {
15
- request: request,
16
- method: method,
17
- args: args,
18
- block: block
19
- }
20
- end
21
-
22
- # Run all requests on queue with `EM::Synchrony::Multi`, wrapping
23
- # it in a reactor and fiber if needed.
24
- def run
25
- result = nil
26
- if !EM.reactor_running?
27
- EM.run do
28
- Fiber.new do
29
- result = perform
30
- EM.stop
31
- end.resume
32
- end
33
- else
34
- result = perform
35
- end
36
- result
37
- end
38
-
39
- private
40
-
41
- # The request queue.
42
- def queue
43
- @queue ||= []
44
- end
45
-
46
- # Main `EM::Synchrony::Multi` performer.
47
- def perform
48
- multi = ::EM::Synchrony::Multi.new
49
-
50
- queue.each do |item|
51
- method = "a#{item[:method]}".to_sym
52
-
53
- req = item[:request].send(method, *item[:args])
54
- req.callback(&item[:block])
55
-
56
- req_name = "req_#{multi.requests.size}".to_sym
57
- multi.add(req_name, req)
58
- end
59
-
60
- # Clear the queue, so parallel manager objects can be reused.
61
- @queue = []
62
-
63
- # Block fiber until all requests have returned.
64
- multi.perform
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,124 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # Excon adapter.
6
- class Excon < Faraday::Adapter
7
- dependency 'excon'
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
-
14
- def call(env)
15
- super
16
-
17
- req_opts = {
18
- method: env[:method].to_s.upcase,
19
- headers: env[:request_headers],
20
- body: read_body(env)
21
- }
22
-
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)
28
- end
29
- end
30
-
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)
34
-
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)
60
- end
61
-
62
- opts
63
- end
64
-
65
- def needs_ssl_settings?(env)
66
- env[:url].scheme == 'https' && env[:ssl]
67
- end
68
-
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
80
-
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]
91
- end
92
- end
93
-
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
106
- end
107
-
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
- }
121
- end
122
- end
123
- end
124
- end
@@ -1,152 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # HTTPClient adapter.
6
- class HTTPClient < Faraday::Adapter
7
- dependency 'httpclient'
8
-
9
- def build_connection(env)
10
- @client ||= ::HTTPClient.new.tap do |cli|
11
- # enable compression
12
- cli.transparent_gzip_decompression = true
13
- end
14
-
15
- if (req = env[:request])
16
- if (proxy = req[:proxy])
17
- configure_proxy @client, proxy
18
- end
19
-
20
- if (bind = req[:bind])
21
- configure_socket @client, bind
22
- end
23
-
24
- configure_timeouts @client, req
25
- end
26
-
27
- if env[:url].scheme == 'https' && (ssl = env[:ssl])
28
- configure_ssl @client, ssl
29
- end
30
-
31
- configure_client @client
32
-
33
- @client
34
- end
35
-
36
- def call(env)
37
- super
38
-
39
- # TODO: Don't stream yet.
40
- # https://github.com/nahi/httpclient/pull/90
41
- env[:body] = env[:body].read if env[:body].respond_to? :read
42
-
43
- connection(env) do |http|
44
- resp = http.request env[:method], env[:url],
45
- body: env[:body],
46
- header: env[:request_headers]
47
-
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
54
-
55
- @app.call env
56
- end
57
- rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
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 ")
63
- end
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
72
- end
73
-
74
- raise
75
- end
76
-
77
- # @param bind [Hash]
78
- def configure_socket(client, bind)
79
- client.socket_local.host = bind[:host]
80
- client.socket_local.port = bind[:port]
81
- end
82
-
83
- # Configure proxy URI and any user credentials.
84
- #
85
- # @param proxy [Hash]
86
- def configure_proxy(client, proxy)
87
- client.proxy = proxy[:uri]
88
- return unless proxy[:user] && proxy[:password]
89
-
90
- client.set_proxy_auth(proxy[:user], proxy[:password])
91
- end
92
-
93
- # @param ssl [Hash]
94
- def configure_ssl(client, ssl)
95
- ssl_config = client.ssl_config
96
- ssl_config.verify_mode = ssl_verify_mode(ssl)
97
- ssl_config.cert_store = ssl_cert_store(ssl)
98
-
99
- ssl_config.add_trust_ca ssl[:ca_file] if ssl[:ca_file]
100
- ssl_config.add_trust_ca ssl[:ca_path] if ssl[:ca_path]
101
- ssl_config.client_cert = ssl[:client_cert] if ssl[:client_cert]
102
- ssl_config.client_key = ssl[:client_key] if ssl[:client_key]
103
- ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
104
- end
105
-
106
- # @param req [Hash]
107
- def configure_timeouts(client, req)
108
- if (sec = request_timeout(:open, req))
109
- client.connect_timeout = sec
110
- end
111
-
112
- if (sec = request_timeout(:write, req))
113
- client.send_timeout = sec
114
- end
115
-
116
- return unless (sec = request_timeout(:read, req))
117
-
118
- client.receive_timeout = sec
119
- end
120
-
121
- def configure_client(client)
122
- @config_block&.call(client)
123
- end
124
-
125
- # @param ssl [Hash]
126
- # @return [OpenSSL::X509::Store]
127
- def ssl_cert_store(ssl)
128
- return ssl[:cert_store] if ssl[:cert_store]
129
-
130
- # Memoize the cert store so that the same one is passed to
131
- # HTTPClient each time, to avoid resyncing SSL sessions when
132
- # it's changed
133
- @ssl_cert_store ||= begin
134
- # Use the default cert store by default, i.e. system ca certs
135
- OpenSSL::X509::Store.new.tap(&:set_default_paths)
136
- end
137
- end
138
-
139
- # @param ssl [Hash]
140
- def ssl_verify_mode(ssl)
141
- ssl[:verify_mode] || begin
142
- if ssl.fetch(:verify, true)
143
- OpenSSL::SSL::VERIFY_PEER |
144
- OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
145
- else
146
- OpenSSL::SSL::VERIFY_NONE
147
- end
148
- end
149
- end
150
- end
151
- end
152
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # Net::HTTP::Persistent adapter.
6
- class NetHttpPersistent < NetHttp
7
- dependency 'net/http/persistent'
8
-
9
- private
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
33
- if (proxy = env[:request][:proxy])
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
39
- proxy_uri.user = proxy_uri.password = nil
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
48
- end
49
- proxy_uri
50
- end
51
-
52
- def perform_request(http, env)
53
- http.request env[:url], create_request(env)
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
61
- end
62
-
63
- raise
64
- end
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
-
75
- def configure_ssl(http, 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
85
-
86
- def http_set(http, attr, value)
87
- http.send("#{attr}=", value) if http.send(attr) != value
88
- end
89
- end
90
- end
91
- end
@@ -1,132 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- class Adapter
5
- # Patron adapter.
6
- class Patron < Faraday::Adapter
7
- dependency 'patron'
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
-
24
- def call(env)
25
- super
26
- # TODO: support streaming requests
27
- env[:body] = env[:body].read if env[:body].respond_to? :read
28
-
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
36
- end
37
- end
38
-
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)
43
- end
44
- # Remove the "HTTP/1.1 200", leaving just the reason phrase
45
- reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
46
-
47
- save_response(env, response.status, response.body,
48
- response.headers, reason_phrase)
49
-
50
- @app.call env
51
- rescue ::Patron::TimeoutError => e
52
- if connection_timed_out_message?(e.message)
53
- raise Faraday::ConnectionFailed, e
54
- end
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 ")
61
- end
62
-
63
- raise Faraday::ConnectionFailed, e
64
- end
65
-
66
- if loaded? && defined?(::Patron::Request::VALID_ACTIONS)
67
- # HAX: helps but doesn't work completely
68
- # https://github.com/toland/patron/issues/34
69
- ::Patron::Request::VALID_ACTIONS.tap do |actions|
70
- if actions[0].is_a?(Symbol)
71
- actions << :patch unless actions.include? :patch
72
- actions << :options unless actions.include? :options
73
- else
74
- # Patron 0.4.20 and up
75
- actions << 'PATCH' unless actions.include? 'PATCH'
76
- actions << 'OPTIONS' unless actions.include? 'OPTIONS'
77
- end
78
- end
79
- end
80
-
81
- def configure_ssl(session, ssl)
82
- if ssl.fetch(:verify, true)
83
- session.cacert = ssl[:ca_file]
84
- else
85
- session.insecure = true
86
- end
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
130
- end
131
- end
132
- end