/
faraday.rb
287 lines (261 loc) · 9.05 KB
/
faraday.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
require 'thread'
require 'cgi'
require 'set'
require 'forwardable'
# This is the main namespace for Faraday.
#
# It provides methods to create {Connection} objects, and HTTP-related
# methods to use directly.
#
# @example Helpful class methods for easy usage
# Faraday.get "http://faraday.com"
#
# @example Helpful class method `.new` to create {Connection} objects.
# conn = Faraday.new "http://faraday.com"
# conn.get '/'
#
module Faraday
VERSION = "0.15.3"
METHODS_WITH_QUERY = %w[get head delete]
METHODS_WITH_BODY = %w[post put patch]
class << self
# The root path that Faraday is being loaded from.
#
# This is the root from where the libraries are auto-loaded.
#
# @return [String]
attr_accessor :root_path
# Gets or sets the path that the Faraday libs are loaded from.
# @return [String]
attr_accessor :lib_path
# @overload default_adapter
# Gets the Symbol key identifying a default Adapter to use
# for the default {Faraday::Connection}. Defaults to `:net_http`.
# @return [Symbol] the default adapter
# @overload default_adapter=(adapter)
# Updates default adapter while resetting {.default_connection}.
# @return [Symbol] the new default_adapter.
attr_reader :default_adapter
# Documented below, see default_connection
attr_writer :default_connection
# Tells Faraday to ignore the environment proxy (http_proxy). Defaults to `false`.
# @return [Boolean]
attr_accessor :ignore_env_proxy
# Initializes a new {Connection}.
#
# @param url [String,Hash] The optional String base URL to use as a prefix for all
# requests. Can also be the options Hash. Any of these values
# will be set on every request made, unless overridden for a
# specific request.
# @param options [Hash]
# @option options [String] :url Base URL
# @option options [Hash] :params Hash of URI query unencoded key/value pairs.
# @option options [Hash] :headers Hash of unencoded HTTP header key/value pairs.
# @option options [Hash] :request Hash of request options.
# @option options [Hash] :ssl Hash of SSL options.
# @option options [Hash] :proxy Hash of Proxy options.
# @return [Faraday::Connection]
#
# @example With an URL argument
# Faraday.new 'http://faraday.com'
# # => Faraday::Connection to http://faraday.com
#
# @example With an URL argument and an options hash
# Faraday.new 'http://faraday.com', :params => {:page => 1}
# # => Faraday::Connection to http://faraday.com?page=1
#
# @example With everything in an options hash
# Faraday.new :url => 'http://faraday.com',
# :params => {:page => 1}
# # => Faraday::Connection to http://faraday.com?page=1
def new(url = nil, options = nil)
block = block_given? ? Proc.new : nil
options = options ? default_connection_options.merge(options) : default_connection_options
Faraday::Connection.new(url, options, &block)
end
# @private
# Internal: Requires internal Faraday libraries.
#
# @param libs [Array] one or more relative String names to Faraday classes.
# @return [void]
def require_libs(*libs)
libs.each do |lib|
require "#{lib_path}/#{lib}"
end
end
alias require_lib require_libs
# Documented elsewhere, see default_adapter reader
def default_adapter=(adapter)
@default_connection = nil
@default_adapter = adapter
end
def respond_to?(symbol, include_private = false)
default_connection.respond_to?(symbol, include_private) || super
end
private
# Internal: Proxies method calls on the Faraday constant to
# .default_connection.
def method_missing(name, *args, &block)
default_connection.send(name, *args, &block)
end
end
self.ignore_env_proxy = false
self.root_path = File.expand_path "..", __FILE__
self.lib_path = File.expand_path "../faraday", __FILE__
self.default_adapter = :net_http
# @overload default_connection
# Gets the default connection used for simple scripts.
# @return [Faraday::Connection] a connection configured with the {.default_adapter}.
# @overload default_connection=(connection)
# @param connection [Faraday::Connection]
# Sets the default {Faraday::Connection} for simple scripts that
# access the Faraday constant directly, such as <code>Faraday.get "https://faraday.com"</code>.
def self.default_connection
@default_connection ||= Connection.new(default_connection_options)
end
# Gets the default connection options used when calling {Faraday#new}.
#
# @return [Faraday::ConnectionOptions]
def self.default_connection_options
@default_connection_options ||= ConnectionOptions.new
end
# Sets the default options used when calling {Faraday#new}.
#
# @param options [Hash, Faraday::ConnectionOptions]
def self.default_connection_options=(options)
@default_connection = nil
@default_connection_options = ConnectionOptions.from(options)
end
unless const_defined? :Timer
require 'timeout'
Timer = Timeout
end
# Adds the ability for other modules to register and lookup
# middleware classes.
module MiddlewareRegistry
# Register middleware class(es) on the current module.
#
# @param autoload_path [String] Middleware autoload path
# @param mapping [Hash{Symbol => Module, Symbol, Array<Module, Symbol, String>}] Middleware mapping from a lookup symbol to a reference to the middleware. - Classes can be expressed as:
# - a fully qualified constant
# - a Symbol
# - a Proc that will be lazily called to return the former
# - an array is given, its first element is the constant or symbol,
# and its second is a file to `require`.
# @return [void]
#
# @example Lookup by a constant
#
# module Faraday
# class Whatever
# # Middleware looked up by :foo returns Faraday::Whatever::Foo.
# register_middleware :foo => Foo
# end
# end
#
# @example Lookup by a symbol
#
# module Faraday
# class Whatever
# # Middleware looked up by :bar returns Faraday::Whatever.const_get(:Bar)
# register_middleware :bar => :Bar
# end
# end
#
# @example Lookup by a symbol and string in an array
#
# module Faraday
# class Whatever
# # Middleware looked up by :baz requires 'baz' and returns Faraday::Whatever.const_get(:Baz)
# register_middleware :baz => [:Baz, 'baz']
# end
# end
#
def register_middleware(autoload_path = nil, mapping = nil)
if mapping.nil?
mapping = autoload_path
autoload_path = nil
end
middleware_mutex do
@middleware_autoload_path = autoload_path if autoload_path
(@registered_middleware ||= {}).update(mapping)
end
end
# Unregister a previously registered middleware class.
#
# @param key [Symbol] key for the registered middleware.
def unregister_middleware(key)
@registered_middleware.delete(key)
end
# Lookup middleware class with a registered Symbol shortcut.
#
# @param key [Symbol] key for the registered middleware.
# @return [Class] a middleware Class.
# @raise [Faraday::Error] if given key is not registered
#
# @example
#
# module Faraday
# class Whatever
# register_middleware :foo => Foo
# end
# end
#
# Faraday::Whatever.lookup_middleware(:foo)
# # => Faraday::Whatever::Foo
#
def lookup_middleware(key)
load_middleware(key) ||
raise(Faraday::Error.new("#{key.inspect} is not registered on #{self}"))
end
def middleware_mutex(&block)
@middleware_mutex ||= begin
require 'monitor'
Monitor.new
end
@middleware_mutex.synchronize(&block)
end
def fetch_middleware(key)
defined?(@registered_middleware) && @registered_middleware[key]
end
def load_middleware(key)
value = fetch_middleware(key)
case value
when Module
value
when Symbol, String
middleware_mutex do
@registered_middleware[key] = const_get(value)
end
when Proc
middleware_mutex do
@registered_middleware[key] = value.call
end
when Array
middleware_mutex do
const, path = value
if root = @middleware_autoload_path
path = "#{root}/#{path}"
end
require(path)
@registered_middleware[key] = const
end
load_middleware(key)
end
end
end
# @private
def self.const_missing(name)
if name.to_sym == :Builder
warn "Faraday::Builder is now Faraday::RackBuilder."
const_set name, RackBuilder
else
super
end
end
require_libs "utils", "options", "connection", "rack_builder", "parameters",
"middleware", "adapter", "request", "response", "upload_io", "error"
if !ENV["FARADAY_NO_AUTOLOAD"]
require_lib 'autoload'
end
end