faraday 0.9.1 → 1.8.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 (146) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +28 -195
  5. data/Rakefile +4 -68
  6. data/examples/client_spec.rb +97 -0
  7. data/examples/client_test.rb +118 -0
  8. data/lib/faraday/adapter/test.rb +158 -58
  9. data/lib/faraday/adapter/typhoeus.rb +7 -115
  10. data/lib/faraday/adapter.rb +79 -20
  11. data/lib/faraday/adapter_registry.rb +30 -0
  12. data/lib/faraday/autoload.rb +39 -36
  13. data/lib/faraday/connection.rb +378 -168
  14. data/lib/faraday/dependency_loader.rb +37 -0
  15. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  16. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  17. data/lib/faraday/error.rb +128 -29
  18. data/lib/faraday/file_part.rb +128 -0
  19. data/lib/faraday/logging/formatter.rb +105 -0
  20. data/lib/faraday/methods.rb +6 -0
  21. data/lib/faraday/middleware.rb +19 -25
  22. data/lib/faraday/middleware_registry.rb +129 -0
  23. data/lib/faraday/options/connection_options.rb +22 -0
  24. data/lib/faraday/options/env.rb +181 -0
  25. data/lib/faraday/options/proxy_options.rb +32 -0
  26. data/lib/faraday/options/request_options.rb +22 -0
  27. data/lib/faraday/options/ssl_options.rb +59 -0
  28. data/lib/faraday/options.rb +61 -193
  29. data/lib/faraday/param_part.rb +53 -0
  30. data/lib/faraday/parameters.rb +4 -180
  31. data/lib/faraday/rack_builder.rb +84 -47
  32. data/lib/faraday/request/authorization.rb +51 -31
  33. data/lib/faraday/request/basic_authentication.rb +14 -7
  34. data/lib/faraday/request/instrumentation.rb +45 -27
  35. data/lib/faraday/request/multipart.rb +88 -45
  36. data/lib/faraday/request/retry.rb +212 -121
  37. data/lib/faraday/request/token_authentication.rb +15 -10
  38. data/lib/faraday/request/url_encoded.rb +43 -23
  39. data/lib/faraday/request.rb +96 -32
  40. data/lib/faraday/response/logger.rb +22 -48
  41. data/lib/faraday/response/raise_error.rb +49 -14
  42. data/lib/faraday/response.rb +33 -25
  43. data/lib/faraday/utils/headers.rb +139 -0
  44. data/lib/faraday/utils/params_hash.rb +61 -0
  45. data/lib/faraday/utils.rb +38 -218
  46. data/lib/faraday/version.rb +5 -0
  47. data/lib/faraday.rb +130 -213
  48. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  49. data/spec/faraday/adapter/em_http_spec.rb +49 -0
  50. data/spec/faraday/adapter/em_synchrony_spec.rb +18 -0
  51. data/spec/faraday/adapter/excon_spec.rb +49 -0
  52. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  53. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  54. data/spec/faraday/adapter/patron_spec.rb +18 -0
  55. data/spec/faraday/adapter/rack_spec.rb +8 -0
  56. data/spec/faraday/adapter/test_spec.rb +377 -0
  57. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  58. data/spec/faraday/adapter_registry_spec.rb +28 -0
  59. data/spec/faraday/adapter_spec.rb +55 -0
  60. data/spec/faraday/composite_read_io_spec.rb +80 -0
  61. data/spec/faraday/connection_spec.rb +736 -0
  62. data/spec/faraday/error_spec.rb +60 -0
  63. data/spec/faraday/middleware_spec.rb +52 -0
  64. data/spec/faraday/options/env_spec.rb +70 -0
  65. data/spec/faraday/options/options_spec.rb +297 -0
  66. data/spec/faraday/options/proxy_options_spec.rb +44 -0
  67. data/spec/faraday/options/request_options_spec.rb +19 -0
  68. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  69. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  70. data/spec/faraday/rack_builder_spec.rb +345 -0
  71. data/spec/faraday/request/authorization_spec.rb +96 -0
  72. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  73. data/spec/faraday/request/multipart_spec.rb +302 -0
  74. data/spec/faraday/request/retry_spec.rb +242 -0
  75. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  76. data/spec/faraday/request_spec.rb +120 -0
  77. data/spec/faraday/response/logger_spec.rb +220 -0
  78. data/spec/faraday/response/middleware_spec.rb +68 -0
  79. data/spec/faraday/response/raise_error_spec.rb +169 -0
  80. data/spec/faraday/response_spec.rb +75 -0
  81. data/spec/faraday/utils/headers_spec.rb +82 -0
  82. data/spec/faraday/utils_spec.rb +56 -0
  83. data/spec/faraday_spec.rb +37 -0
  84. data/spec/spec_helper.rb +132 -0
  85. data/spec/support/disabling_stub.rb +14 -0
  86. data/spec/support/fake_safe_buffer.rb +15 -0
  87. data/spec/support/helper_methods.rb +133 -0
  88. data/spec/support/shared_examples/adapter.rb +105 -0
  89. data/spec/support/shared_examples/params_encoder.rb +18 -0
  90. data/spec/support/shared_examples/request_method.rb +262 -0
  91. data/spec/support/streaming_response_checker.rb +35 -0
  92. data/spec/support/webmock_rack_app.rb +68 -0
  93. metadata +199 -98
  94. data/.document +0 -6
  95. data/CONTRIBUTING.md +0 -36
  96. data/Gemfile +0 -25
  97. data/faraday.gemspec +0 -34
  98. data/lib/faraday/adapter/em_http.rb +0 -237
  99. data/lib/faraday/adapter/em_http_ssl_patch.rb +0 -56
  100. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +0 -66
  101. data/lib/faraday/adapter/em_synchrony.rb +0 -92
  102. data/lib/faraday/adapter/excon.rb +0 -80
  103. data/lib/faraday/adapter/httpclient.rb +0 -106
  104. data/lib/faraday/adapter/net_http.rb +0 -130
  105. data/lib/faraday/adapter/net_http_persistent.rb +0 -48
  106. data/lib/faraday/adapter/patron.rb +0 -72
  107. data/lib/faraday/adapter/rack.rb +0 -58
  108. data/lib/faraday/upload_io.rb +0 -67
  109. data/script/cached-bundle +0 -46
  110. data/script/console +0 -7
  111. data/script/generate_certs +0 -42
  112. data/script/package +0 -7
  113. data/script/proxy-server +0 -42
  114. data/script/release +0 -17
  115. data/script/s3-put +0 -71
  116. data/script/server +0 -36
  117. data/script/test +0 -172
  118. data/test/adapters/default_test.rb +0 -14
  119. data/test/adapters/em_http_test.rb +0 -20
  120. data/test/adapters/em_synchrony_test.rb +0 -20
  121. data/test/adapters/excon_test.rb +0 -20
  122. data/test/adapters/httpclient_test.rb +0 -21
  123. data/test/adapters/integration.rb +0 -254
  124. data/test/adapters/logger_test.rb +0 -82
  125. data/test/adapters/net_http_persistent_test.rb +0 -20
  126. data/test/adapters/net_http_test.rb +0 -14
  127. data/test/adapters/patron_test.rb +0 -20
  128. data/test/adapters/rack_test.rb +0 -31
  129. data/test/adapters/test_middleware_test.rb +0 -114
  130. data/test/adapters/typhoeus_test.rb +0 -28
  131. data/test/authentication_middleware_test.rb +0 -65
  132. data/test/composite_read_io_test.rb +0 -111
  133. data/test/connection_test.rb +0 -522
  134. data/test/env_test.rb +0 -218
  135. data/test/helper.rb +0 -81
  136. data/test/live_server.rb +0 -67
  137. data/test/middleware/instrumentation_test.rb +0 -88
  138. data/test/middleware/retry_test.rb +0 -177
  139. data/test/middleware_stack_test.rb +0 -173
  140. data/test/multibyte.txt +0 -1
  141. data/test/options_test.rb +0 -252
  142. data/test/parameters_test.rb +0 -64
  143. data/test/request_middleware_test.rb +0 -142
  144. data/test/response_middleware_test.rb +0 -72
  145. data/test/strawberry.rb +0 -2
  146. data/test/utils_test.rb +0 -58
@@ -1,123 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
5
+ # Typhoeus adapter. This class is just a stub, the real adapter is in
6
+ # https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
3
7
  class Typhoeus < Faraday::Adapter
4
- self.supports_parallel = true
5
-
6
- def self.setup_parallel_manager(options = {})
7
- options.empty? ? ::Typhoeus::Hydra.hydra : ::Typhoeus::Hydra.new(options)
8
- end
8
+ # Needs to define this method in order to support Typhoeus <= 1.3.0
9
+ def call; end
9
10
 
10
11
  dependency 'typhoeus'
11
-
12
- def call(env)
13
- super
14
- perform_request env
15
- @app.call env
16
- end
17
-
18
- def perform_request(env)
19
- read_body env
20
-
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)
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
38
-
39
- req = ::Typhoeus::Request.new env[:url].to_s,
40
- :method => method,
41
- :body => env[:body],
42
- :headers => env[:request_headers],
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
101
-
102
- def configure_timeout(req, env)
103
- env_req = request_options(env)
104
- req.timeout = req.connect_timeout = (env_req[:timeout] * 1000) if env_req[:timeout]
105
- req.connect_timeout = (env_req[:open_timeout] * 1000) if env_req[:open_timeout]
106
- end
107
-
108
- def configure_socket(req, env)
109
- if bind = request_options(env)[:bind]
110
- req.interface = bind[:host]
111
- end
112
- end
113
-
114
- def request_options(env)
115
- env[:request]
116
- end
117
-
118
- def parallel?(env)
119
- !!env[:parallel_manager]
120
- end
12
+ dependency 'typhoeus/adapters/faraday'
121
13
  end
122
14
  end
123
15
  end
@@ -1,46 +1,105 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- # Public: This is a base class for all Faraday adapters. Adapters are
4
+ # Base class for all Faraday adapters. Adapters are
3
5
  # responsible for fulfilling a Faraday request.
4
- class Adapter < Middleware
5
- CONTENT_LENGTH = 'Content-Length'.freeze
6
-
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']
18
-
19
- # Public: This module marks an Adapter as supporting parallel requests.
6
+ class Adapter
7
+ extend MiddlewareRegistry
8
+ extend DependencyLoader
9
+
10
+ CONTENT_LENGTH = 'Content-Length'
11
+
12
+ register_middleware File.expand_path('adapter', __dir__),
13
+ test: [:Test, 'test'],
14
+ typhoeus: [:Typhoeus, 'typhoeus']
15
+
16
+ # This module marks an Adapter as supporting parallel requests.
20
17
  module Parallelism
21
18
  attr_writer :supports_parallel
22
- def supports_parallel?() @supports_parallel end
19
+
20
+ def supports_parallel?
21
+ @supports_parallel
22
+ end
23
23
 
24
24
  def inherited(subclass)
25
25
  super
26
- subclass.supports_parallel = self.supports_parallel?
26
+ subclass.supports_parallel = supports_parallel?
27
27
  end
28
28
  end
29
29
 
30
30
  extend Parallelism
31
31
  self.supports_parallel = false
32
32
 
33
+ def initialize(_app = nil, opts = {}, &block)
34
+ @app = ->(env) { env.response }
35
+ @connection_options = opts
36
+ @config_block = block
37
+ end
38
+
39
+ # Yields or returns an adapter's configured connection. Depends on
40
+ # #build_connection being defined on this adapter.
41
+ #
42
+ # @param env [Faraday::Env, Hash] The env object for a faraday request.
43
+ #
44
+ # @return The return value of the given block, or the HTTP connection object
45
+ # if no block is given.
46
+ def connection(env)
47
+ conn = build_connection(env)
48
+ return conn unless block_given?
49
+
50
+ yield conn
51
+ end
52
+
53
+ # Close any persistent connections. The adapter should still be usable
54
+ # after calling close.
55
+ def close
56
+ # Possible implementation:
57
+ # @app.close if @app.respond_to?(:close)
58
+ end
59
+
33
60
  def call(env)
34
61
  env.clear_body if env.needs_body?
62
+ env.response = Response.new
35
63
  end
36
64
 
37
- def save_response(env, status, body, headers = nil)
65
+ private
66
+
67
+ def save_response(env, status, body, headers = nil, reason_phrase = nil)
38
68
  env.status = status
39
69
  env.body = body
70
+ env.reason_phrase = reason_phrase&.to_s&.strip
40
71
  env.response_headers = Utils::Headers.new.tap do |response_headers|
41
72
  response_headers.update headers unless headers.nil?
42
73
  yield(response_headers) if block_given?
43
74
  end
75
+
76
+ env.response.finish(env) unless env.parallel?
77
+ env.response
44
78
  end
79
+
80
+ # Fetches either a read, write, or open timeout setting. Defaults to the
81
+ # :timeout value if a more specific one is not given.
82
+ #
83
+ # @param type [Symbol] Describes which timeout setting to get: :read,
84
+ # :write, or :open.
85
+ # @param options [Hash] Hash containing Symbol keys like :timeout,
86
+ # :read_timeout, :write_timeout, :open_timeout, or
87
+ # :timeout
88
+ #
89
+ # @return [Integer, nil] Timeout duration in seconds, or nil if no timeout
90
+ # has been set.
91
+ def request_timeout(type, options)
92
+ key = TIMEOUT_KEYS.fetch(type) do
93
+ msg = "Expected :read, :write, :open. Got #{type.inspect} :("
94
+ raise ArgumentError, msg
95
+ end
96
+ options[key] || options[:timeout]
97
+ end
98
+
99
+ TIMEOUT_KEYS = {
100
+ read: :read_timeout,
101
+ open: :open_timeout,
102
+ write: :write_timeout
103
+ }.freeze
45
104
  end
46
105
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'monitor'
4
+
5
+ module Faraday
6
+ # AdapterRegistry registers adapter class names so they can be looked up by a
7
+ # String or Symbol name.
8
+ class AdapterRegistry
9
+ def initialize
10
+ @lock = Monitor.new
11
+ @constants = {}
12
+ end
13
+
14
+ def get(name)
15
+ klass = @lock.synchronize do
16
+ @constants[name]
17
+ end
18
+ return klass if klass
19
+
20
+ Object.const_get(name).tap { |c| set(c, name) }
21
+ end
22
+
23
+ def set(klass, name = nil)
24
+ name ||= klass.to_s
25
+ @lock.synchronize do
26
+ @constants[name] = klass
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,84 +1,87 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- # Internal: Adds the ability for other modules to manage autoloadable
4
+ # Adds the ability for other modules to manage autoloadable
3
5
  # constants.
6
+ #
7
+ # @api private
4
8
  module AutoloadHelper
5
- # Internal: Registers the constants to be auto loaded.
9
+ # Registers the constants to be auto loaded.
6
10
  #
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
+ # @param prefix [String] The require prefix. If the path is inside Faraday,
12
+ # then it will be prefixed with the root path of this loaded
13
+ # Faraday version.
14
+ # @param options [{ Symbol => String }] library names.
11
15
  #
12
- # Examples.
16
+ # @example
13
17
  #
14
18
  # Faraday.autoload_all 'faraday/foo',
15
- # :Bar => 'bar'
19
+ # Bar: 'bar'
16
20
  #
17
21
  # # requires faraday/foo/bar to load Faraday::Bar.
18
22
  # Faraday::Bar
19
23
  #
20
- #
21
- # Returns nothing.
24
+ # @return [void]
22
25
  def autoload_all(prefix, options)
23
- if prefix =~ /^faraday(\/|$)/i
26
+ if prefix.match? %r{^faraday(/|$)}i
24
27
  prefix = File.join(Faraday.root_path, prefix)
25
28
  end
29
+
26
30
  options.each do |const_name, path|
27
31
  autoload const_name, File.join(prefix, path)
28
32
  end
29
33
  end
30
34
 
31
- # Internal: Loads each autoloaded constant. If thread safety is a concern,
35
+ # Loads each autoloaded constant. If thread safety is a concern,
32
36
  # wrap this in a Mutex.
33
37
  #
34
- # Returns nothing.
38
+ # @return [void]
35
39
  def load_autoloaded_constants
36
40
  constants.each do |const|
37
41
  const_get(const) if autoload?(const)
38
42
  end
39
43
  end
40
44
 
41
- # Internal: Filters the module's contents with those that have been already
45
+ # Filters the module's contents with those that have been already
42
46
  # autoloaded.
43
47
  #
44
- # Returns an Array of Class/Module objects.
48
+ # @return [Array<Class, Module>]
45
49
  def all_loaded_constants
46
- constants.map { |c| const_get(c) }.
47
- select { |a| a.respond_to?(:loaded?) && a.loaded? }
50
+ constants
51
+ .map { |c| const_get(c) }
52
+ .select { |a| a.respond_to?(:loaded?) && a.loaded? }
48
53
  end
49
54
  end
50
55
 
56
+ # Adapter is the base class for all Faraday adapters.
57
+ # @see lib/faraday/adapter.rb Original class location
51
58
  class Adapter
52
59
  extend AutoloadHelper
53
60
  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'
61
+ Typhoeus: 'typhoeus',
62
+ Test: 'test'
64
63
  end
65
64
 
65
+ # Request represents a single HTTP request for a Faraday adapter to make.
66
+ # @see lib/faraday/request.rb Original class location
66
67
  class Request
67
68
  extend AutoloadHelper
68
69
  autoload_all 'faraday/request',
69
- :UrlEncoded => 'url_encoded',
70
- :Multipart => 'multipart',
71
- :Retry => 'retry',
72
- :Authorization => 'authorization',
73
- :BasicAuthentication => 'basic_authentication',
74
- :TokenAuthentication => 'token_authentication',
75
- :Instrumentation => 'instrumentation'
70
+ UrlEncoded: 'url_encoded',
71
+ Multipart: 'multipart',
72
+ Retry: 'retry',
73
+ Authorization: 'authorization',
74
+ BasicAuthentication: 'basic_authentication',
75
+ TokenAuthentication: 'token_authentication',
76
+ Instrumentation: 'instrumentation'
76
77
  end
77
78
 
79
+ # Response represents the returned value of a sent Faraday request.
80
+ # @see lib/faraday/response.rb Original class location
78
81
  class Response
79
82
  extend AutoloadHelper
80
83
  autoload_all 'faraday/response',
81
- :RaiseError => 'raise_error',
82
- :Logger => 'logger'
84
+ RaiseError: 'raise_error',
85
+ Logger: 'logger'
83
86
  end
84
87
  end