faraday 0.9.1 → 0.12.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 (71) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +141 -21
  4. data/lib/faraday/adapter/em_http.rb +8 -2
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +1 -1
  6. data/lib/faraday/adapter/em_synchrony.rb +16 -2
  7. data/lib/faraday/adapter/excon.rb +7 -7
  8. data/lib/faraday/adapter/httpclient.rb +27 -5
  9. data/lib/faraday/adapter/net_http.rb +13 -8
  10. data/lib/faraday/adapter/net_http_persistent.rb +6 -4
  11. data/lib/faraday/adapter/patron.rb +13 -9
  12. data/lib/faraday/adapter/test.rb +64 -21
  13. data/lib/faraday/adapter.rb +8 -1
  14. data/lib/faraday/connection.rb +36 -13
  15. data/lib/faraday/error.rb +11 -1
  16. data/lib/faraday/options.rb +38 -16
  17. data/lib/faraday/parameters.rb +54 -38
  18. data/lib/faraday/rack_builder.rb +3 -2
  19. data/lib/faraday/request/authorization.rb +1 -2
  20. data/lib/faraday/request/multipart.rb +7 -2
  21. data/lib/faraday/request/retry.rb +20 -5
  22. data/lib/faraday/request.rb +2 -0
  23. data/lib/faraday/response/logger.rb +27 -6
  24. data/lib/faraday/response.rb +6 -2
  25. data/lib/faraday/utils.rb +22 -2
  26. data/lib/faraday.rb +9 -34
  27. metadata +7 -93
  28. data/.document +0 -6
  29. data/CHANGELOG.md +0 -20
  30. data/CONTRIBUTING.md +0 -36
  31. data/Gemfile +0 -25
  32. data/Rakefile +0 -71
  33. data/faraday.gemspec +0 -34
  34. data/script/cached-bundle +0 -46
  35. data/script/console +0 -7
  36. data/script/generate_certs +0 -42
  37. data/script/package +0 -7
  38. data/script/proxy-server +0 -42
  39. data/script/release +0 -17
  40. data/script/s3-put +0 -71
  41. data/script/server +0 -36
  42. data/script/test +0 -172
  43. data/test/adapters/default_test.rb +0 -14
  44. data/test/adapters/em_http_test.rb +0 -20
  45. data/test/adapters/em_synchrony_test.rb +0 -20
  46. data/test/adapters/excon_test.rb +0 -20
  47. data/test/adapters/httpclient_test.rb +0 -21
  48. data/test/adapters/integration.rb +0 -254
  49. data/test/adapters/logger_test.rb +0 -82
  50. data/test/adapters/net_http_persistent_test.rb +0 -20
  51. data/test/adapters/net_http_test.rb +0 -14
  52. data/test/adapters/patron_test.rb +0 -20
  53. data/test/adapters/rack_test.rb +0 -31
  54. data/test/adapters/test_middleware_test.rb +0 -114
  55. data/test/adapters/typhoeus_test.rb +0 -28
  56. data/test/authentication_middleware_test.rb +0 -65
  57. data/test/composite_read_io_test.rb +0 -111
  58. data/test/connection_test.rb +0 -522
  59. data/test/env_test.rb +0 -218
  60. data/test/helper.rb +0 -81
  61. data/test/live_server.rb +0 -67
  62. data/test/middleware/instrumentation_test.rb +0 -88
  63. data/test/middleware/retry_test.rb +0 -177
  64. data/test/middleware_stack_test.rb +0 -173
  65. data/test/multibyte.txt +0 -1
  66. data/test/options_test.rb +0 -252
  67. data/test/parameters_test.rb +0 -64
  68. data/test/request_middleware_test.rb +0 -142
  69. data/test/response_middleware_test.rb +0 -72
  70. data/test/strawberry.rb +0 -2
  71. data/test/utils_test.rb +0 -58
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c31dbb021fc6a43b4f0b102a9a3ccf52a72303a
4
- data.tar.gz: 54da868027777adb5a21145bd6433b0154af2297
3
+ metadata.gz: d6ed59b880f0d605e4efc8ce513ced0b4688c4ef
4
+ data.tar.gz: 21d3a0326416db1e19add553b8d5c0ef1c5a3b50
5
5
  SHA512:
6
- metadata.gz: 22c1c286687ca596bd1d6b7d9a6a3749731f6d8962a5bbbe7e1e39cf22e364b92010ae44446cf1804ba10567a2e6409cc2be537375d9f47ace9bca909196dcd3
7
- data.tar.gz: 7e8116cdeea918b8e7de661ec6d49d839960e26f136903e53db62e8cc353f89b3ac053d5efe6401995129418ae4dfce8fda9c8a471093223dca08002615d10e1
6
+ metadata.gz: 9e882a5072cc36a986e8fc2f23f0563755bae2d0c4e6fed4adc51a6fd46b449ea6be3dd189662ea0aa4f427c5402969bfb0ad626c837e9bad68d06aa0a3cc6d3
7
+ data.tar.gz: 63856c35cbcceda6abeb3dc076574d7e880343e8ee7af5e80971c08637a647a079433b1220161c24871d3718c268d018ebdce009ca46d89c4da7c059fdaeaf72
data/LICENSE.md CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2013 Rick Olson, Zack Hobson
1
+ Copyright (c) 2009-2015 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,14 +1,19 @@
1
1
  # Faraday
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/faraday.svg)](https://rubygems.org/gems/faraday)
4
+ [![Build Status](https://travis-ci.org/lostisland/faraday.svg)](https://travis-ci.org/lostisland/faraday)
5
+ [![Gitter](https://badges.gitter.im/lostisland/faraday.svg)](https://gitter.im/lostisland/faraday?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
6
+
7
+
3
8
  Faraday is an HTTP client lib that provides a common interface over many
4
9
  adapters (such as Net::HTTP) and embraces the concept of Rack middleware when
5
10
  processing the request/response cycle.
6
11
 
7
12
  Faraday supports these adapters:
8
13
 
9
- * Net::HTTP
14
+ * [Net::HTTP][net_http] _(default)_
15
+ * [Net::HTTP::Persistent][persistent]
10
16
  * [Excon][]
11
- * [Typhoeus][]
12
17
  * [Patron][]
13
18
  * [EventMachine][]
14
19
  * [HTTPClient][]
@@ -16,8 +21,29 @@ Faraday supports these adapters:
16
21
  It also includes a Rack adapter for hitting loaded Rack applications through
17
22
  Rack::Test, and a Test adapter for stubbing requests by hand.
18
23
 
24
+ ## API documentation
25
+
26
+ Available at [rubydoc.info](http://www.rubydoc.info/gems/faraday).
27
+
19
28
  ## Usage
20
29
 
30
+ ### Basic Use
31
+
32
+ ```ruby
33
+ response = Faraday.get 'http://sushi.com/nigiri/sake.json'
34
+ ```
35
+ A simple `get` request can be performed by using the syntax described above. This works if you don't need to set up anything; you can roll with just the default middleware
36
+ stack and default adapter (see [Faraday::RackBuilder#initialize](https://github.com/lostisland/faraday/blob/master/lib/faraday/rack_builder.rb)).
37
+
38
+ A more flexible way to use Faraday is to start with a Connection object. If you want to keep the same defaults, you can use this syntax:
39
+
40
+ ```ruby
41
+ conn = Faraday.new(:url => 'http://www.example.com')
42
+ response = conn.get '/users' # GET http://www.example.com/users'
43
+ ```
44
+
45
+ Connections can also take an options hash as a parameter or be configured by using a block. Checkout the section called [Advanced middleware usage](#advanced-middleware-usage) for more details about how to use this block for configurations.
46
+
21
47
  ```ruby
22
48
  conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
23
49
  faraday.request :url_encoded # form-encode POST params
@@ -25,6 +51,19 @@ conn = Faraday.new(:url => 'http://sushi.com') do |faraday|
25
51
  faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
26
52
  end
27
53
 
54
+ # Filter sensitive information from logs with a regex matcher
55
+
56
+ conn = Faraday.new(:url => 'http://sushi.com/api_key=s3cr3t') do |faraday|
57
+ faraday.response :logger do | logger |
58
+ logger.filter(/(api_key=)(\w+)/,'\1[REMOVED]')
59
+ end
60
+ faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
61
+ end
62
+ ```
63
+
64
+ Once you have the connection object, use it to make HTTP requests. You can pass paramters to it in a few different ways:
65
+
66
+ ```ruby
28
67
  ## GET ##
29
68
 
30
69
  response = conn.get '/nigiri/sake.json' # GET http://sushi.com/nigiri/sake.json
@@ -32,7 +71,7 @@ response.body
32
71
 
33
72
  conn.get '/nigiri', { :name => 'Maguro' } # GET http://sushi.com/nigiri?name=Maguro
34
73
 
35
- conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
74
+ conn.get do |req| # GET http://sushi.com/search?page=2&limit=100
36
75
  req.url '/search', :page => 2
37
76
  req.params['limit'] = 100
38
77
  end
@@ -40,7 +79,11 @@ end
40
79
  ## POST ##
41
80
 
42
81
  conn.post '/nigiri', { :name => 'Maguro' } # POST "name=maguro" to http://sushi.com/nigiri
82
+ ```
83
+
84
+ Some configuration options can be adjusted per request:
43
85
 
86
+ ```ruby
44
87
  # post payload as JSON instead of "www-form-urlencoded" encoding:
45
88
  conn.post do |req|
46
89
  req.url '/nigiri'
@@ -57,13 +100,46 @@ conn.get do |req|
57
100
  end
58
101
  ```
59
102
 
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)):
103
+ And you can inject arbitrary data into the request using the `context` option:
62
104
 
63
105
  ```ruby
64
- response = Faraday.get 'http://sushi.com/nigiri/sake.json'
106
+ # Anything you inject using context option will be available in the env on all middlewares
107
+
108
+ conn.get do |req|
109
+ req.url '/search'
110
+ req.options.context = {
111
+ foo: 'foo',
112
+ bar: 'bar'
113
+ }
114
+ end
115
+ ```
116
+
117
+ ### Changing how parameters are serialized
118
+
119
+ Sometimes you need to send the same URL parameter multiple times with different
120
+ values. This requires manually setting the parameter encoder and can be done on
121
+ either per-connection or per-request basis.
122
+
123
+ ```ruby
124
+ # per-connection setting
125
+ conn = Faraday.new :request => { :params_encoder => Faraday::FlatParamsEncoder }
126
+
127
+ conn.get do |req|
128
+ # per-request setting:
129
+ # req.options.params_encoder = my_encoder
130
+ req.params['roll'] = ['california', 'philadelphia']
131
+ end
132
+ # GET 'http://sushi.com?roll=california&roll=philadelphia'
65
133
  ```
66
134
 
135
+ The value of Faraday `params_encoder` can be any object that responds to:
136
+
137
+ * `encode(hash) #=> String`
138
+ * `decode(string) #=> Hash`
139
+
140
+ The encoder will affect both how query strings are processed and how POST bodies
141
+ get serialized. The default encoder is Faraday::NestedParamsEncoder.
142
+
67
143
  ## Advanced middleware usage
68
144
 
69
145
  The order in which middleware is stacked is important. Like with Rack, the
@@ -138,6 +214,53 @@ later, response. Some keys are:
138
214
  :response_headers
139
215
  ```
140
216
 
217
+ ## Ad-hoc adapters customization
218
+
219
+ Faraday is intended to be a generic interface between your code and the adapter. However, sometimes you need to access a feature specific to one of the adapters that is not covered in Faraday's interface.
220
+
221
+ When that happens, you can pass a block when specifying the adapter to customize it. The block parameter will change based on the adapter you're using. See below for some examples.
222
+
223
+ ### NetHttp
224
+ ```ruby
225
+ conn = Faraday.new(...) do |f|
226
+ f.adapter :net_http do |http| # yields Net::HTTP
227
+ http.idle_timeout = 100
228
+ http.verify_callback = lambda do | preverify_ok, cert_store |
229
+ # do something here...
230
+ end
231
+ end
232
+ end
233
+ ```
234
+
235
+ ### NetHttpPersistent
236
+ ```ruby
237
+ conn = Faraday.new(...) do |f|
238
+ f.adapter :net_http_persistent do |http| # yields Net::HTTP::Persistent
239
+ http.idle_timeout = 100
240
+ http.retry_change_requests = true
241
+ end
242
+ end
243
+ ```
244
+
245
+ ### Patron
246
+ ```ruby
247
+ conn = Faraday.new(...) do |f|
248
+ f.adapter :patron do |session| # yields Patron::Session
249
+ session.max_redirects = 10
250
+ end
251
+ end
252
+ ```
253
+
254
+ ### HTTPClient
255
+ ```ruby
256
+ conn = Faraday.new(...) do |f|
257
+ f.adapter :httpclient do |client| # yields HTTPClient
258
+ client.keep_alive_timeout = 20
259
+ client.ssl_config.timeout = 25
260
+ end
261
+ end
262
+ ```
263
+
141
264
  ## Using Faraday for testing
142
265
 
143
266
  ```ruby
@@ -183,13 +306,9 @@ stubs.verify_stubbed_calls
183
306
  This library aims to support and is [tested against][travis] the following Ruby
184
307
  implementations:
185
308
 
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][]
309
+ * Ruby 1.9.3+
310
+ * [JRuby][] 1.7+
311
+ * [Rubinius][] 2+
193
312
 
194
313
  If something doesn't work on one of these Ruby versions, it's a bug.
195
314
 
@@ -209,12 +328,13 @@ of a major release, support for that Ruby version may be dropped.
209
328
  Copyright (c) 2009-2013 [Rick Olson](mailto:technoweenie@gmail.com), Zack Hobson.
210
329
  See [LICENSE][] for details.
211
330
 
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/
331
+ [net_http]: http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html
332
+ [persistent]: https://github.com/drbrain/net-http-persistent
333
+ [travis]: https://travis-ci.org/lostisland/faraday
334
+ [excon]: https://github.com/excon/excon#readme
335
+ [patron]: http://toland.github.io/patron/
216
336
  [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
337
+ [httpclient]: https://github.com/nahi/httpclient
338
+ [jruby]: http://jruby.org/
339
+ [rubinius]: http://rubini.us/
340
+ [license]: LICENSE.md
@@ -138,9 +138,11 @@ module Faraday
138
138
 
139
139
  # TODO: reuse the connection to support pipelining
140
140
  def perform_single_request(env)
141
- req = EventMachine::HttpRequest.new(env[:url], connection_config(env))
141
+ req = create_request(env)
142
142
  req.setup_request(env[:method], request_config(env)).callback { |client|
143
- save_response(env, client.response_header.status, client.response) do |resp_headers|
143
+ status = client.response_header.status
144
+ reason = client.response_header.http_reason
145
+ save_response(env, status, client.response, nil, reason) do |resp_headers|
144
146
  client.response_header.each do |name, value|
145
147
  resp_headers[name.to_sym] = value
146
148
  end
@@ -148,6 +150,10 @@ module Faraday
148
150
  }
149
151
  end
150
152
 
153
+ def create_request(env)
154
+ EventMachine::HttpRequest.new(env[:url], connection_config(env).merge(@connection_options))
155
+ end
156
+
151
157
  def error_message(client)
152
158
  client.error or "request failed"
153
159
  end
@@ -39,7 +39,7 @@ module EmHttpSslPatch
39
39
  end
40
40
 
41
41
  def host
42
- parent.connopts.host
42
+ parent.uri.host
43
43
  end
44
44
 
45
45
  def certificate_store
@@ -19,7 +19,7 @@ module Faraday
19
19
 
20
20
  def call(env)
21
21
  super
22
- request = EventMachine::HttpRequest.new(Utils::URI(env[:url].to_s), connection_config(env))
22
+ request = create_request(env)
23
23
 
24
24
  http_method = env[:method].to_s.downcase.to_sym
25
25
 
@@ -54,7 +54,9 @@ module Faraday
54
54
 
55
55
  raise client.error if client.error
56
56
 
57
- save_response(env, client.response_header.status, client.response) do |resp_headers|
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|
58
60
  client.response_header.each do |name, value|
59
61
  resp_headers[name.to_sym] = value
60
62
  end
@@ -70,6 +72,14 @@ module Faraday
70
72
  else
71
73
  raise Error::ConnectionFailed, err
72
74
  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
82
+ end
73
83
  rescue => err
74
84
  if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
75
85
  raise Faraday::SSLError, err
@@ -77,6 +87,10 @@ module Faraday
77
87
  raise
78
88
  end
79
89
  end
90
+
91
+ def create_request(env)
92
+ EventMachine::HttpRequest.new(Utils::URI(env[:url].to_s), connection_config(env).merge(@connection_options))
93
+ end
80
94
  end
81
95
  end
82
96
  end
@@ -3,11 +3,6 @@ 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
-
11
6
  def call(env)
12
7
  super
13
8
 
@@ -41,6 +36,7 @@ module Faraday
41
36
  if req[:proxy]
42
37
  opts[:proxy] = {
43
38
  :host => req[:proxy][:uri].host,
39
+ :hostname => req[:proxy][:uri].hostname,
44
40
  :port => req[:proxy][:uri].port,
45
41
  :scheme => req[:proxy][:uri].scheme,
46
42
  :user => req[:proxy][:user],
@@ -49,14 +45,14 @@ module Faraday
49
45
  end
50
46
  end
51
47
 
52
- conn = ::Excon.new(env[:url].to_s, opts.merge(@connection_options))
48
+ conn = create_connection(env, opts)
53
49
 
54
50
  resp = conn.request \
55
51
  :method => env[:method].to_s.upcase,
56
52
  :headers => env[:request_headers],
57
53
  :body => read_body(env)
58
54
 
59
- save_response(env, resp.status.to_i, resp.body, resp.headers)
55
+ save_response(env, resp.status.to_i, resp.body, resp.headers, resp.reason_phrase)
60
56
 
61
57
  @app.call env
62
58
  rescue ::Excon::Errors::SocketError => err
@@ -71,6 +67,10 @@ module Faraday
71
67
  raise Error::TimeoutError, err
72
68
  end
73
69
 
70
+ def create_connection(env, opts)
71
+ ::Excon.new(env[:url].to_s, opts.merge(@connection_options))
72
+ end
73
+
74
74
  # TODO: support streaming requests
75
75
  def read_body(env)
76
76
  env[:body].respond_to?(:read) ? env[:body].read : env[:body]
@@ -10,6 +10,9 @@ module Faraday
10
10
  def call(env)
11
11
  super
12
12
 
13
+ # enable compression
14
+ client.transparent_gzip_decompression = true
15
+
13
16
  if req = env[:request]
14
17
  if proxy = req[:proxy]
15
18
  configure_proxy proxy
@@ -26,6 +29,8 @@ module Faraday
26
29
  configure_ssl ssl
27
30
  end
28
31
 
32
+ configure_client
33
+
29
34
  # TODO Don't stream yet.
30
35
  # https://github.com/nahi/httpclient/pull/90
31
36
  env[:body] = env[:body].read if env[:body].respond_to? :read
@@ -34,10 +39,10 @@ module Faraday
34
39
  :body => env[:body],
35
40
  :header => env[:request_headers]
36
41
 
37
- save_response env, resp.status, resp.body, resp.headers
42
+ save_response env, resp.status, resp.body, resp.headers, resp.reason
38
43
 
39
44
  @app.call env
40
- rescue ::HTTPClient::TimeoutError
45
+ rescue ::HTTPClient::TimeoutError, Errno::ETIMEDOUT
41
46
  raise Faraday::Error::TimeoutError, $!
42
47
  rescue ::HTTPClient::BadResponseError => err
43
48
  if err.message.include?('status 407')
@@ -45,7 +50,7 @@ module Faraday
45
50
  else
46
51
  raise Faraday::Error::ClientError, $!
47
52
  end
48
- rescue Errno::ECONNREFUSED, EOFError
53
+ rescue Errno::ECONNREFUSED, IOError
49
54
  raise Faraday::Error::ConnectionFailed, $!
50
55
  rescue => err
51
56
  if defined?(OpenSSL) && OpenSSL::SSL::SSLError === err
@@ -69,14 +74,14 @@ module Faraday
69
74
 
70
75
  def configure_ssl(ssl)
71
76
  ssl_config = client.ssl_config
77
+ ssl_config.verify_mode = ssl_verify_mode(ssl)
78
+ ssl_config.cert_store = ssl_cert_store(ssl)
72
79
 
73
80
  ssl_config.add_trust_ca ssl[:ca_file] if ssl[:ca_file]
74
81
  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
82
  ssl_config.client_cert = ssl[:client_cert] if ssl[:client_cert]
77
83
  ssl_config.client_key = ssl[:client_key] if ssl[:client_key]
78
84
  ssl_config.verify_depth = ssl[:verify_depth] if ssl[:verify_depth]
79
- ssl_config.verify_mode = ssl_verify_mode(ssl)
80
85
  end
81
86
 
82
87
  def configure_timeouts(req)
@@ -92,6 +97,23 @@ module Faraday
92
97
  end
93
98
  end
94
99
 
100
+ def configure_client
101
+ @config_block.call(client) if @config_block
102
+ end
103
+
104
+ def ssl_cert_store(ssl)
105
+ return ssl[:cert_store] if ssl[:cert_store]
106
+ # Memoize the cert store so that the same one is passed to
107
+ # HTTPClient each time, to avoid resyncing SSL sesions when
108
+ # it's changed
109
+ @cert_store ||= begin
110
+ # 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
114
+ end
115
+ end
116
+
95
117
  def ssl_verify_mode(ssl)
96
118
  ssl[:verify_mode] || begin
97
119
  if ssl.fetch(:verify, true)
@@ -10,13 +10,14 @@ module Faraday
10
10
  class Adapter
11
11
  class NetHttp < Faraday::Adapter
12
12
  NET_HTTP_EXCEPTIONS = [
13
- EOFError,
13
+ IOError,
14
14
  Errno::ECONNABORTED,
15
15
  Errno::ECONNREFUSED,
16
16
  Errno::ECONNRESET,
17
17
  Errno::EHOSTUNREACH,
18
18
  Errno::EINVAL,
19
19
  Errno::ENETUNREACH,
20
+ Errno::EPIPE,
20
21
  Net::HTTPBadResponse,
21
22
  Net::HTTPHeaderSyntaxError,
22
23
  Net::ProtocolError,
@@ -31,10 +32,7 @@ module Faraday
31
32
  super
32
33
  with_net_http_connection(env) do |http|
33
34
  configure_ssl(http, env[:ssl]) if env[:url].scheme == 'https' and env[:ssl]
34
-
35
- req = env[:request]
36
- http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
37
- http.open_timeout = req[:open_timeout] if req[:open_timeout]
35
+ configure_request(http, env[:request])
38
36
 
39
37
  begin
40
38
  http_response = perform_request(http, env)
@@ -46,7 +44,7 @@ module Faraday
46
44
  end
47
45
  end
48
46
 
49
- save_response(env, http_response.code.to_i, http_response.body || '') do |response_headers|
47
+ save_response(env, http_response.code.to_i, http_response.body || '', nil, http_response.message) do |response_headers|
50
48
  http_response.each_header do |key, value|
51
49
  response_headers[key] = value
52
50
  end
@@ -54,7 +52,7 @@ module Faraday
54
52
  end
55
53
 
56
54
  @app.call env
57
- rescue Timeout::Error => err
55
+ rescue Timeout::Error, Errno::ETIMEDOUT => err
58
56
  raise Faraday::Error::TimeoutError, err
59
57
  end
60
58
 
@@ -92,7 +90,7 @@ module Faraday
92
90
  Net::HTTP::Proxy(proxy[:uri].host, proxy[:uri].port, proxy[:user], proxy[:password])
93
91
  else
94
92
  Net::HTTP
95
- end.new(env[:url].host, env[:url].port)
93
+ end.new(env[:url].host, env[:url].port || (env[:url].scheme == 'https' ? 443 : 80))
96
94
  end
97
95
 
98
96
  def configure_ssl(http, ssl)
@@ -108,6 +106,13 @@ module Faraday
108
106
  http.ssl_version = ssl[:version] if ssl[:version]
109
107
  end
110
108
 
109
+ def configure_request(http, req)
110
+ http.read_timeout = http.open_timeout = req[:timeout] if req[:timeout]
111
+ http.open_timeout = req[:open_timeout] if req[:open_timeout]
112
+
113
+ @config_block.call(http) if @config_block
114
+ end
115
+
111
116
  def ssl_cert_store(ssl)
112
117
  return ssl[:cert_store] if ssl[:cert_store]
113
118
  # Use the default cert store by default, i.e. system ca certs
@@ -4,12 +4,11 @@
4
4
 
5
5
  module Faraday
6
6
  class Adapter
7
- # Experimental adapter for net-http-persistent
8
7
  class NetHttpPersistent < NetHttp
9
8
  dependency 'net/http/persistent'
10
9
 
11
- def with_net_http_connection(env)
12
- if proxy = env[:request][:proxy]
10
+ def net_http_connection(env)
11
+ if (proxy = env[:request][:proxy])
13
12
  proxy_uri = ::URI::HTTP === proxy[:uri] ? proxy[:uri].dup : ::URI.parse(proxy[:uri].to_s)
14
13
  proxy_uri.user = proxy_uri.password = nil
15
14
  # awful patch for net-http-persistent 2.8 not unescaping user/password
@@ -17,13 +16,16 @@ module Faraday
17
16
  define_method(:user) { proxy[:user] }
18
17
  define_method(:password) { proxy[:password] }
19
18
  end if proxy[:user]
19
+ return Net::HTTP::Persistent.new 'Faraday', proxy_uri
20
20
  end
21
21
 
22
- yield Net::HTTP::Persistent.new 'Faraday', proxy_uri
22
+ Net::HTTP::Persistent.new 'Faraday'
23
23
  end
24
24
 
25
25
  def perform_request(http, env)
26
26
  http.request env[:url], create_request(env)
27
+ rescue Errno::ETIMEDOUT => error
28
+ raise Faraday::Error::TimeoutError, error
27
29
  rescue Net::HTTP::Persistent::Error => error
28
30
  if error.message.include? 'Timeout'
29
31
  raise Faraday::Error::TimeoutError, error
@@ -3,11 +3,6 @@ module Faraday
3
3
  class Patron < Faraday::Adapter
4
4
  dependency 'patron'
5
5
 
6
- def initialize(app, &block)
7
- super(app)
8
- @block = block
9
- end
10
-
11
6
  def call(env)
12
7
  super
13
8
 
@@ -35,7 +30,10 @@ module Faraday
35
30
  raise Error::ConnectionFailed, $!
36
31
  end
37
32
 
38
- save_response(env, response.status, response.body, response.headers)
33
+ # Remove the "HTTP/1.1 200", leaving just the reason phrase
34
+ reason_phrase = response.status_line.gsub(/^.* \d{3} /, '')
35
+
36
+ save_response(env, response.status, response.body, response.headers, reason_phrase)
39
37
 
40
38
  @app.call env
41
39
  rescue ::Patron::TimeoutError => err
@@ -56,15 +54,21 @@ module Faraday
56
54
  # HAX: helps but doesn't work completely
57
55
  # https://github.com/toland/patron/issues/34
58
56
  ::Patron::Request::VALID_ACTIONS.tap do |actions|
59
- actions << :patch unless actions.include? :patch
60
- actions << :options unless actions.include? :options
57
+ if actions[0].is_a?(Symbol)
58
+ actions << :patch unless actions.include? :patch
59
+ actions << :options unless actions.include? :options
60
+ else
61
+ # Patron 0.4.20 and up
62
+ actions << "PATCH" unless actions.include? "PATCH"
63
+ actions << "OPTIONS" unless actions.include? "OPTIONS"
64
+ end
61
65
  end
62
66
  end
63
67
 
64
68
  def create_session
65
69
  session = ::Patron::Session.new
66
70
  session.insecure = true
67
- @block.call(session) if @block
71
+ @config_block.call(session) if @config_block
68
72
  session
69
73
  end
70
74
  end