faraday 0.8.11 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.document +6 -0
- data/CHANGELOG.md +15 -0
- data/CONTRIBUTING.md +36 -0
- data/Gemfile +10 -3
- data/LICENSE.md +1 -1
- data/README.md +17 -51
- data/Rakefile +2 -18
- data/faraday.gemspec +34 -0
- data/lib/faraday/adapter/em_http.rb +34 -0
- data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
- data/lib/faraday/adapter/em_synchrony.rb +11 -24
- data/lib/faraday/adapter/excon.rb +12 -2
- data/lib/faraday/adapter/httpclient.rb +106 -0
- data/lib/faraday/adapter/net_http.rb +10 -6
- data/lib/faraday/adapter/patron.rb +2 -8
- data/lib/faraday/adapter/rack.rb +0 -2
- data/lib/faraday/adapter/test.rb +39 -39
- data/lib/faraday/adapter/typhoeus.rb +12 -3
- data/lib/faraday/adapter.rb +20 -35
- data/lib/faraday/autoload.rb +85 -0
- data/lib/faraday/connection.rb +232 -125
- data/lib/faraday/error.rb +42 -34
- data/lib/faraday/options.rb +350 -0
- data/lib/faraday/parameters.rb +193 -0
- data/lib/faraday/{builder.rb → rack_builder.rb} +79 -22
- data/lib/faraday/request/authorization.rb +7 -5
- data/lib/faraday/request/basic_authentication.rb +1 -1
- data/lib/faraday/request/instrumentation.rb +36 -0
- data/lib/faraday/request/multipart.rb +10 -9
- data/lib/faraday/request/retry.rb +99 -4
- data/lib/faraday/request/token_authentication.rb +2 -2
- data/lib/faraday/request/url_encoded.rb +7 -6
- data/lib/faraday/request.rb +21 -30
- data/lib/faraday/response/logger.rb +4 -4
- data/lib/faraday/response/raise_error.rb +4 -2
- data/lib/faraday/response.rb +17 -23
- data/lib/faraday/utils.rb +81 -71
- data/lib/faraday.rb +187 -68
- data/script/console +7 -0
- data/script/proxy-server +1 -0
- data/script/release +6 -3
- data/script/test +4 -2
- data/test/adapters/em_http_test.rb +6 -1
- data/test/adapters/em_synchrony_test.rb +7 -1
- data/test/adapters/httpclient_test.rb +21 -0
- data/test/adapters/integration.rb +23 -8
- data/test/adapters/logger_test.rb +1 -1
- data/test/adapters/net_http_persistent_test.rb +10 -1
- data/test/adapters/net_http_test.rb +0 -31
- data/test/adapters/patron_test.rb +4 -1
- data/test/adapters/test_middleware_test.rb +48 -4
- data/test/adapters/typhoeus_test.rb +8 -1
- data/test/authentication_middleware_test.rb +2 -2
- data/test/connection_test.rb +160 -84
- data/test/env_test.rb +51 -24
- data/test/helper.rb +13 -13
- data/test/live_server.rb +8 -0
- data/test/middleware/instrumentation_test.rb +88 -0
- data/test/middleware/retry_test.rb +88 -35
- data/test/middleware_stack_test.rb +13 -12
- data/test/options_test.rb +252 -0
- data/test/request_middleware_test.rb +11 -1
- data/test/response_middleware_test.rb +2 -4
- data/test/strawberry.rb +2 -0
- data/test/utils_test.rb +34 -6
- metadata +71 -11
- data/test/parameters_test.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0e442daff424089e143751d7cb1d684c169bf4fc
|
4
|
+
data.tar.gz: ba1dd50171576d5064350e48b8869364c0710a26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 80c7a955f7d0a2217fcde0be2760649b9e5fc2d950929b118383ba61ea7282410b224315e289b40fec12be13898b0b00551e441704462ac39269368a8f9d5931
|
7
|
+
data.tar.gz: cdef47ebdb9519d0e45e7511326ed1368fa520ad314a4055ea154187193c967f8821573705161e3bbca5d3cbbf40f219071223ba8d24821c5dd89e37ddd16a9e
|
data/.document
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# Faraday Changelog
|
2
|
+
|
3
|
+
## v0.9.0
|
4
|
+
|
5
|
+
* Add HTTPClient adapter (@hakanensari)
|
6
|
+
* Improve Retry handler (@mislav)
|
7
|
+
* Remove autoloading by default (@technoweenie)
|
8
|
+
* Improve internal docs (@technoweenie, @mislav)
|
9
|
+
* Respect user/password in http proxy string (@mislav)
|
10
|
+
* Adapter options are structs. Reinforces consistent options across adapters
|
11
|
+
(@technoweenie)
|
12
|
+
* Stop stripping trailing / off base URLs in a Faraday::Connection. (@technoweenie)
|
13
|
+
* Add a configurable URI parser. (@technoweenie)
|
14
|
+
* Remove need to manually autoload when using the authorization header helpers on `Faraday::Connection`. (@technoweenie)
|
15
|
+
* `Faraday::Adapter::Test` respects the `Faraday::RequestOptions#params_encoder` option. (@technoweenie)
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
## Contributing
|
2
|
+
|
3
|
+
You can run the test suite against a live server by running `script/test`. It
|
4
|
+
automatically starts a test server in background. Only tests in
|
5
|
+
`test/adapters/*_test.rb` require a server, though.
|
6
|
+
|
7
|
+
``` sh
|
8
|
+
# run the whole suite
|
9
|
+
$ script/test
|
10
|
+
|
11
|
+
# run only specific files
|
12
|
+
$ script/test excon typhoeus
|
13
|
+
|
14
|
+
# run tests using SSL
|
15
|
+
$ SSL=yes script/test
|
16
|
+
```
|
17
|
+
|
18
|
+
We will accept middleware that:
|
19
|
+
|
20
|
+
1. is useful to a broader audience, but can be implemented relatively
|
21
|
+
simple; and
|
22
|
+
2. which isn't already present in [faraday_middleware][] project.
|
23
|
+
|
24
|
+
We will accept adapters that:
|
25
|
+
|
26
|
+
1. support SSL & streaming;
|
27
|
+
1. are proven and may have better performance than existing ones; or
|
28
|
+
2. if they have features not present in included adapters.
|
29
|
+
|
30
|
+
We are pushing towards a 1.0 release, when we will have to follow [Semantic
|
31
|
+
Versioning][semver]. If your patch includes changes to break compatiblitity,
|
32
|
+
note that so we can add it to the [Changelog][].
|
33
|
+
|
34
|
+
[semver]: http://semver.org/
|
35
|
+
[changelog]: https://github.com/technoweenie/faraday/wiki/Changelog
|
36
|
+
[faraday_middleware]: https://github.com/pengwynn/faraday_middleware/wiki
|
data/Gemfile
CHANGED
@@ -5,18 +5,25 @@ gem 'jruby-openssl', '~> 0.8.8', :platforms => :jruby
|
|
5
5
|
gem 'rake'
|
6
6
|
|
7
7
|
group :test do
|
8
|
-
gem '
|
8
|
+
gem 'coveralls', :require => false
|
9
9
|
gem 'em-http-request', '>= 1.1', :require => 'em-http'
|
10
|
-
gem 'em-synchrony', '>= 1.0', :require => ['em-synchrony', 'em-synchrony/em-http']
|
10
|
+
gem 'em-synchrony', '>= 1.0.3', :require => ['em-synchrony', 'em-synchrony/em-http']
|
11
11
|
gem 'excon', '>= 0.27.4'
|
12
|
+
gem 'httpclient', '>= 2.2'
|
12
13
|
gem 'leftright', '>= 0.9', :require => false
|
13
14
|
gem 'mime-types', '~> 1.25', :platforms => [:jruby, :ruby_18]
|
15
|
+
gem 'minitest', '>= 5.0.5'
|
14
16
|
gem 'net-http-persistent', '>= 2.5', :require => false
|
15
17
|
gem 'patron', '>= 0.4.2', :platforms => :ruby
|
16
18
|
gem 'rack-test', '>= 0.6', :require => 'rack/test'
|
17
19
|
gem 'simplecov'
|
18
20
|
gem 'sinatra', '~> 1.3'
|
19
|
-
gem 'typhoeus', '~> 0.3.3', :platforms =>
|
21
|
+
gem 'typhoeus', '~> 0.3.3', :platforms => :ruby
|
22
|
+
end
|
23
|
+
|
24
|
+
platforms :rbx do
|
25
|
+
gem 'rubinius-coverage'
|
26
|
+
gem 'rubysl'
|
20
27
|
end
|
21
28
|
|
22
29
|
gemspec
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -51,8 +51,8 @@ end
|
|
51
51
|
|
52
52
|
conn.get do |req|
|
53
53
|
req.url '/search'
|
54
|
-
req.options
|
55
|
-
req.options
|
54
|
+
req.options.timeout = 5 # open/read timeout in seconds
|
55
|
+
req.options.open_timeout = 2 # connection open timeout in seconds
|
56
56
|
end
|
57
57
|
```
|
58
58
|
|
@@ -175,36 +175,6 @@ stubs.verify_stubbed_calls
|
|
175
175
|
* support streaming requests/responses
|
176
176
|
* better stubbing API
|
177
177
|
|
178
|
-
## Contributing
|
179
|
-
|
180
|
-
You can run the test suite against a live server by running `script/test`. It
|
181
|
-
automatically starts a test server in background. Only tests in
|
182
|
-
`test/adapters/*_test.rb` require a server, though.
|
183
|
-
|
184
|
-
``` sh
|
185
|
-
# run the whole suite
|
186
|
-
$ script/test
|
187
|
-
|
188
|
-
# run only specific files
|
189
|
-
$ script/test excon typhoeus
|
190
|
-
```
|
191
|
-
|
192
|
-
We will accept middleware that:
|
193
|
-
|
194
|
-
1. is useful to a broader audience, but can be implemented relatively
|
195
|
-
simple; and
|
196
|
-
2. which isn't already present in [faraday_middleware][] project.
|
197
|
-
|
198
|
-
We will accept adapters that:
|
199
|
-
|
200
|
-
1. support SSL & streaming;
|
201
|
-
1. are proven and may have better performance than existing ones; or
|
202
|
-
2. if they have features not present in included adapters.
|
203
|
-
|
204
|
-
We are pushing towards a 1.0 release, when we will have to follow [Semantic
|
205
|
-
Versioning][semver]. If your patch includes changes to break compatiblitity,
|
206
|
-
note that so we can add it to the [Changelog][].
|
207
|
-
|
208
178
|
## Supported Ruby versions
|
209
179
|
|
210
180
|
This library aims to support and is [tested against][travis] the following Ruby
|
@@ -213,11 +183,12 @@ implementations:
|
|
213
183
|
* MRI 1.8.7
|
214
184
|
* MRI 1.9.2
|
215
185
|
* MRI 1.9.3
|
186
|
+
* MRI 2.0.0
|
187
|
+
* MRI 2.1.0
|
216
188
|
* [JRuby][]
|
217
189
|
* [Rubinius][]
|
218
190
|
|
219
|
-
If something doesn't work on one of these
|
220
|
-
a bug.
|
191
|
+
If something doesn't work on one of these Ruby versions, it's a bug.
|
221
192
|
|
222
193
|
This library may inadvertently work (or seem to work) on other Ruby
|
223
194
|
implementations, however support will only be provided for the versions listed
|
@@ -226,25 +197,20 @@ above.
|
|
226
197
|
If you would like this library to support another Ruby version, you may
|
227
198
|
volunteer to be a maintainer. Being a maintainer entails making sure all tests
|
228
199
|
run and pass on that implementation. When something breaks on your
|
229
|
-
implementation, you will be
|
230
|
-
|
231
|
-
|
200
|
+
implementation, you will be responsible for providing patches in a timely
|
201
|
+
fashion. If critical issues for a particular implementation exist at the time
|
202
|
+
of a major release, support for that Ruby version may be dropped.
|
232
203
|
|
233
204
|
## Copyright
|
234
205
|
|
235
|
-
Copyright (c) 2009-
|
206
|
+
Copyright (c) 2009-2013 [Rick Olson](mailto:technoweenie@gmail.com), Zack Hobson.
|
236
207
|
See [LICENSE][] for details.
|
237
208
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
[typhoeus]: https://github.com/typhoeus/typhoeus#readme
|
247
|
-
[patron]: http://toland.github.com/patron/
|
248
|
-
|
249
|
-
[eventmachine]: https://github.com/igrigorik/em-http-request#readme
|
250
|
-
[faraday_middleware]: https://github.com/pengwynn/faraday_middleware/wiki
|
209
|
+
[travis]: http://travis-ci.org/lostisland/faraday
|
210
|
+
[excon]: https://github.com/geemus/excon#readme
|
211
|
+
[typhoeus]: https://github.com/typhoeus/typhoeus#readme
|
212
|
+
[patron]: http://toland.github.com/patron/
|
213
|
+
[eventmachine]: https://github.com/igrigorik/em-http-request#readme
|
214
|
+
[jruby]: http://jruby.org/
|
215
|
+
[rubinius]: http://rubini.us/
|
216
|
+
[license]: LICENSE.md
|
data/Rakefile
CHANGED
@@ -2,6 +2,8 @@ require 'date'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require 'openssl'
|
4
4
|
require 'rake/testtask'
|
5
|
+
require 'bundler'
|
6
|
+
Bundler::GemHelper.install_tasks
|
5
7
|
|
6
8
|
task :default => :test
|
7
9
|
|
@@ -67,21 +69,3 @@ desc "Open an irb session preloaded with this library"
|
|
67
69
|
task :console do
|
68
70
|
sh "irb -rubygems -r ./lib/#{name}.rb"
|
69
71
|
end
|
70
|
-
|
71
|
-
## release management tasks
|
72
|
-
|
73
|
-
desc "Commit, create tag v#{version} and build and push #{gem_file} to Rubygems"
|
74
|
-
task :release => :build do
|
75
|
-
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
76
|
-
sh "git tag v#{version}"
|
77
|
-
sh "git push origin"
|
78
|
-
sh "git push origin v#{version}"
|
79
|
-
sh "gem push pkg/#{gem_file}"
|
80
|
-
end
|
81
|
-
|
82
|
-
desc "Build #{gem_file} into the pkg directory"
|
83
|
-
task :build do
|
84
|
-
FileUtils.mkdir_p 'pkg'
|
85
|
-
sh "gem build #{gemspec_file}"
|
86
|
-
sh "mv #{gem_file} pkg"
|
87
|
-
end
|
data/faraday.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
lib = "faraday"
|
2
|
+
lib_file = File.expand_path("../lib/#{lib}.rb", __FILE__)
|
3
|
+
File.read(lib_file) =~ /\bVERSION\s*=\s*["'](.+?)["']/
|
4
|
+
version = $1
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.specification_version = 2 if spec.respond_to? :specification_version=
|
8
|
+
spec.required_rubygems_version = '>= 1.3.5'
|
9
|
+
|
10
|
+
spec.name = lib
|
11
|
+
spec.version = version
|
12
|
+
|
13
|
+
spec.summary = "HTTP/REST API client library."
|
14
|
+
|
15
|
+
spec.authors = ["Rick Olson"]
|
16
|
+
spec.email = 'technoweenie@gmail.com'
|
17
|
+
spec.homepage = 'https://github.com/lostisland/faraday'
|
18
|
+
spec.licenses = ['MIT']
|
19
|
+
|
20
|
+
spec.add_dependency 'multipart-post', '>= 1.2', '< 3'
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.0'
|
22
|
+
|
23
|
+
spec.files = %w(.document CHANGELOG.md CONTRIBUTING.md Gemfile LICENSE.md README.md Rakefile)
|
24
|
+
spec.files << "#{lib}.gemspec"
|
25
|
+
spec.files += Dir.glob("lib/**/*.rb")
|
26
|
+
spec.files += Dir.glob("test/**/*.{rb,txt}")
|
27
|
+
spec.files += Dir.glob("script/*")
|
28
|
+
|
29
|
+
dev_null = File.exist?('/dev/null') ? '/dev/null' : 'NUL'
|
30
|
+
git_files = `git ls-files -z 2>#{dev_null}`
|
31
|
+
spec.files &= git_files.split("\0") if $?.success?
|
32
|
+
|
33
|
+
spec.test_files = Dir.glob("test/**/*.rb")
|
34
|
+
end
|
@@ -9,6 +9,8 @@ module Faraday
|
|
9
9
|
options = {}
|
10
10
|
configure_proxy(options, env)
|
11
11
|
configure_timeout(options, env)
|
12
|
+
configure_socket(options, env)
|
13
|
+
configure_ssl(options, env)
|
12
14
|
options
|
13
15
|
end
|
14
16
|
|
@@ -38,6 +40,24 @@ module Faraday
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
43
|
+
def configure_socket(options, env)
|
44
|
+
if bind = request_options(env)[:bind]
|
45
|
+
options[:bind] = {
|
46
|
+
:host => bind[:host],
|
47
|
+
:port => bind[:port]
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def configure_ssl(options, env)
|
53
|
+
if env[:url].scheme == 'https' && env[:ssl]
|
54
|
+
options[:ssl] = {
|
55
|
+
:cert_chain_file => env[:ssl][:ca_file],
|
56
|
+
:verify_peer => env[:ssl].fetch(:verify, true)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
41
61
|
def configure_timeout(options, env)
|
42
62
|
timeout, open_timeout = request_options(env).values_at(:timeout, :open_timeout)
|
43
63
|
options[:connect_timeout] = options[:inactivity_timeout] = timeout
|
@@ -108,6 +128,12 @@ module Faraday
|
|
108
128
|
else
|
109
129
|
raise Error::ConnectionFailed, err
|
110
130
|
end
|
131
|
+
rescue => err
|
132
|
+
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
133
|
+
raise Faraday::SSLError, err
|
134
|
+
else
|
135
|
+
raise
|
136
|
+
end
|
111
137
|
end
|
112
138
|
|
113
139
|
# TODO: reuse the connection to support pipelining
|
@@ -201,3 +227,11 @@ module Faraday
|
|
201
227
|
end
|
202
228
|
end
|
203
229
|
end
|
230
|
+
|
231
|
+
begin
|
232
|
+
require 'openssl'
|
233
|
+
rescue LoadError
|
234
|
+
warn "Warning: no such file to load -- openssl. Make sure it is installed if you want HTTPS support"
|
235
|
+
else
|
236
|
+
require 'faraday/adapter/em_http_ssl_patch'
|
237
|
+
end if Faraday::Adapter::EMHttp.loaded?
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'em-http'
|
3
|
+
|
4
|
+
module EmHttpSslPatch
|
5
|
+
def ssl_verify_peer(cert_string)
|
6
|
+
cert = nil
|
7
|
+
begin
|
8
|
+
cert = OpenSSL::X509::Certificate.new(cert_string)
|
9
|
+
rescue OpenSSL::X509::CertificateError
|
10
|
+
return false
|
11
|
+
end
|
12
|
+
|
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}"))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def ssl_handshake_completed
|
28
|
+
return true unless verify_peer?
|
29
|
+
|
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
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def verify_peer?
|
38
|
+
parent.connopts.tls[:verify_peer]
|
39
|
+
end
|
40
|
+
|
41
|
+
def host
|
42
|
+
parent.connopts.host
|
43
|
+
end
|
44
|
+
|
45
|
+
def certificate_store
|
46
|
+
@certificate_store ||= begin
|
47
|
+
store = OpenSSL::X509::Store.new
|
48
|
+
store.set_default_paths
|
49
|
+
ca_file = parent.connopts.tls[:cert_chain_file]
|
50
|
+
store.add_file(ca_file) if ca_file
|
51
|
+
store
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
EventMachine::HttpStubConnection.send(:include, EmHttpSslPatch)
|
@@ -19,7 +19,7 @@ module Faraday
|
|
19
19
|
|
20
20
|
def call(env)
|
21
21
|
super
|
22
|
-
request = EventMachine::HttpRequest.new(URI
|
22
|
+
request = EventMachine::HttpRequest.new(Utils::URI(env[:url].to_s), connection_config(env))
|
23
23
|
|
24
24
|
http_method = env[:method].to_s.downcase.to_sym
|
25
25
|
|
@@ -70,9 +70,9 @@ module Faraday
|
|
70
70
|
else
|
71
71
|
raise Error::ConnectionFailed, err
|
72
72
|
end
|
73
|
-
rescue
|
74
|
-
if
|
75
|
-
raise
|
73
|
+
rescue => err
|
74
|
+
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
75
|
+
raise Faraday::SSLError, err
|
76
76
|
else
|
77
77
|
raise
|
78
78
|
end
|
@@ -83,23 +83,10 @@ end
|
|
83
83
|
|
84
84
|
require 'faraday/adapter/em_synchrony/parallel_manager'
|
85
85
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
f = Fiber.current
|
94
|
-
conn = setup_request(:#{type}, options, &blk)
|
95
|
-
if conn.error.nil?
|
96
|
-
conn.callback { f.resume(conn) }
|
97
|
-
conn.errback { f.resume(conn) }
|
98
|
-
Fiber.yield
|
99
|
-
else
|
100
|
-
conn
|
101
|
-
end
|
102
|
-
end
|
103
|
-
]
|
104
|
-
end
|
105
|
-
end
|
86
|
+
begin
|
87
|
+
require 'openssl'
|
88
|
+
rescue LoadError
|
89
|
+
warn "Warning: no such file to load -- openssl. Make sure it is installed if you want HTTPS support"
|
90
|
+
else
|
91
|
+
require 'faraday/adapter/em_http_ssl_patch'
|
92
|
+
end if Faraday::Adapter::EMSynchrony.loaded?
|
@@ -3,6 +3,11 @@ module Faraday
|
|
3
3
|
class Excon < Faraday::Adapter
|
4
4
|
dependency 'excon'
|
5
5
|
|
6
|
+
def initialize(app, connection_options = {})
|
7
|
+
@connection_options = connection_options
|
8
|
+
super(app)
|
9
|
+
end
|
10
|
+
|
6
11
|
def call(env)
|
7
12
|
super
|
8
13
|
|
@@ -11,6 +16,10 @@ module Faraday
|
|
11
16
|
opts[:ssl_verify_peer] = !!ssl.fetch(:verify, true)
|
12
17
|
opts[:ssl_ca_path] = ssl[:ca_path] if ssl[:ca_path]
|
13
18
|
opts[:ssl_ca_file] = ssl[:ca_file] if ssl[:ca_file]
|
19
|
+
opts[:client_cert] = ssl[:client_cert] if ssl[:client_cert]
|
20
|
+
opts[:client_key] = ssl[:client_key] if ssl[:client_key]
|
21
|
+
opts[:certificate] = ssl[:certificate] if ssl[:certificate]
|
22
|
+
opts[:private_key] = ssl[:private_key] if ssl[:private_key]
|
14
23
|
|
15
24
|
# https://github.com/geemus/excon/issues/106
|
16
25
|
# https://github.com/jruby/jruby-ossl/issues/19
|
@@ -32,7 +41,6 @@ module Faraday
|
|
32
41
|
if req[:proxy]
|
33
42
|
opts[:proxy] = {
|
34
43
|
:host => req[:proxy][:uri].host,
|
35
|
-
:hostname => req[:proxy][:uri].hostname,
|
36
44
|
:port => req[:proxy][:uri].port,
|
37
45
|
:scheme => req[:proxy][:uri].scheme,
|
38
46
|
:user => req[:proxy][:user],
|
@@ -41,7 +49,7 @@ module Faraday
|
|
41
49
|
end
|
42
50
|
end
|
43
51
|
|
44
|
-
conn = ::Excon.new(env[:url].to_s, opts)
|
52
|
+
conn = ::Excon.new(env[:url].to_s, opts.merge(@connection_options))
|
45
53
|
|
46
54
|
resp = conn.request \
|
47
55
|
:method => env[:method].to_s.upcase,
|
@@ -54,6 +62,8 @@ module Faraday
|
|
54
62
|
rescue ::Excon::Errors::SocketError => err
|
55
63
|
if err.message =~ /\btimeout\b/
|
56
64
|
raise Error::TimeoutError, err
|
65
|
+
elsif err.message =~ /\bcertificate\b/
|
66
|
+
raise Faraday::SSLError, err
|
57
67
|
else
|
58
68
|
raise Error::ConnectionFailed, err
|
59
69
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Faraday
|
2
|
+
class Adapter
|
3
|
+
class HTTPClient < Faraday::Adapter
|
4
|
+
dependency 'httpclient'
|
5
|
+
|
6
|
+
def client
|
7
|
+
@client ||= ::HTTPClient.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
super
|
12
|
+
|
13
|
+
if req = env[:request]
|
14
|
+
if proxy = req[:proxy]
|
15
|
+
configure_proxy proxy
|
16
|
+
end
|
17
|
+
|
18
|
+
if bind = req[:bind]
|
19
|
+
configure_socket bind
|
20
|
+
end
|
21
|
+
|
22
|
+
configure_timeouts req
|
23
|
+
end
|
24
|
+
|
25
|
+
if env[:url].scheme == 'https' && ssl = env[:ssl]
|
26
|
+
configure_ssl ssl
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO Don't stream yet.
|
30
|
+
# https://github.com/nahi/httpclient/pull/90
|
31
|
+
env[:body] = env[:body].read if env[:body].respond_to? :read
|
32
|
+
|
33
|
+
resp = client.request env[:method], env[:url],
|
34
|
+
:body => env[:body],
|
35
|
+
:header => env[:request_headers]
|
36
|
+
|
37
|
+
save_response env, resp.status, resp.body, resp.headers
|
38
|
+
|
39
|
+
@app.call env
|
40
|
+
rescue ::HTTPClient::TimeoutError
|
41
|
+
raise Faraday::Error::TimeoutError, $!
|
42
|
+
rescue ::HTTPClient::BadResponseError => err
|
43
|
+
if err.message.include?('status 407')
|
44
|
+
raise Faraday::Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
|
45
|
+
else
|
46
|
+
raise Faraday::Error::ClientError, $!
|
47
|
+
end
|
48
|
+
rescue Errno::ECONNREFUSED, EOFError
|
49
|
+
raise Faraday::Error::ConnectionFailed, $!
|
50
|
+
rescue => err
|
51
|
+
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
52
|
+
raise Faraday::SSLError, err
|
53
|
+
else
|
54
|
+
raise
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def configure_socket(bind)
|
59
|
+
client.socket_local.host = bind[:host]
|
60
|
+
client.socket_local.port = bind[:port]
|
61
|
+
end
|
62
|
+
|
63
|
+
def configure_proxy(proxy)
|
64
|
+
client.proxy = proxy[:uri]
|
65
|
+
if proxy[:user] && proxy[:password]
|
66
|
+
client.set_proxy_auth proxy[:user], proxy[:password]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def configure_ssl(ssl)
|
71
|
+
ssl_config = client.ssl_config
|
72
|
+
|
73
|
+
ssl_config.add_trust_ca ssl[:ca_file] if ssl[:ca_file]
|
74
|
+
ssl_config.add_trust_ca ssl[:ca_path] if ssl[:ca_path]
|
75
|
+
ssl_config.cert_store = ssl[:cert_store] if ssl[:cert_store]
|
76
|
+
ssl_config.client_cert = ssl[:client_cert] if ssl[:client_cert]
|
77
|
+
ssl_config.client_key = ssl[:client_key] if ssl[:client_key]
|
78
|
+
ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
|
79
|
+
ssl_config.verify_mode = ssl_verify_mode(ssl)
|
80
|
+
end
|
81
|
+
|
82
|
+
def configure_timeouts(req)
|
83
|
+
if req[:timeout]
|
84
|
+
client.connect_timeout = req[:timeout]
|
85
|
+
client.receive_timeout = req[:timeout]
|
86
|
+
client.send_timeout = req[:timeout]
|
87
|
+
end
|
88
|
+
|
89
|
+
if req[:open_timeout]
|
90
|
+
client.connect_timeout = req[:open_timeout]
|
91
|
+
client.send_timeout = req[:open_timeout]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def ssl_verify_mode(ssl)
|
96
|
+
ssl[:verify_mode] || begin
|
97
|
+
if ssl.fetch(:verify, true)
|
98
|
+
OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
99
|
+
else
|
100
|
+
OpenSSL::SSL::VERIFY_NONE
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -13,9 +13,10 @@ module Faraday
|
|
13
13
|
EOFError,
|
14
14
|
Errno::ECONNABORTED,
|
15
15
|
Errno::ECONNREFUSED,
|
16
|
-
Errno::ENETUNREACH,
|
17
16
|
Errno::ECONNRESET,
|
17
|
+
Errno::EHOSTUNREACH,
|
18
18
|
Errno::EINVAL,
|
19
|
+
Errno::ENETUNREACH,
|
19
20
|
Net::HTTPBadResponse,
|
20
21
|
Net::HTTPHeaderSyntaxError,
|
21
22
|
Net::ProtocolError,
|
@@ -24,7 +25,6 @@ module Faraday
|
|
24
25
|
]
|
25
26
|
|
26
27
|
NET_HTTP_EXCEPTIONS << OpenSSL::SSL::SSLError if defined?(OpenSSL)
|
27
|
-
NET_HTTP_EXCEPTIONS << Net::OpenTimeout if defined?(Net::OpenTimeout)
|
28
28
|
|
29
29
|
def call(env)
|
30
30
|
super
|
@@ -37,11 +37,15 @@ module Faraday
|
|
37
37
|
|
38
38
|
begin
|
39
39
|
http_response = perform_request(http, env)
|
40
|
-
rescue *NET_HTTP_EXCEPTIONS
|
41
|
-
|
40
|
+
rescue *NET_HTTP_EXCEPTIONS => err
|
41
|
+
if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
|
42
|
+
raise Faraday::SSLError, err
|
43
|
+
else
|
44
|
+
raise Error::ConnectionFailed, err
|
45
|
+
end
|
42
46
|
end
|
43
47
|
|
44
|
-
save_response(env, http_response.code.to_i, http_response.body) do |response_headers|
|
48
|
+
save_response(env, http_response.code.to_i, http_response.body || '') do |response_headers|
|
45
49
|
http_response.each_header do |key, value|
|
46
50
|
response_headers[key] = value
|
47
51
|
end
|
@@ -82,7 +86,7 @@ module Faraday
|
|
82
86
|
Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password])
|
83
87
|
else
|
84
88
|
Net::HTTP
|
85
|
-
end.new(env[:url].host, env[:url].port
|
89
|
+
end.new(env[:url].host, env[:url].port)
|
86
90
|
end
|
87
91
|
|
88
92
|
def configure_ssl(http, ssl)
|
@@ -52,14 +52,8 @@ module Faraday
|
|
52
52
|
# HAX: helps but doesn't work completely
|
53
53
|
# https://github.com/toland/patron/issues/34
|
54
54
|
::Patron::Request::VALID_ACTIONS.tap do |actions|
|
55
|
-
|
56
|
-
|
57
|
-
actions << :options unless actions.include? :options
|
58
|
-
else
|
59
|
-
# Patron 0.4.20 and up
|
60
|
-
actions << "PATCH" unless actions.include? "PATCH"
|
61
|
-
actions << "OPTIONS" unless actions.include? "OPTIONS"
|
62
|
-
end
|
55
|
+
actions << :patch unless actions.include? :patch
|
56
|
+
actions << :options unless actions.include? :options
|
63
57
|
end
|
64
58
|
end
|
65
59
|
|