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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 1c31dbb021fc6a43b4f0b102a9a3ccf52a72303a
4
- data.tar.gz: 54da868027777adb5a21145bd6433b0154af2297
2
+ SHA256:
3
+ metadata.gz: 010e4dd27187eb834e8a0c185cab419a1b69c6e3f8a5728f6681109b7848091d
4
+ data.tar.gz: ccd678f8acf84929c15a19b7a6ca1b22b2d634eabfae21c84c4a0f0ba97fb8b6
5
5
  SHA512:
6
- metadata.gz: 22c1c286687ca596bd1d6b7d9a6a3749731f6d8962a5bbbe7e1e39cf22e364b92010ae44446cf1804ba10567a2e6409cc2be537375d9f47ace9bca909196dcd3
7
- data.tar.gz: 7e8116cdeea918b8e7de661ec6d49d839960e26f136903e53db62e8cc353f89b3ac053d5efe6401995129418ae4dfce8fda9c8a471093223dca08002615d10e1
6
+ metadata.gz: 150271b18c60bf5b55cc7e74f39fb01d6c83eecc39119d425fe8d399829ba728183900a5a948dbb874f432fc95996b88c367e87b5274b45addbd15d6175d7bc0
7
+ data.tar.gz: 3f4ef0b5d787aeffef29d79af04297a62a6b1ae77f034858b7d68ac4bdcfc00734c976cb8dff8b76b0af007590c6f4a5376797c14d3798cc13193aed96689d0c
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2013 Rick Olson, Zack Hobson
1
+ Copyright (c) 2009-2019 Rick Olson, Zack Hobson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,200 +1,32 @@
1
- # Faraday
1
+ # ![Faraday](./docs/assets/img/repo-card-slim.png)
2
2
 
3
- Faraday is an HTTP client lib that provides a common interface over many
4
- adapters (such as Net::HTTP) and embraces the concept of Rack middleware when
5
- processing the request/response cycle.
6
-
7
- Faraday supports these adapters:
8
-
9
- * Net::HTTP
10
- * [Excon][]
11
- * [Typhoeus][]
12
- * [Patron][]
13
- * [EventMachine][]
14
- * [HTTPClient][]
15
-
16
- It also includes a Rack adapter for hitting loaded Rack applications through
17
- Rack::Test, and a Test adapter for stubbing requests by hand.
18
-
19
- ## Usage
20
-
21
- ```ruby
22
- conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
23
- faraday.request :url_encoded # form-encode POST params
24
- faraday.response :logger # log requests to STDOUT
25
- faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
26
- end
27
-
28
- ## GET ##
29
-
30
- response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
31
- response.body
32
-
33
- conn.get '/nigiri', { :name => 'Maguro' } # GET http://sushi.com/nigiri?name=Maguro
34
-
35
- conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
36
- req.url '/search', :page => 2
37
- req.params['limit'] = 100
38
- end
39
-
40
- ## POST ##
41
-
42
- conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri
43
-
44
- # post payload as JSON instead of "www-form-urlencoded" encoding:
45
- conn.post do |req|
46
- req.url '/nigiri'
47
- req.headers['Content-Type'] = 'application/json'
48
- req.body = '{ "name": "Unagi" }'
49
- end
50
-
51
- ## Per-request options ##
52
-
53
- conn.get do |req|
54
- req.url '/search'
55
- req.options.timeout = 5 # open/read timeout in seconds
56
- req.options.open_timeout = 2 # connection open timeout in seconds
57
- end
58
- ```
59
-
60
- If you don't need to set up anything, you can roll with just the default middleware
61
- stack and default adapter (see [Faraday::RackBuilder#initialize](https://github.com/lostisland/faraday/blob/master/lib/faraday/rack_builder.rb)):
62
-
63
- ```ruby
64
- response = Faraday.get 'http://sushi.com/nigiri/sake.json'
65
- ```
66
-
67
- ## Advanced middleware usage
68
-
69
- The order in which middleware is stacked is important. Like with Rack, the
70
- first middleware on the list wraps all others, while the last middleware is the
71
- innermost one, so that must be the adapter.
72
-
73
- ```ruby
74
- Faraday.new(...) do |conn|
75
- # POST/PUT params encoders:
76
- conn.request :multipart
77
- conn.request :url_encoded
78
-
79
- conn.adapter :net_http
80
- end
81
- ```
3
+ [![Gem Version](https://badge.fury.io/rb/faraday.svg)](https://rubygems.org/gems/faraday)
4
+ [![CircleCI](https://circleci.com/gh/lostisland/faraday/tree/master.svg?style=svg)](https://circleci.com/gh/lostisland/faraday/tree/master)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/f869daab091ceef1da73/test_coverage)](https://codeclimate.com/github/lostisland/faraday/test_coverage)
6
+ [![Maintainability](https://api.codeclimate.com/v1/badges/f869daab091ceef1da73/maintainability)](https://codeclimate.com/github/lostisland/faraday/maintainability)
7
+ [![Gitter](https://badges.gitter.im/lostisland/faraday.svg)](https://gitter.im/lostisland/faraday?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
82
8
 
83
- This request middleware setup affects POST/PUT requests in the following way:
84
9
 
85
- 1. `Request::Multipart` checks for files in the payload, otherwise leaves
86
- everything untouched;
87
- 2. `Request::UrlEncoded` encodes as "application/x-www-form-urlencoded" if not
88
- already encoded or of another type
89
-
90
- Swapping middleware means giving the other priority. Specifying the
91
- "Content-Type" for the request is explicitly stating which middleware should
92
- process it.
93
-
94
- Examples:
95
-
96
- ```ruby
97
- # uploading a file:
98
- payload[:profile_pic] = Faraday::UploadIO.new('/path/to/avatar.jpg', 'image/jpeg')
99
-
100
- # "Multipart" middleware detects files and encodes with "multipart/form-data":
101
- conn.put '/profile', payload
102
- ```
103
-
104
- ## Writing middleware
105
-
106
- Middleware are classes that implement a `call` instance method. They hook into
107
- the request/response cycle.
108
-
109
- ```ruby
110
- def call(request_env)
111
- # do something with the request
112
- # request_env[:request_headers].merge!(...)
113
-
114
- @app.call(request_env).on_complete do |response_env|
115
- # do something with the response
116
- # response_env[:response_headers].merge!(...)
117
- end
118
- end
119
- ```
120
-
121
- It's important to do all processing of the response only in the `on_complete`
122
- block. This enables middleware to work in parallel mode where requests are
123
- asynchronous.
124
-
125
- The `env` is a hash with symbol keys that contains info about the request and,
126
- later, response. Some keys are:
127
-
128
- ```
129
- # request phase
130
- :method - :get, :post, ...
131
- :url - URI for the current request; also contains GET parameters
132
- :body - POST parameters for :post/:put requests
133
- :request_headers
134
-
135
- # response phase
136
- :status - HTTP response status code, such as 200
137
- :body - the response body
138
- :response_headers
139
- ```
140
-
141
- ## Using Faraday for testing
142
-
143
- ```ruby
144
- # It's possible to define stubbed request outside a test adapter block.
145
- stubs = Faraday::Adapter::Test::Stubs.new do |stub|
146
- stub.get('/tamago') { |env| [200, {}, 'egg'] }
147
- end
148
-
149
- # You can pass stubbed request to the test adapter or define them in a block
150
- # or a combination of the two.
151
- test = Faraday.new do |builder|
152
- builder.adapter :test, stubs do |stub|
153
- stub.get('/ebi') { |env| [ 200, {}, 'shrimp' ]}
154
- end
155
- end
156
-
157
- # It's also possible to stub additional requests after the connection has
158
- # been initialized. This is useful for testing.
159
- stubs.get('/uni') { |env| [ 200, {}, 'urchin' ]}
160
-
161
- resp = test.get '/tamago'
162
- resp.body # => 'egg'
163
- resp = test.get '/ebi'
164
- resp.body # => 'shrimp'
165
- resp = test.get '/uni'
166
- resp.body # => 'urchin'
167
- resp = test.get '/else' #=> raises "no such stub" error
168
-
169
- # If you like, you can treat your stubs as mocks by verifying that all of
170
- # the stubbed calls were made. NOTE that this feature is still fairly
171
- # experimental: It will not verify the order or count of any stub, only that
172
- # it was called once during the course of the test.
173
- stubs.verify_stubbed_calls
174
- ```
10
+ Faraday is an HTTP client library that provides a common interface over many
11
+ adapters (such as Net::HTTP) and embraces the concept of Rack middleware when
12
+ processing the request/response cycle.
175
13
 
176
- ## TODO
14
+ ## Getting Started
177
15
 
178
- * support streaming requests/responses
179
- * better stubbing API
16
+ The best starting point is the [Faraday Website][website], with its introduction and explanation.
17
+ Need more details? See the [Faraday API Documentation][apidoc] to see how it works internally.
180
18
 
181
19
  ## Supported Ruby versions
182
20
 
183
- This library aims to support and is [tested against][travis] the following Ruby
21
+ This library aims to support and is [tested against][circle_ci] the following Ruby
184
22
  implementations:
185
23
 
186
- * MRI 1.8.7
187
- * MRI 1.9.2
188
- * MRI 1.9.3
189
- * MRI 2.0.0
190
- * MRI 2.1.0
191
- * [JRuby][]
192
- * [Rubinius][]
24
+ * Ruby 2.3+
193
25
 
194
26
  If something doesn't work on one of these Ruby versions, it's a bug.
195
27
 
196
28
  This library may inadvertently work (or seem to work) on other Ruby
197
- implementations, however support will only be provided for the versions listed
29
+ implementations and versions, however support will only be provided for the versions listed
198
30
  above.
199
31
 
200
32
  If you would like this library to support another Ruby version, you may
@@ -204,17 +36,20 @@ implementation, you will be responsible for providing patches in a timely
204
36
  fashion. If critical issues for a particular implementation exist at the time
205
37
  of a major release, support for that Ruby version may be dropped.
206
38
 
207
- ## Copyright
39
+ ## Contribute
208
40
 
209
- Copyright (c) 2009-2013 [Rick Olson](mailto:technoweenie@gmail.com), Zack Hobson.
210
- See [LICENSE][] for details.
41
+ Do you want to contribute to Faraday?
42
+ Open the issues page and check for the `help wanted` label!
43
+ But before you start coding, please read our [Contributing Guide][contributing]
211
44
 
212
- [travis]: http://travis-ci.org/lostisland/faraday
213
- [excon]: https://github.com/geemus/excon#readme
214
- [typhoeus]: https://github.com/typhoeus/typhoeus#readme
215
- [patron]: http://toland.github.com/patron/
216
- [eventmachine]: https://github.com/igrigorik/em-http-request#readme
217
- [httpclient]: https://github.com/nahi/httpclient
218
- [jruby]: http://jruby.org/
219
- [rubinius]: http://rubini.us/
220
- [license]: LICENSE.md
45
+ ## Copyright
46
+ © 2009 - 2019, the [Faraday Team][faraday_team]. Website and branding design by [Elena Lo Piccolo](https://elelopic.design).
47
+
48
+ [website]: https://lostisland.github.io/faraday
49
+ [faraday_team]: https://lostisland.github.io/faraday/team
50
+ [contributing]: https://github.com/lostisland/faraday/blob/master/.github/CONTRIBUTING.md
51
+ [apidoc]: http://www.rubydoc.info/gems/faraday
52
+ [circle_ci]: https://circleci.com/gh/lostisland/faraday
53
+ [jruby]: http://jruby.org/
54
+ [rubinius]: http://rubini.us/
55
+ [license]: LICENSE.md
@@ -1,10 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # EventMachine adapter is useful for either asynchronous requests
4
- # when in EM reactor loop or for making parallel requests in
5
+ # EventMachine adapter. This adapter is useful for either asynchronous
6
+ # requests when in an EM reactor loop, or for making parallel requests in
5
7
  # synchronous code.
6
8
  class EMHttp < Faraday::Adapter
9
+ # Options is a module containing helpers to convert the Faraday env object
10
+ # into options hashes for EMHTTP method calls.
7
11
  module Options
12
+ # @return [Hash]
8
13
  def connection_config(env)
9
14
  options = {}
10
15
  configure_proxy(options, env)
@@ -16,10 +21,10 @@ module Faraday
16
21
 
17
22
  def request_config(env)
18
23
  options = {
19
- :body => read_body(env),
20
- :head => env[:request_headers],
21
- # :keepalive => true,
22
- # :file => 'path/to/file', # stream data off disk
24
+ body: read_body(env),
25
+ head: env[:request_headers]
26
+ # keepalive: true,
27
+ # file: 'path/to/file', # stream data off disk
23
28
  }
24
29
  configure_compression(options, env)
25
30
  options
@@ -30,44 +35,53 @@ module Faraday
30
35
  body.respond_to?(:read) ? body.read : body
31
36
  end
32
37
 
38
+ # Reads out proxy settings from env into options
33
39
  def configure_proxy(options, env)
34
- if proxy = request_options(env)[:proxy]
35
- options[:proxy] = {
36
- :host => proxy[:uri].host,
37
- :port => proxy[:uri].port,
38
- :authorization => [proxy[:user], proxy[:password]]
39
- }
40
- end
40
+ proxy = request_options(env)[:proxy]
41
+ return unless proxy
42
+
43
+ options[:proxy] = {
44
+ host: proxy[:uri].host,
45
+ port: proxy[:uri].port,
46
+ authorization: [proxy[:user], proxy[:password]]
47
+ }
41
48
  end
42
49
 
50
+ # Reads out host and port settings from env into options
43
51
  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
52
+ bind = request_options(env)[:bind]
53
+ return unless bind
54
+
55
+ options[:bind] = {
56
+ host: bind[:host],
57
+ port: bind[:port]
58
+ }
50
59
  end
51
60
 
61
+ # Reads out SSL certificate settings from env into options
52
62
  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
63
+ return unless env[:url].scheme == 'https' && env[:ssl]
64
+
65
+ options[:ssl] = {
66
+ cert_chain_file: env[:ssl][:ca_file],
67
+ verify_peer: env[:ssl].fetch(:verify, true)
68
+ }
59
69
  end
60
70
 
71
+ # Reads out timeout settings from env into options
61
72
  def configure_timeout(options, env)
62
- timeout, open_timeout = request_options(env).values_at(:timeout, :open_timeout)
73
+ timeout, open_timeout = request_options(env)
74
+ .values_at(:timeout, :open_timeout)
63
75
  options[:connect_timeout] = options[:inactivity_timeout] = timeout
64
76
  options[:connect_timeout] = open_timeout if open_timeout
65
77
  end
66
78
 
79
+ # Reads out compression header settings from env into options
67
80
  def configure_compression(options, env)
68
- if env[:method] == :get and not options[:head].key? 'accept-encoding'
69
- options[:head]['accept-encoding'] = 'gzip, compressed'
70
- end
81
+ return unless (env[:method] == :get) &&
82
+ !options[:head].key?('accept-encoding')
83
+
84
+ options[:head]['accept-encoding'] = 'gzip, compressed'
71
85
  end
72
86
 
73
87
  def request_options(env)
@@ -81,7 +95,8 @@ module Faraday
81
95
 
82
96
  self.supports_parallel = true
83
97
 
84
- def self.setup_parallel_manager(options = nil)
98
+ # @return [Manager]
99
+ def self.setup_parallel_manager(_options = nil)
85
100
  Manager.new
86
101
  end
87
102
 
@@ -94,89 +109,113 @@ module Faraday
94
109
  def perform_request(env)
95
110
  if parallel?(env)
96
111
  manager = env[:parallel_manager]
97
- manager.add {
98
- perform_single_request(env).
99
- callback { env[:response].finish(env) }
100
- }
101
- else
102
- unless EventMachine.reactor_running?
103
- error = nil
104
- # start EM, block until request is completed
105
- EventMachine.run do
106
- perform_single_request(env).
107
- callback { EventMachine.stop }.
108
- errback { |client|
109
- error = error_message(client)
110
- EventMachine.stop
111
- }
112
+ manager.add do
113
+ perform_single_request(env)
114
+ .callback { env[:response].finish(env) }
115
+ end
116
+ elsif EventMachine.reactor_running?
117
+ # EM is running: instruct upstream that this is an async request
118
+ env[:parallel_manager] = true
119
+ perform_single_request(env)
120
+ .callback { env[:response].finish(env) }
121
+ .errback do
122
+ # TODO: no way to communicate the error in async mode
123
+ raise NotImplementedError
112
124
  end
113
- raise_error(error) if error
114
- else
115
- # EM is running: instruct upstream that this is an async request
116
- env[:parallel_manager] = true
117
- perform_single_request(env).
118
- callback { env[:response].finish(env) }.
119
- errback {
120
- # TODO: no way to communicate the error in async mode
121
- raise NotImplementedError
122
- }
125
+ else
126
+ error = nil
127
+ # start EM, block until request is completed
128
+ EventMachine.run do
129
+ perform_single_request(env)
130
+ .callback { EventMachine.stop }
131
+ .errback do |client|
132
+ error = error_message(client)
133
+ EventMachine.stop
134
+ end
123
135
  end
136
+ raise_error(error) if error
124
137
  end
125
- rescue EventMachine::Connectify::CONNECTError => err
126
- if err.message.include?("Proxy Authentication Required")
127
- raise Error::ConnectionFailed, %{407 "Proxy Authentication Required "}
128
- else
129
- raise Error::ConnectionFailed, err
138
+ rescue EventMachine::Connectify::CONNECTError => e
139
+ if e.message.include?('Proxy Authentication Required')
140
+ raise Faraday::ConnectionFailed,
141
+ %(407 "Proxy Authentication Required ")
130
142
  end
131
- rescue => err
132
- if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
133
- raise Faraday::SSLError, err
134
- else
135
- raise
143
+
144
+ raise Faraday::ConnectionFailed, e
145
+ rescue StandardError => e
146
+ if defined?(OpenSSL) && e.is_a?(OpenSSL::SSL::SSLError)
147
+ raise Faraday::SSLError, e
136
148
  end
149
+
150
+ raise
137
151
  end
138
152
 
139
153
  # TODO: reuse the connection to support pipelining
140
154
  def perform_single_request(env)
141
- req = EventMachine::HttpRequest.new(env[:url], connection_config(env))
142
- req.setup_request(env[:method], request_config(env)).callback { |client|
143
- save_response(env, client.response_header.status, client.response) do |resp_headers|
155
+ req = create_request(env)
156
+ req = req.setup_request(env[:method], request_config(env))
157
+ req.callback do |client|
158
+ if env[:request].stream_response?
159
+ warn "Streaming downloads for #{self.class.name} " \
160
+ 'are not yet implemented.'
161
+ env[:request].on_data.call(
162
+ client.response,
163
+ client.response.bytesize
164
+ )
165
+ end
166
+ status = client.response_header.status
167
+ reason = client.response_header.http_reason
168
+ save_response(env, status, client.response, nil, reason) do |headers|
144
169
  client.response_header.each do |name, value|
145
- resp_headers[name.to_sym] = value
170
+ headers[name.to_sym] = value
146
171
  end
147
172
  end
148
- }
173
+ end
174
+ end
175
+
176
+ def create_request(env)
177
+ EventMachine::HttpRequest.new(
178
+ env[:url], connection_config(env).merge(@connection_options)
179
+ )
149
180
  end
150
181
 
151
182
  def error_message(client)
152
- client.error or "request failed"
183
+ client.error || 'request failed'
153
184
  end
154
185
 
155
186
  def raise_error(msg)
156
- errklass = Faraday::Error::ClientError
157
- if msg == Errno::ETIMEDOUT
158
- errklass = Faraday::Error::TimeoutError
159
- msg = "request timed out"
187
+ error_class = Faraday::ClientError
188
+ if timeout_message?(msg)
189
+ error_class = Faraday::TimeoutError
190
+ msg = 'request timed out'
160
191
  elsif msg == Errno::ECONNREFUSED
161
- errklass = Faraday::Error::ConnectionFailed
162
- msg = "connection refused"
163
- elsif msg == "connection closed by server"
164
- errklass = Faraday::Error::ConnectionFailed
192
+ error_class = Faraday::ConnectionFailed
193
+ msg = 'connection refused'
194
+ elsif msg == 'connection closed by server'
195
+ error_class = Faraday::ConnectionFailed
165
196
  end
166
- raise errklass, msg
197
+ raise error_class, msg
167
198
  end
168
199
 
200
+ def timeout_message?(msg)
201
+ msg == Errno::ETIMEDOUT ||
202
+ (msg.is_a?(String) && msg.include?('timeout error'))
203
+ end
204
+
205
+ # @return [Boolean]
169
206
  def parallel?(env)
170
207
  !!env[:parallel_manager]
171
208
  end
172
209
 
173
- # The parallel manager is designed to start an EventMachine loop
210
+ # This parallel manager is designed to start an EventMachine loop
174
211
  # and block until all registered requests have been completed.
175
212
  class Manager
213
+ # @see reset
176
214
  def initialize
177
215
  reset
178
216
  end
179
217
 
218
+ # Re-initializes instance variables
180
219
  def reset
181
220
  @registered_procs = []
182
221
  @num_registered = 0
@@ -185,27 +224,30 @@ module Faraday
185
224
  @running = false
186
225
  end
187
226
 
188
- def running?() @running end
227
+ # @return [Boolean]
228
+ def running?
229
+ @running
230
+ end
189
231
 
190
- def add
232
+ def add(&block)
191
233
  if running?
192
234
  perform_request { yield }
193
235
  else
194
- @registered_procs << Proc.new
236
+ @registered_procs << block
195
237
  end
196
238
  @num_registered += 1
197
239
  end
198
240
 
199
241
  def run
200
- if @num_registered > 0
242
+ if @num_registered.positive?
201
243
  @running = true
202
244
  EventMachine.run do
203
245
  @registered_procs.each do |proc|
204
246
  perform_request(&proc)
205
247
  end
206
248
  end
207
- if @errors.size > 0
208
- raise Faraday::Error::ClientError, @errors.first || "connection failed"
249
+ unless @errors.empty?
250
+ raise Faraday::ClientError, @errors.first || 'connection failed'
209
251
  end
210
252
  end
211
253
  ensure
@@ -214,24 +256,31 @@ module Faraday
214
256
 
215
257
  def perform_request
216
258
  client = yield
217
- client.callback { @num_succeeded += 1; check_finished }
218
- client.errback { @errors << client.error; check_finished }
259
+ client.callback do
260
+ @num_succeeded += 1
261
+ check_finished
262
+ end
263
+ client.errback do
264
+ @errors << client.error
265
+ check_finished
266
+ end
219
267
  end
220
268
 
221
269
  def check_finished
222
- if @num_succeeded + @errors.size == @num_registered
223
- EventMachine.stop
224
- end
270
+ EventMachine.stop if @num_succeeded + @errors.size == @num_registered
225
271
  end
226
272
  end
227
273
  end
228
274
  end
229
275
  end
230
276
 
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?
277
+ if Faraday::Adapter::EMHttp.loaded?
278
+ begin
279
+ require 'openssl'
280
+ rescue LoadError
281
+ warn 'Warning: no such file to load -- openssl. ' \
282
+ 'Make sure it is installed if you want HTTPS support'
283
+ else
284
+ require 'faraday/adapter/em_http_ssl_patch'
285
+ end
286
+ end