faraday 0.6.0 → 0.9.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 (83) hide show
  1. checksums.yaml +7 -0
  2. data/.document +6 -0
  3. data/CHANGELOG.md +15 -0
  4. data/CONTRIBUTING.md +36 -0
  5. data/Gemfile +25 -15
  6. data/{LICENSE → LICENSE.md} +1 -1
  7. data/README.md +187 -137
  8. data/Rakefile +38 -101
  9. data/faraday.gemspec +26 -81
  10. data/lib/faraday/adapter/em_http.rb +237 -0
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +56 -0
  12. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +66 -0
  13. data/lib/faraday/adapter/em_synchrony.rb +65 -38
  14. data/lib/faraday/adapter/excon.rb +60 -9
  15. data/lib/faraday/adapter/httpclient.rb +106 -0
  16. data/lib/faraday/adapter/net_http.rb +89 -38
  17. data/lib/faraday/adapter/net_http_persistent.rb +47 -0
  18. data/lib/faraday/adapter/patron.rb +46 -9
  19. data/lib/faraday/adapter/rack.rb +58 -0
  20. data/lib/faraday/adapter/test.rb +68 -28
  21. data/lib/faraday/adapter/typhoeus.rb +94 -16
  22. data/lib/faraday/adapter.rb +33 -25
  23. data/lib/faraday/autoload.rb +85 -0
  24. data/lib/faraday/connection.rb +342 -134
  25. data/lib/faraday/error.rb +44 -29
  26. data/lib/faraday/middleware.rb +18 -10
  27. data/lib/faraday/options.rb +350 -0
  28. data/lib/faraday/parameters.rb +193 -0
  29. data/lib/faraday/rack_builder.rb +212 -0
  30. data/lib/faraday/request/authorization.rb +42 -0
  31. data/lib/faraday/request/basic_authentication.rb +13 -0
  32. data/lib/faraday/request/instrumentation.rb +36 -0
  33. data/lib/faraday/request/multipart.rb +15 -15
  34. data/lib/faraday/request/retry.rb +118 -0
  35. data/lib/faraday/request/token_authentication.rb +15 -0
  36. data/lib/faraday/request/url_encoded.rb +8 -9
  37. data/lib/faraday/request.rb +46 -45
  38. data/lib/faraday/response/logger.rb +4 -4
  39. data/lib/faraday/response/raise_error.rb +8 -3
  40. data/lib/faraday/response.rb +20 -25
  41. data/lib/faraday/upload_io.rb +51 -7
  42. data/lib/faraday/utils.rb +240 -44
  43. data/lib/faraday.rb +218 -38
  44. data/script/console +7 -0
  45. data/script/generate_certs +42 -0
  46. data/script/package +7 -0
  47. data/script/proxy-server +42 -0
  48. data/script/release +17 -0
  49. data/script/server +36 -0
  50. data/script/test +172 -0
  51. data/test/adapters/default_test.rb +14 -0
  52. data/test/adapters/em_http_test.rb +20 -0
  53. data/test/adapters/em_synchrony_test.rb +20 -0
  54. data/test/adapters/excon_test.rb +20 -0
  55. data/test/adapters/httpclient_test.rb +21 -0
  56. data/test/adapters/integration.rb +254 -0
  57. data/test/adapters/logger_test.rb +3 -3
  58. data/test/adapters/net_http_persistent_test.rb +20 -0
  59. data/test/adapters/net_http_test.rb +6 -25
  60. data/test/adapters/patron_test.rb +20 -0
  61. data/test/adapters/rack_test.rb +31 -0
  62. data/test/adapters/test_middleware_test.rb +74 -3
  63. data/test/adapters/typhoeus_test.rb +28 -0
  64. data/test/authentication_middleware_test.rb +65 -0
  65. data/test/composite_read_io_test.rb +111 -0
  66. data/test/connection_test.rb +381 -104
  67. data/test/env_test.rb +116 -40
  68. data/test/helper.rb +61 -25
  69. data/test/live_server.rb +55 -29
  70. data/test/middleware/instrumentation_test.rb +88 -0
  71. data/test/middleware/retry_test.rb +109 -0
  72. data/test/middleware_stack_test.rb +87 -5
  73. data/test/multibyte.txt +1 -0
  74. data/test/options_test.rb +252 -0
  75. data/test/request_middleware_test.rb +78 -21
  76. data/test/response_middleware_test.rb +32 -7
  77. data/test/strawberry.rb +2 -0
  78. data/test/utils_test.rb +58 -0
  79. metadata +116 -117
  80. data/lib/faraday/adapter/action_dispatch.rb +0 -30
  81. data/lib/faraday/builder.rb +0 -137
  82. data/lib/faraday/request/json.rb +0 -31
  83. data/test/adapters/live_test.rb +0 -186
@@ -1,7 +1,7 @@
1
1
  module Faraday
2
2
  class Adapter
3
3
  class Typhoeus < Faraday::Adapter
4
- self.supports_parallel_requests = true
4
+ self.supports_parallel = true
5
5
 
6
6
  def self.setup_parallel_manager(options = {})
7
7
  options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
@@ -11,34 +11,112 @@ module Faraday
11
11
 
12
12
  def call(env)
13
13
  super
14
+ perform_request env
15
+ @app.call env
16
+ end
17
+
18
+ def perform_request(env)
19
+ read_body env
14
20
 
15
- # TODO: support streaming requests
21
+ hydra = env[:parallel_manager] || self.class.setup_parallel_manager
22
+ hydra.queue request(env)
23
+ hydra.run unless parallel?(env)
24
+ rescue Errno::ECONNREFUSED
25
+ raise Error::ConnectionFailed, $!
26
+ end
27
+
28
+ # TODO: support streaming requests
29
+ def read_body(env)
16
30
  env[:body] = env[:body].read if env[:body].respond_to? :read
31
+ end
32
+
33
+ def request(env)
34
+ method = env[:method]
35
+ # For some reason, prevents Typhoeus from using "100-continue".
36
+ # We want this because Webrick 1.3.1 can't seem to handle it w/ PUT.
37
+ method = method.to_s.upcase if method == :put
17
38
 
18
39
  req = ::Typhoeus::Request.new env[:url].to_s,
19
- :method => env[:method],
40
+ :method => method,
20
41
  :body => env[:body],
21
42
  :headers => env[:request_headers],
22
- :disable_ssl_peer_verification => (env[:ssl] && !env[:ssl].fetch(:verify, true))
43
+ :disable_ssl_peer_verification => (env[:ssl] && env[:ssl].disable?)
44
+
45
+ configure_ssl req, env
46
+ configure_proxy req, env
47
+ configure_timeout req, env
48
+ configure_socket req, env
49
+
50
+ req.on_complete do |resp|
51
+ if resp.timed_out?
52
+ if parallel?(env)
53
+ # TODO: error callback in async mode
54
+ else
55
+ raise Faraday::Error::TimeoutError, "request timed out"
56
+ end
57
+ end
58
+
59
+ case resp.curl_return_code
60
+ when 0
61
+ # everything OK
62
+ when 7
63
+ raise Error::ConnectionFailed, resp.curl_error_message
64
+ when 60
65
+ raise Faraday::SSLError, resp.curl_error_message
66
+ else
67
+ raise Error::ClientError, resp.curl_error_message
68
+ end
69
+
70
+ save_response(env, resp.code, resp.body) do |response_headers|
71
+ response_headers.parse resp.headers
72
+ end
73
+ # in async mode, :response is initialized at this point
74
+ env[:response].finish(env) if parallel?(env)
75
+ end
76
+
77
+ req
78
+ end
79
+
80
+ def configure_ssl(req, env)
81
+ ssl = env[:ssl]
82
+
83
+ req.ssl_version = ssl[:version] if ssl[:version]
84
+ req.ssl_cert = ssl[:client_cert] if ssl[:client_cert]
85
+ req.ssl_key = ssl[:client_key] if ssl[:client_key]
86
+ req.ssl_cacert = ssl[:ca_file] if ssl[:ca_file]
87
+ req.ssl_capath = ssl[:ca_path] if ssl[:ca_path]
88
+ end
89
+
90
+ def configure_proxy(req, env)
91
+ proxy = request_options(env)[:proxy]
92
+ return unless proxy
93
+
94
+ req.proxy = "#{proxy[:uri].host}:#{proxy[:uri].port}"
95
+
96
+ if proxy[:user] && proxy[:password]
97
+ req.proxy_username = proxy[:user]
98
+ req.proxy_password = proxy[:password]
99
+ end
100
+ end
23
101
 
24
- env_req = env[:request]
102
+ def configure_timeout(req, env)
103
+ env_req = request_options(env)
25
104
  req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
26
105
  req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
106
+ end
27
107
 
28
- is_parallel = !!env[:parallel_manager]
29
- req.on_complete do |resp|
30
- env.update :status => resp.code, :body => resp.body
31
- response_headers(env).parse resp.headers
32
- env[:response].finish(env) if is_parallel
108
+ def configure_socket(req, env)
109
+ if bind = request_options(env)[:bind]
110
+ req.interface = bind[:host]
33
111
  end
112
+ end
34
113
 
35
- hydra = env[:parallel_manager] || self.class.setup_parallel_manager
36
- hydra.queue req
37
- hydra.run unless is_parallel
114
+ def request_options(env)
115
+ env[:request]
116
+ end
38
117
 
39
- @app.call env
40
- rescue Errno::ECONNREFUSED
41
- raise Error::ConnectionFailed, $!
118
+ def parallel?(env)
119
+ !!env[:parallel_manager]
42
120
  end
43
121
  end
44
122
  end
@@ -1,38 +1,46 @@
1
1
  module Faraday
2
+ # Public: This is a base class for all Faraday adapters. Adapters are
3
+ # responsible for fulfilling a Faraday request.
2
4
  class Adapter < Middleware
3
5
  CONTENT_LENGTH = 'Content-Length'.freeze
4
6
 
5
- extend AutoloadHelper
7
+ register_middleware File.expand_path('../adapter', __FILE__),
8
+ :test => [:Test, 'test'],
9
+ :net_http => [:NetHttp, 'net_http'],
10
+ :net_http_persistent => [:NetHttpPersistent, 'net_http_persistent'],
11
+ :typhoeus => [:Typhoeus, 'typhoeus'],
12
+ :patron => [:Patron, 'patron'],
13
+ :em_synchrony => [:EMSynchrony, 'em_synchrony'],
14
+ :em_http => [:EMHttp, 'em_http'],
15
+ :excon => [:Excon, 'excon'],
16
+ :rack => [:Rack, 'rack'],
17
+ :httpclient => [:HTTPClient, 'httpclient']
6
18
 
7
- autoload_all 'faraday/adapter',
8
- :ActionDispatch => 'action_dispatch',
9
- :NetHttp => 'net_http',
10
- :Typhoeus => 'typhoeus',
11
- :EMSynchrony => 'em_synchrony',
12
- :Patron => 'patron',
13
- :Excon => 'excon',
14
- :Test => 'test'
19
+ # Public: This module marks an Adapter as supporting parallel requests.
20
+ module Parallelism
21
+ attr_writer :supports_parallel
22
+ def supports_parallel?() @supports_parallel end
15
23
 
16
- register_lookup_modules \
17
- :action_dispatch => :ActionDispatch,
18
- :test => :Test,
19
- :net_http => :NetHttp,
20
- :typhoeus => :Typhoeus,
21
- :patron => :Patron,
22
- :em_synchrony => :EMSynchrony,
23
- :excon => :Excon
24
+ def inherited(subclass)
25
+ super
26
+ subclass.supports_parallel = self.supports_parallel?
27
+ end
28
+ end
29
+
30
+ extend Parallelism
31
+ self.supports_parallel = false
24
32
 
25
33
  def call(env)
26
- if !env[:body] and Connection::METHODS_WITH_BODIES.include? env[:method]
27
- # play nice and indicate we're sending an empty body
28
- env[:request_headers][CONTENT_LENGTH] = "0"
29
- # Typhoeus hangs on PUT requests if body is nil
30
- env[:body] = ''
31
- end
34
+ env.clear_body if env.needs_body?
32
35
  end
33
36
 
34
- def response_headers(env)
35
- env[:response_headers] ||= Utils::Headers.new
37
+ def save_response(env, status, body, headers = nil)
38
+ env.status = status
39
+ env.body = body
40
+ env.response_headers = Utils::Headers.new.tap do |response_headers|
41
+ response_headers.update headers unless headers.nil?
42
+ yield(response_headers) if block_given?
43
+ end
36
44
  end
37
45
  end
38
46
  end
@@ -0,0 +1,85 @@
1
+ module Faraday
2
+ # Internal: Adds the ability for other modules to manage autoloadable
3
+ # constants.
4
+ module AutoloadHelper
5
+ # Internal: Registers the constants to be auto loaded.
6
+ #
7
+ # prefix - The String require prefix. If the path is inside Faraday, then
8
+ # it will be prefixed with the root path of this loaded Faraday
9
+ # version.
10
+ # options - Hash of Symbol => String library names.
11
+ #
12
+ # Examples.
13
+ #
14
+ # Faraday.autoload_all 'faraday/foo',
15
+ # :Bar => 'bar'
16
+ #
17
+ # # requires faraday/foo/bar to load Faraday::Bar.
18
+ # Faraday::Bar
19
+ #
20
+ #
21
+ # Returns nothing.
22
+ def autoload_all(prefix, options)
23
+ if prefix =~ /^faraday(\/|$)/i
24
+ prefix = File.join(Faraday.root_path, prefix)
25
+ end
26
+ options.each do |const_name, path|
27
+ autoload const_name, File.join(prefix, path)
28
+ end
29
+ end
30
+
31
+ # Internal: Loads each autoloaded constant. If thread safety is a concern,
32
+ # wrap this in a Mutex.
33
+ #
34
+ # Returns nothing.
35
+ def load_autoloaded_constants
36
+ constants.each do |const|
37
+ const_get(const) if autoload?(const)
38
+ end
39
+ end
40
+
41
+ # Internal: Filters the module's contents with those that have been already
42
+ # autoloaded.
43
+ #
44
+ # Returns an Array of Class/Module objects.
45
+ def all_loaded_constants
46
+ constants.map { |c| const_get(c) }.
47
+ select { |a| a.respond_to?(:loaded?) && a.loaded? }
48
+ end
49
+ end
50
+
51
+ class Adapter
52
+ extend AutoloadHelper
53
+ autoload_all 'faraday/adapter',
54
+ :NetHttp => 'net_http',
55
+ :NetHttpPersistent => 'net_http_persistent',
56
+ :Typhoeus => 'typhoeus',
57
+ :EMSynchrony => 'em_synchrony',
58
+ :EMHttp => 'em_http',
59
+ :Patron => 'patron',
60
+ :Excon => 'excon',
61
+ :Test => 'test',
62
+ :Rack => 'rack',
63
+ :HTTPClient => 'httpclient'
64
+ end
65
+
66
+ class Request
67
+ extend AutoloadHelper
68
+ autoload_all 'faraday/request',
69
+ :UrlEncoded => 'url_encoded',
70
+ :Multipart => 'multipart',
71
+ :Retry => 'retry',
72
+ :Timeout => 'timeout',
73
+ :Authorization => 'authorization',
74
+ :BasicAuthentication => 'basic_authentication',
75
+ :TokenAuthentication => 'token_authentication',
76
+ :Instrumentation => 'instrumentation'
77
+ end
78
+
79
+ class Response
80
+ extend AutoloadHelper
81
+ autoload_all 'faraday/response',
82
+ :RaiseError => 'raise_error',
83
+ :Logger => 'logger'
84
+ end
85
+ end