faraday 0.17.3 → 1.0.1

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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +52 -8
  3. data/LICENSE.md +1 -1
  4. data/README.md +18 -358
  5. data/Rakefile +1 -7
  6. data/examples/client_spec.rb +65 -0
  7. data/examples/client_test.rb +79 -0
  8. data/lib/faraday.rb +94 -175
  9. data/lib/faraday/adapter.rb +82 -22
  10. data/lib/faraday/adapter/em_http.rb +142 -99
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  12. data/lib/faraday/adapter/em_synchrony.rb +104 -60
  13. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  14. data/lib/faraday/adapter/excon.rb +98 -56
  15. data/lib/faraday/adapter/httpclient.rb +83 -59
  16. data/lib/faraday/adapter/net_http.rb +130 -63
  17. data/lib/faraday/adapter/net_http_persistent.rb +50 -27
  18. data/lib/faraday/adapter/patron.rb +80 -43
  19. data/lib/faraday/adapter/rack.rb +30 -13
  20. data/lib/faraday/adapter/test.rb +86 -53
  21. data/lib/faraday/adapter/typhoeus.rb +4 -1
  22. data/lib/faraday/adapter_registry.rb +30 -0
  23. data/lib/faraday/autoload.rb +47 -36
  24. data/lib/faraday/connection.rb +312 -182
  25. data/lib/faraday/dependency_loader.rb +37 -0
  26. data/lib/faraday/encoders/flat_params_encoder.rb +98 -0
  27. data/lib/faraday/encoders/nested_params_encoder.rb +171 -0
  28. data/lib/faraday/error.rb +9 -35
  29. data/lib/faraday/file_part.rb +128 -0
  30. data/lib/faraday/logging/formatter.rb +105 -0
  31. data/lib/faraday/middleware.rb +12 -28
  32. data/lib/faraday/middleware_registry.rb +129 -0
  33. data/lib/faraday/options.rb +32 -183
  34. data/lib/faraday/options/connection_options.rb +22 -0
  35. data/lib/faraday/options/env.rb +181 -0
  36. data/lib/faraday/options/proxy_options.rb +28 -0
  37. data/lib/faraday/options/request_options.rb +22 -0
  38. data/lib/faraday/options/ssl_options.rb +59 -0
  39. data/lib/faraday/param_part.rb +53 -0
  40. data/lib/faraday/parameters.rb +4 -197
  41. data/lib/faraday/rack_builder.rb +66 -55
  42. data/lib/faraday/request.rb +68 -36
  43. data/lib/faraday/request/authorization.rb +44 -30
  44. data/lib/faraday/request/basic_authentication.rb +14 -7
  45. data/lib/faraday/request/instrumentation.rb +45 -27
  46. data/lib/faraday/request/multipart.rb +79 -48
  47. data/lib/faraday/request/retry.rb +197 -171
  48. data/lib/faraday/request/token_authentication.rb +15 -10
  49. data/lib/faraday/request/url_encoded.rb +43 -23
  50. data/lib/faraday/response.rb +24 -14
  51. data/lib/faraday/response/logger.rb +22 -69
  52. data/lib/faraday/response/raise_error.rb +38 -18
  53. data/lib/faraday/utils.rb +36 -245
  54. data/lib/faraday/utils/headers.rb +139 -0
  55. data/lib/faraday/utils/params_hash.rb +61 -0
  56. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  57. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  58. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  59. data/spec/faraday/adapter/excon_spec.rb +49 -0
  60. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  61. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  62. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  63. data/spec/faraday/adapter/patron_spec.rb +18 -0
  64. data/spec/faraday/adapter/rack_spec.rb +8 -0
  65. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  66. data/spec/faraday/adapter_registry_spec.rb +28 -0
  67. data/spec/faraday/adapter_spec.rb +55 -0
  68. data/spec/faraday/composite_read_io_spec.rb +80 -0
  69. data/spec/faraday/connection_spec.rb +691 -0
  70. data/spec/faraday/error_spec.rb +0 -57
  71. data/spec/faraday/middleware_spec.rb +26 -0
  72. data/spec/faraday/options/env_spec.rb +70 -0
  73. data/spec/faraday/options/options_spec.rb +297 -0
  74. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  75. data/spec/faraday/options/request_options_spec.rb +19 -0
  76. data/spec/faraday/params_encoders/flat_spec.rb +34 -0
  77. data/spec/faraday/params_encoders/nested_spec.rb +134 -0
  78. data/spec/faraday/rack_builder_spec.rb +196 -0
  79. data/spec/faraday/request/authorization_spec.rb +88 -0
  80. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  81. data/spec/faraday/request/multipart_spec.rb +274 -0
  82. data/spec/faraday/request/retry_spec.rb +242 -0
  83. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  84. data/spec/faraday/request_spec.rb +109 -0
  85. data/spec/faraday/response/logger_spec.rb +220 -0
  86. data/spec/faraday/response/middleware_spec.rb +68 -0
  87. data/spec/faraday/response/raise_error_spec.rb +15 -15
  88. data/spec/faraday/response_spec.rb +75 -0
  89. data/spec/faraday/utils/headers_spec.rb +82 -0
  90. data/spec/faraday/utils_spec.rb +56 -0
  91. data/spec/faraday_spec.rb +37 -0
  92. data/spec/spec_helper.rb +63 -36
  93. data/spec/support/disabling_stub.rb +14 -0
  94. data/spec/support/fake_safe_buffer.rb +15 -0
  95. data/spec/support/helper_methods.rb +133 -0
  96. data/spec/support/shared_examples/adapter.rb +104 -0
  97. data/spec/support/shared_examples/params_encoder.rb +18 -0
  98. data/spec/support/shared_examples/request_method.rb +234 -0
  99. data/spec/support/streaming_response_checker.rb +35 -0
  100. data/spec/support/webmock_rack_app.rb +68 -0
  101. metadata +66 -38
  102. data/lib/faraday/deprecate.rb +0 -107
  103. data/lib/faraday/upload_io.rb +0 -67
  104. data/spec/faraday/deprecate_spec.rb +0 -69
  105. data/test/adapters/default_test.rb +0 -14
  106. data/test/adapters/em_http_test.rb +0 -30
  107. data/test/adapters/em_synchrony_test.rb +0 -32
  108. data/test/adapters/excon_test.rb +0 -30
  109. data/test/adapters/httpclient_test.rb +0 -34
  110. data/test/adapters/integration.rb +0 -263
  111. data/test/adapters/logger_test.rb +0 -136
  112. data/test/adapters/net_http_persistent_test.rb +0 -114
  113. data/test/adapters/net_http_test.rb +0 -79
  114. data/test/adapters/patron_test.rb +0 -40
  115. data/test/adapters/rack_test.rb +0 -38
  116. data/test/adapters/test_middleware_test.rb +0 -157
  117. data/test/adapters/typhoeus_test.rb +0 -38
  118. data/test/authentication_middleware_test.rb +0 -65
  119. data/test/composite_read_io_test.rb +0 -109
  120. data/test/connection_test.rb +0 -738
  121. data/test/env_test.rb +0 -268
  122. data/test/helper.rb +0 -75
  123. data/test/live_server.rb +0 -67
  124. data/test/middleware/instrumentation_test.rb +0 -88
  125. data/test/middleware/retry_test.rb +0 -282
  126. data/test/middleware_stack_test.rb +0 -260
  127. data/test/multibyte.txt +0 -1
  128. data/test/options_test.rb +0 -333
  129. data/test/parameters_test.rb +0 -157
  130. data/test/request_middleware_test.rb +0 -126
  131. data/test/response_middleware_test.rb +0 -72
  132. data/test/strawberry.rb +0 -2
  133. data/test/utils_test.rb +0 -98
@@ -1,6 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  class Adapter
3
- # This class is just a stub, the real adapter is in https://github.com/philsturgeon/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb
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
4
7
  class Typhoeus < Faraday::Adapter
5
8
  # Needs to define this method in order to support Typhoeus <= 1.3.0
6
9
  def call; 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,95 @@
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 =~ %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
- :EMSynchrony => 'em_synchrony',
57
- :EMHttp => 'em_http',
58
- :Typhoeus => 'typhoeus',
59
- :Patron => 'patron',
60
- :Excon => 'excon',
61
- :Test => 'test',
62
- :Rack => 'rack',
63
- :HTTPClient => 'httpclient'
61
+ NetHttp: 'net_http',
62
+ NetHttpPersistent: 'net_http_persistent',
63
+ EMSynchrony: 'em_synchrony',
64
+ EMHttp: 'em_http',
65
+ Typhoeus: 'typhoeus',
66
+ Patron: 'patron',
67
+ Excon: 'excon',
68
+ Test: 'test',
69
+ Rack: 'rack',
70
+ HTTPClient: 'httpclient'
64
71
  end
65
72
 
73
+ # Request represents a single HTTP request for a Faraday adapter to make.
74
+ # @see lib/faraday/request.rb Original class location
66
75
  class Request
67
76
  extend AutoloadHelper
68
77
  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'
78
+ UrlEncoded: 'url_encoded',
79
+ Multipart: 'multipart',
80
+ Retry: 'retry',
81
+ Authorization: 'authorization',
82
+ BasicAuthentication: 'basic_authentication',
83
+ TokenAuthentication: 'token_authentication',
84
+ Instrumentation: 'instrumentation'
76
85
  end
77
86
 
87
+ # Response represents the returned value of a sent Faraday request.
88
+ # @see lib/faraday/response.rb Original class location
78
89
  class Response
79
90
  extend AutoloadHelper
80
91
  autoload_all 'faraday/response',
81
- :RaiseError => 'raise_error',
82
- :Logger => 'logger'
92
+ RaiseError: 'raise_error',
93
+ Logger: 'logger'
83
94
  end
84
95
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
- # Public: Connection objects manage the default properties and the middleware
4
+ # Connection objects manage the default properties and the middleware
3
5
  # stack for fulfilling an HTTP request.
4
6
  #
5
- # Examples
7
+ # @example
6
8
  #
7
9
  # conn = Faraday::Connection.new 'http://sushi.com'
8
10
  #
@@ -12,51 +14,51 @@ module Faraday
12
14
  #
13
15
  class Connection
14
16
  # A Set of allowed HTTP verbs.
15
- METHODS = Set.new [:get, :post, :put, :delete, :head, :patch, :options]
17
+ METHODS = Set.new %i[get post put delete head patch options trace]
16
18
 
17
- # Public: Returns a Hash of URI query unencoded key/value pairs.
19
+ # @return [Hash] URI query unencoded key/value pairs.
18
20
  attr_reader :params
19
21
 
20
- # Public: Returns a Hash of unencoded HTTP header key/value pairs.
22
+ # @return [Hash] unencoded HTTP header key/value pairs.
21
23
  attr_reader :headers
22
24
 
23
- # Public: Returns a URI with the prefix used for all requests from this
24
- # Connection. This includes a default host name, scheme, port, and path.
25
+ # @return [String] a URI with the prefix used for all requests from this
26
+ # Connection. This includes a default host name, scheme, port, and path.
25
27
  attr_reader :url_prefix
26
28
 
27
- # Public: Returns the Faraday::Builder for this Connection.
29
+ # @return [Faraday::Builder] Builder for this Connection.
28
30
  attr_reader :builder
29
31
 
30
- # Public: Returns a Hash of the request options.
31
- attr_reader :options
32
-
33
- # Public: Returns a Hash of the SSL options.
32
+ # @return [Hash] SSL options.
34
33
  attr_reader :ssl
35
34
 
36
- # Public: Returns the parallel manager for this Connection.
35
+ # @return [Object] the parallel manager for this Connection.
37
36
  attr_reader :parallel_manager
38
37
 
39
- # Public: Sets the default parallel manager for this connection.
38
+ # Sets the default parallel manager for this connection.
40
39
  attr_writer :default_parallel_manager
41
40
 
42
- # Public: Gets or Sets the Hash proxy options.
43
- # attr_reader :proxy
41
+ # @return [Hash] proxy options.
42
+ attr_reader :proxy
44
43
 
45
- # Public: Initializes a new Faraday::Connection.
44
+ # Initializes a new Faraday::Connection.
46
45
  #
47
- # url - URI or String base URL to use as a prefix for all
46
+ # @param url [URI, String] URI or String base URL to use as a prefix for all
48
47
  # requests (optional).
49
- # options - Hash or Faraday::ConnectionOptions.
50
- # :url - URI or String base URL (default: "http:/").
51
- # :params - Hash of URI query unencoded key/value pairs.
52
- # :headers - Hash of unencoded HTTP header key/value pairs.
53
- # :request - Hash of request options.
54
- # :ssl - Hash of SSL options.
55
- # :proxy - URI, String or Hash of HTTP proxy options
56
- # (default: "http_proxy" environment variable).
57
- # :uri - URI or String
58
- # :user - String (optional)
59
- # :password - String (optional)
48
+ # @param options [Hash, Faraday::ConnectionOptions]
49
+ # @option options [URI, String] :url ('http:/') URI or String base URL
50
+ # @option options [Hash<String => String>] :params URI query unencoded
51
+ # key/value pairs.
52
+ # @option options [Hash<String => String>] :headers Hash of unencoded HTTP
53
+ # header key/value pairs.
54
+ # @option options [Hash] :request Hash of request options.
55
+ # @option options [Hash] :ssl Hash of SSL options.
56
+ # @option options [Hash, URI, String] :proxy proxy options, either as a URL
57
+ # or as a Hash
58
+ # @option options [URI, String] :proxy[:uri]
59
+ # @option options [String] :proxy[:user]
60
+ # @option options [String] :proxy[:password]
61
+ # @yield [self] after all setup has been done
60
62
  def initialize(url = nil, options = nil)
61
63
  options = ConnectionOptions.from(options)
62
64
 
@@ -74,7 +76,7 @@ module Faraday
74
76
 
75
77
  @builder = options.builder || begin
76
78
  # pass an empty block to Builder so it doesn't assume default middleware
77
- options.new_builder(block_given? ? Proc.new { |b| } : nil)
79
+ options.new_builder(block_given? ? proc { |b| } : nil)
78
80
  end
79
81
 
80
82
  self.url_prefix = url || 'http:/'
@@ -82,21 +84,31 @@ module Faraday
82
84
  @params.update(options.params) if options.params
83
85
  @headers.update(options.headers) if options.headers
84
86
 
85
- @manual_proxy = !!options.proxy
86
- @proxy = options.proxy ? ProxyOptions.from(options.proxy) : proxy_from_env(url)
87
- @temp_proxy = @proxy
87
+ initialize_proxy(url, options)
88
88
 
89
89
  yield(self) if block_given?
90
90
 
91
91
  @headers[:user_agent] ||= "Faraday v#{VERSION}"
92
92
  end
93
93
 
94
- # Public: Sets the Hash of URI query unencoded key/value pairs.
94
+ def initialize_proxy(url, options)
95
+ @manual_proxy = !!options.proxy
96
+ @proxy =
97
+ if options.proxy
98
+ ProxyOptions.from(options.proxy)
99
+ else
100
+ proxy_from_env(url)
101
+ end
102
+ end
103
+
104
+ # Sets the Hash of URI query unencoded key/value pairs.
105
+ # @param hash [Hash]
95
106
  def params=(hash)
96
107
  @params.replace hash
97
108
  end
98
109
 
99
- # Public: Sets the Hash of unencoded HTTP header key/value pairs.
110
+ # Sets the Hash of unencoded HTTP header key/value pairs.
111
+ # @param hash [Hash]
100
112
  def headers=(hash)
101
113
  @headers.replace hash
102
114
  end
@@ -105,71 +117,163 @@ module Faraday
105
117
 
106
118
  def_delegators :builder, :build, :use, :request, :response, :adapter, :app
107
119
 
108
- # Public: Makes an HTTP request without a body.
109
- #
110
- # url - The optional String base URL to use as a prefix for all
111
- # requests. Can also be the options Hash.
112
- # params - Hash of URI query unencoded key/value pairs.
113
- # headers - Hash of unencoded HTTP header key/value pairs.
120
+ # Closes the underlying resources and/or connections. In the case of
121
+ # persistent connections, this closes all currently open connections
122
+ # but does not prevent new connections from being made.
123
+ def close
124
+ app.close
125
+ end
126
+
127
+ # @!method get(url = nil, params = nil, headers = nil)
128
+ # Makes a GET HTTP request without a body.
129
+ # @!scope class
114
130
  #
115
- # Examples
131
+ # @param url [String] The optional String base URL to use as a prefix for
132
+ # all requests. Can also be the options Hash.
133
+ # @param params [Hash] Hash of URI query unencoded key/value pairs.
134
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
116
135
  #
117
- # conn.get '/items', {:page => 1}, :accept => 'application/json'
118
- # conn.head '/items/1'
136
+ # @example
137
+ # conn.get '/items', { page: 1 }, :accept => 'application/json'
119
138
  #
120
139
  # # ElasticSearch example sending a body with GET.
121
140
  # conn.get '/twitter/tweet/_search' do |req|
122
141
  # req.headers[:content_type] = 'application/json'
123
142
  # req.params[:routing] = 'kimchy'
124
- # req.body = JSON.generate(:query => {...})
143
+ # req.body = JSON.generate(query: {...})
125
144
  # end
126
145
  #
127
- # Yields a Faraday::Request for further request customizations.
128
- # Returns a Faraday::Response.
146
+ # @yield [Faraday::Request] for further request customizations
147
+ # @return [Faraday::Response]
148
+
149
+ # @!method head(url = nil, params = nil, headers = nil)
150
+ # Makes a HEAD HTTP request without a body.
151
+ # @!scope class
152
+ #
153
+ # @param url [String] The optional String base URL to use as a prefix for
154
+ # all requests. Can also be the options Hash.
155
+ # @param params [Hash] Hash of URI query unencoded key/value pairs.
156
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
157
+ #
158
+ # @example
159
+ # conn.head '/items/1'
160
+ #
161
+ # @yield [Faraday::Request] for further request customizations
162
+ # @return [Faraday::Response]
163
+
164
+ # @!method delete(url = nil, params = nil, headers = nil)
165
+ # Makes a DELETE HTTP request without a body.
166
+ # @!scope class
167
+ #
168
+ # @param url [String] The optional String base URL to use as a prefix for
169
+ # all requests. Can also be the options Hash.
170
+ # @param params [Hash] Hash of URI query unencoded key/value pairs.
171
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
172
+ #
173
+ # @example
174
+ # conn.delete '/items/1'
175
+ #
176
+ # @yield [Faraday::Request] for further request customizations
177
+ # @return [Faraday::Response]
178
+
179
+ # @!method trace(url = nil, params = nil, headers = nil)
180
+ # Makes a TRACE HTTP request without a body.
181
+ # @!scope class
129
182
  #
130
- # Signature
183
+ # @param url [String] The optional String base URL to use as a prefix for
184
+ # all requests. Can also be the options Hash.
185
+ # @param params [Hash] Hash of URI query unencoded key/value pairs.
186
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
131
187
  #
132
- # <verb>(url = nil, params = nil, headers = nil)
188
+ # @example
189
+ # conn.connect '/items/1'
133
190
  #
134
- # verb - An HTTP verb: get, head, or delete.
135
- %w[get head delete].each do |method|
191
+ # @yield [Faraday::Request] for further request customizations
192
+ # @return [Faraday::Response]
193
+
194
+ # @!visibility private
195
+ METHODS_WITH_QUERY.each do |method|
136
196
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
137
197
  def #{method}(url = nil, params = nil, headers = nil)
138
- run_request(:#{method}, url, nil, headers) { |request|
198
+ run_request(:#{method}, url, nil, headers) do |request|
139
199
  request.params.update(params) if params
140
- yield(request) if block_given?
141
- }
200
+ yield request if block_given?
201
+ end
142
202
  end
143
203
  RUBY
144
204
  end
145
205
 
146
- # Public: Makes an HTTP request with a body.
206
+ # @overload options()
207
+ # Returns current Connection options.
208
+ #
209
+ # @overload options(url, params = nil, headers = nil)
210
+ # Makes an OPTIONS HTTP request to the given URL.
211
+ # @param url [String] String base URL to sue as a prefix for all requests.
212
+ # @param params [Hash] Hash of URI query unencoded key/value pairs.
213
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
214
+ #
215
+ # @example
216
+ # conn.options '/items/1'
147
217
  #
148
- # url - The optional String base URL to use as a prefix for all
149
- # requests. Can also be the options Hash.
150
- # body - The String body for the request.
151
- # headers - Hash of unencoded HTTP header key/value pairs.
218
+ # @yield [Faraday::Request] for further request customizations
219
+ # @return [Faraday::Response]
220
+ def options(*args)
221
+ return @options if args.size.zero?
222
+
223
+ url, params, headers = *args
224
+ run_request(:options, url, nil, headers) do |request|
225
+ request.params.update(params) if params
226
+ yield request if block_given?
227
+ end
228
+ end
229
+
230
+ # @!method post(url = nil, body = nil, headers = nil)
231
+ # Makes a POST HTTP request with a body.
232
+ # @!scope class
152
233
  #
153
- # Examples
234
+ # @param url [String] The optional String base URL to use as a prefix for
235
+ # all requests. Can also be the options Hash.
236
+ # @param body [String] body for the request.
237
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
154
238
  #
155
- # conn.post '/items', data, :content_type => 'application/json'
239
+ # @example
240
+ # conn.post '/items', data, content_type: 'application/json'
156
241
  #
157
242
  # # Simple ElasticSearch indexing sample.
158
243
  # conn.post '/twitter/tweet' do |req|
159
244
  # req.headers[:content_type] = 'application/json'
160
245
  # req.params[:routing] = 'kimchy'
161
- # req.body = JSON.generate(:user => 'kimchy', ...)
246
+ # req.body = JSON.generate(user: 'kimchy', ...)
162
247
  # end
163
248
  #
164
- # Yields a Faraday::Request for further request customizations.
165
- # Returns a Faraday::Response.
249
+ # @yield [Faraday::Request] for further request customizations
250
+ # @return [Faraday::Response]
251
+
252
+ # @!method put(url = nil, body = nil, headers = nil)
253
+ # Makes a PUT HTTP request with a body.
254
+ # @!scope class
255
+ #
256
+ # @param url [String] The optional String base URL to use as a prefix for
257
+ # all requests. Can also be the options Hash.
258
+ # @param body [String] body for the request.
259
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
166
260
  #
167
- # Signature
261
+ # @example
262
+ # # TODO: Make it a PUT example
263
+ # conn.post '/items', data, content_type: 'application/json'
168
264
  #
169
- # <verb>(url = nil, body = nil, headers = nil)
265
+ # # Simple ElasticSearch indexing sample.
266
+ # conn.post '/twitter/tweet' do |req|
267
+ # req.headers[:content_type] = 'application/json'
268
+ # req.params[:routing] = 'kimchy'
269
+ # req.body = JSON.generate(user: 'kimchy', ...)
270
+ # end
170
271
  #
171
- # verb - An HTTP verb: post, put, or patch.
172
- %w[post put patch].each do |method|
272
+ # @yield [Faraday::Request] for further request customizations
273
+ # @return [Faraday::Response]
274
+
275
+ # @!visibility private
276
+ METHODS_WITH_BODY.each do |method|
173
277
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
174
278
  def #{method}(url = nil, body = nil, headers = nil, &block)
175
279
  run_request(:#{method}, url, body, headers, &block)
@@ -177,116 +281,110 @@ module Faraday
177
281
  RUBY
178
282
  end
179
283
 
180
- # Public: Sets up the Authorization header with these credentials, encoded
284
+ # Sets up the Authorization header with these credentials, encoded
181
285
  # with base64.
182
286
  #
183
- # login - The authentication login.
184
- # pass - The authentication password.
287
+ # @param login [String] The authentication login.
288
+ # @param pass [String] The authentication password.
185
289
  #
186
- # Examples
290
+ # @example
187
291
  #
188
292
  # conn.basic_auth 'Aladdin', 'open sesame'
189
293
  # conn.headers['Authorization']
190
294
  # # => "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=="
191
295
  #
192
- # Returns nothing.
296
+ # @return [void]
193
297
  def basic_auth(login, pass)
194
298
  set_authorization_header(:basic_auth, login, pass)
195
299
  end
196
300
 
197
- # Public: Sets up the Authorization header with the given token.
301
+ # Sets up the Authorization header with the given token.
198
302
  #
199
- # token - The String token.
200
- # options - Optional Hash of extra token options.
303
+ # @param token [String]
304
+ # @param options [Hash] extra token options.
201
305
  #
202
- # Examples
306
+ # @example
203
307
  #
204
- # conn.token_auth 'abcdef', :foo => 'bar'
308
+ # conn.token_auth 'abcdef', foo: 'bar'
205
309
  # conn.headers['Authorization']
206
310
  # # => "Token token=\"abcdef\",
207
311
  # foo=\"bar\""
208
312
  #
209
- # Returns nothing.
313
+ # @return [void]
210
314
  def token_auth(token, options = nil)
211
315
  set_authorization_header(:token_auth, token, options)
212
316
  end
213
317
 
214
- # Public: Sets up a custom Authorization header.
318
+ # Sets up a custom Authorization header.
215
319
  #
216
- # type - The String authorization type.
217
- # token - The String or Hash token. A String value is taken literally, and
218
- # a Hash is encoded into comma separated key/value pairs.
320
+ # @param type [String] authorization type
321
+ # @param token [String, Hash] token. A String value is taken literally, and
322
+ # a Hash is encoded into comma-separated key/value pairs.
219
323
  #
220
- # Examples
324
+ # @example
221
325
  #
222
326
  # conn.authorization :Bearer, 'mF_9.B5f-4.1JqM'
223
327
  # conn.headers['Authorization']
224
328
  # # => "Bearer mF_9.B5f-4.1JqM"
225
329
  #
226
- # conn.authorization :Token, :token => 'abcdef', :foo => 'bar'
330
+ # conn.authorization :Token, token: 'abcdef', foo: 'bar'
227
331
  # conn.headers['Authorization']
228
332
  # # => "Token token=\"abcdef\",
229
333
  # foo=\"bar\""
230
334
  #
231
- # Returns nothing.
335
+ # @return [void]
232
336
  def authorization(type, token)
233
337
  set_authorization_header(:authorization, type, token)
234
338
  end
235
339
 
236
- # Internal: Traverse the middleware stack in search of a
237
- # parallel-capable adapter.
340
+ # Check if the adapter is parallel-capable.
238
341
  #
239
- # Yields in case of not found.
342
+ # @yield if the adapter isn't parallel-capable, or if no adapter is set yet.
240
343
  #
241
- # Returns a parallel manager or nil if not found.
344
+ # @return [Object, nil] a parallel manager or nil if yielded
345
+ # @api private
242
346
  def default_parallel_manager
243
347
  @default_parallel_manager ||= begin
244
- handler = @builder.handlers.detect do |h|
245
- h.klass.respond_to?(:supports_parallel?) and h.klass.supports_parallel?
246
- end
348
+ adapter = @builder.adapter.klass if @builder.adapter
247
349
 
248
- if handler
249
- handler.klass.setup_parallel_manager
350
+ if support_parallel?(adapter)
351
+ adapter.setup_parallel_manager
250
352
  elsif block_given?
251
353
  yield
252
354
  end
253
355
  end
254
356
  end
255
357
 
256
- # Public: Determine if this Faraday::Connection can make parallel requests.
358
+ # Determine if this Faraday::Connection can make parallel requests.
257
359
  #
258
- # Returns true or false.
360
+ # @return [Boolean]
259
361
  def in_parallel?
260
362
  !!@parallel_manager
261
363
  end
262
364
 
263
- # Public: Sets up the parallel manager to make a set of requests.
365
+ # Sets up the parallel manager to make a set of requests.
264
366
  #
265
- # manager - The parallel manager that this Connection's Adapter uses.
367
+ # @param manager [Object] The parallel manager that this Connection's
368
+ # Adapter uses.
266
369
  #
267
- # Yields a block to execute multiple requests.
268
- # Returns nothing.
370
+ # @yield a block to execute multiple requests.
371
+ # @return [void]
269
372
  def in_parallel(manager = nil)
270
- @parallel_manager = manager || default_parallel_manager {
271
- warn "Warning: `in_parallel` called but no parallel-capable adapter on Faraday stack"
272
- warn caller[2,10].join("\n")
373
+ @parallel_manager = manager || default_parallel_manager do
374
+ warn 'Warning: `in_parallel` called but no parallel-capable adapter ' \
375
+ 'on Faraday stack'
376
+ warn caller[2, 10].join("\n")
273
377
  nil
274
- }
378
+ end
275
379
  yield
276
- @parallel_manager && @parallel_manager.run
380
+ @parallel_manager&.run
277
381
  ensure
278
382
  @parallel_manager = nil
279
383
  end
280
384
 
281
- # Public: Gets or Sets the Hash proxy options.
282
- def proxy(arg = nil)
283
- return @proxy if arg.nil?
284
- warn 'Warning: use of proxy(new_value) to set connection proxy have been DEPRECATED and will be removed in Faraday 1.0'
285
- @manual_proxy = true
286
- @proxy = ProxyOptions.from(arg)
287
- end
288
-
289
- # Public: Sets the Hash proxy options.
385
+ # Sets the Hash proxy options.
386
+ #
387
+ # @param new_value [Object]
290
388
  def proxy=(new_value)
291
389
  @manual_proxy = true
292
390
  @proxy = new_value ? ProxyOptions.from(new_value) : nil
@@ -295,13 +393,14 @@ module Faraday
295
393
  def_delegators :url_prefix, :scheme, :scheme=, :host, :host=, :port, :port=
296
394
  def_delegator :url_prefix, :path, :path_prefix
297
395
 
298
- # Public: Parses the giving url with URI and stores the individual
299
- # components in this connection. These components serve as defaults for
396
+ # Parses the given URL with URI and stores the individual
397
+ # components in this connection. These components serve as defaults for
300
398
  # requests made by this connection.
301
399
  #
302
- # url - A String or URI.
400
+ # @param url [String, URI]
401
+ # @param encoder [Object]
303
402
  #
304
- # Examples
403
+ # @example
305
404
  #
306
405
  # conn = Faraday::Connection.new { ... }
307
406
  # conn.url_prefix = "https://sushi.com/api"
@@ -309,8 +408,6 @@ module Faraday
309
408
  # conn.path_prefix # => "/api"
310
409
  #
311
410
  # conn.get("nigiri?page=2") # accesses https://sushi.com/api/nigiri
312
- #
313
- # Returns the parsed URI from the given input..
314
411
  def url_prefix=(url, encoder = nil)
315
412
  uri = @url_prefix = Utils.URI(url)
316
413
  self.path_prefix = uri.path
@@ -322,62 +419,70 @@ module Faraday
322
419
  basic_auth user, password
323
420
  uri.user = uri.password = nil
324
421
  end
325
-
326
- uri
327
422
  end
328
423
 
329
- # Public: Sets the path prefix and ensures that it always has a leading
424
+ # Sets the path prefix and ensures that it always has a leading
330
425
  # slash.
331
426
  #
332
- # value - A String.
427
+ # @param value [String]
333
428
  #
334
- # Returns the new String path prefix.
429
+ # @return [String] the new path prefix
335
430
  def path_prefix=(value)
336
431
  url_prefix.path = if value
337
- value = '/' + value unless value[0,1] == '/'
338
- value
339
- end
432
+ value = '/' + value unless value[0, 1] == '/'
433
+ value
434
+ end
340
435
  end
341
436
 
342
- # Public: Takes a relative url for a request and combines it with the defaults
437
+ # Takes a relative url for a request and combines it with the defaults
343
438
  # set on the connection instance.
344
439
  #
440
+ # @param url [String]
441
+ # @param extra_params [Hash]
442
+ #
443
+ # @example
345
444
  # conn = Faraday::Connection.new { ... }
346
445
  # conn.url_prefix = "https://sushi.com/api?token=abc"
347
446
  # conn.scheme # => https
348
447
  # conn.path_prefix # => "/api"
349
448
  #
350
- # conn.build_url("nigiri?page=2") # => https://sushi.com/api/nigiri?token=abc&page=2
351
- # conn.build_url("nigiri", :page => 2) # => https://sushi.com/api/nigiri?token=abc&page=2
449
+ # conn.build_url("nigiri?page=2")
450
+ # # => https://sushi.com/api/nigiri?token=abc&page=2
451
+ #
452
+ # conn.build_url("nigiri", page: 2)
453
+ # # => https://sushi.com/api/nigiri?token=abc&page=2
352
454
  #
353
455
  def build_url(url = nil, extra_params = nil)
354
456
  uri = build_exclusive_url(url)
355
457
 
356
458
  query_values = params.dup.merge_query(uri.query, options.params_encoder)
357
- query_values.update extra_params if extra_params
358
- uri.query = query_values.empty? ? nil : query_values.to_query(options.params_encoder)
459
+ query_values.update(extra_params) if extra_params
460
+ uri.query =
461
+ if query_values.empty?
462
+ nil
463
+ else
464
+ query_values.to_query(options.params_encoder)
465
+ end
359
466
 
360
467
  uri
361
468
  end
362
469
 
363
470
  # Builds and runs the Faraday::Request.
364
471
  #
365
- # method - The Symbol HTTP method.
366
- # url - The String or URI to access.
367
- # body - The request body that will eventually be converted to a string.
368
- # headers - Hash of unencoded HTTP header key/value pairs.
472
+ # @param method [Symbol] HTTP method.
473
+ # @param url [String, URI] String or URI to access.
474
+ # @param body [Object] The request body that will eventually be converted to
475
+ # a string.
476
+ # @param headers [Hash] unencoded HTTP header key/value pairs.
369
477
  #
370
- # Returns a Faraday::Response.
478
+ # @return [Faraday::Response]
371
479
  def run_request(method, url, body, headers)
372
- if !METHODS.include?(method)
480
+ unless METHODS.include?(method)
373
481
  raise ArgumentError, "unknown http method: #{method}"
374
482
  end
375
483
 
376
- # Resets temp_proxy
377
- @temp_proxy = proxy_for_request(url)
378
-
379
484
  request = build_request(method) do |req|
380
- req.options = req.options.merge(:proxy => @temp_proxy)
485
+ req.options.proxy = proxy_for_request(url)
381
486
  req.url(url) if url
382
487
  req.headers.update(headers) if headers
383
488
  req.body = body if body
@@ -389,73 +494,93 @@ module Faraday
389
494
 
390
495
  # Creates and configures the request object.
391
496
  #
392
- # Returns the new Request.
497
+ # @param method [Symbol]
498
+ #
499
+ # @yield [Faraday::Request] if block given
500
+ # @return [Faraday::Request]
393
501
  def build_request(method)
394
502
  Request.create(method) do |req|
395
- req.params = self.params.dup
396
- req.headers = self.headers.dup
397
- req.options = self.options
503
+ req.params = params.dup
504
+ req.headers = headers.dup
505
+ req.options = options.dup
398
506
  yield(req) if block_given?
399
507
  end
400
508
  end
401
509
 
402
- # Internal: Build an absolute URL based on url_prefix.
510
+ # Build an absolute URL based on url_prefix.
403
511
  #
404
- # url - A String or URI-like object
405
- # params - A Faraday::Utils::ParamsHash to replace the query values
512
+ # @param url [String, URI]
513
+ # @param params [Faraday::Utils::ParamsHash] A Faraday::Utils::ParamsHash to
514
+ # replace the query values
406
515
  # of the resulting url (default: nil).
407
516
  #
408
- # Returns the resulting URI instance.
517
+ # @return [URI]
409
518
  def build_exclusive_url(url = nil, params = nil, params_encoder = nil)
410
- url = nil if url.respond_to?(:empty?) and url.empty?
519
+ url = nil if url.respond_to?(:empty?) && url.empty?
411
520
  base = url_prefix
412
- if url and base.path and base.path !~ /\/$/
521
+ if url && base.path && base.path !~ %r{/$}
413
522
  base = base.dup
414
- base.path = base.path + '/' # ensure trailing slash
523
+ base.path = base.path + '/' # ensure trailing slash
415
524
  end
416
525
  uri = url ? base + url : base
417
- uri.query = params.to_query(params_encoder || options.params_encoder) if params
418
- uri.query = nil if uri.query and uri.query.empty?
526
+ if params
527
+ uri.query = params.to_query(params_encoder || options.params_encoder)
528
+ end
529
+ # rubocop:disable Style/SafeNavigation
530
+ uri.query = nil if uri.query && uri.query.empty?
531
+ # rubocop:enable Style/SafeNavigation
419
532
  uri
420
533
  end
421
534
 
422
- # Internal: Creates a duplicate of this Faraday::Connection.
535
+ # Creates a duplicate of this Faraday::Connection.
423
536
  #
424
- # Returns a Faraday::Connection.
537
+ # @api private
538
+ #
539
+ # @return [Faraday::Connection]
425
540
  def dup
426
541
  self.class.new(build_exclusive_url,
427
- :headers => headers.dup,
428
- :params => params.dup,
429
- :builder => builder.dup,
430
- :ssl => ssl.dup,
431
- :request => options.dup)
542
+ headers: headers.dup,
543
+ params: params.dup,
544
+ builder: builder.dup,
545
+ ssl: ssl.dup,
546
+ request: options.dup)
432
547
  end
433
548
 
434
- # Internal: Yields username and password extracted from a URI if they both exist.
549
+ # Yields username and password extracted from a URI if they both exist.
550
+ #
551
+ # @param uri [URI]
552
+ # @yield [username, password] any username and password
553
+ # @yieldparam username [String] any username from URI
554
+ # @yieldparam password [String] any password from URI
555
+ # @return [void]
556
+ # @api private
435
557
  def with_uri_credentials(uri)
436
- if uri.user and uri.password
437
- yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
438
- end
558
+ return unless uri.user && uri.password
559
+
560
+ yield(Utils.unescape(uri.user), Utils.unescape(uri.password))
439
561
  end
440
562
 
441
563
  def set_authorization_header(header_type, *args)
442
- header = Faraday::Request.lookup_middleware(header_type).
443
- header(*args)
564
+ header = Faraday::Request
565
+ .lookup_middleware(header_type)
566
+ .header(*args)
567
+
444
568
  headers[Faraday::Request::Authorization::KEY] = header
445
569
  end
446
570
 
447
571
  def proxy_from_env(url)
448
572
  return if Faraday.ignore_env_proxy
573
+
449
574
  uri = nil
450
575
  if URI.parse('').respond_to?(:find_proxy)
451
576
  case url
452
577
  when String
453
- uri = Utils.URI(url)
454
- uri = URI.parse("#{uri.scheme}://#{uri.hostname}").find_proxy
455
- when URI
456
- uri = url.find_proxy
457
- when nil
458
- uri = find_default_proxy
578
+ uri = Utils.URI(url)
579
+ uri = URI.parse("#{uri.scheme}://#{uri.hostname}").find_proxy
580
+ when URI
581
+ uri = url.find_proxy
582
+ when nil
583
+ uri = find_default_proxy
459
584
  end
460
585
  else
461
586
  warn 'no_proxy is unsupported' if ENV['no_proxy'] || ENV['NO_PROXY']
@@ -466,19 +591,24 @@ module Faraday
466
591
 
467
592
  def find_default_proxy
468
593
  uri = ENV['http_proxy']
469
- if uri && !uri.empty?
470
- uri = 'http://' + uri if uri !~ /^http/i
471
- uri
472
- end
594
+ return unless uri && !uri.empty?
595
+
596
+ uri = 'http://' + uri if uri !~ /^http/i
597
+ uri
473
598
  end
474
599
 
475
600
  def proxy_for_request(url)
476
- return self.proxy if @manual_proxy
601
+ return proxy if @manual_proxy
602
+
477
603
  if url && Utils.URI(url).absolute?
478
604
  proxy_from_env(url)
479
605
  else
480
- self.proxy
606
+ proxy
481
607
  end
482
608
  end
609
+
610
+ def support_parallel?(adapter)
611
+ adapter&.respond_to?(:supports_parallel?) && adapter&.supports_parallel?
612
+ end
483
613
  end
484
614
  end