faraday 0.12.2 → 1.3.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 (105) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +350 -0
  3. data/LICENSE.md +1 -1
  4. data/README.md +22 -325
  5. data/Rakefile +7 -0
  6. data/examples/client_spec.rb +65 -0
  7. data/examples/client_test.rb +79 -0
  8. data/lib/faraday.rb +120 -188
  9. data/lib/faraday/adapter.rb +84 -22
  10. data/lib/faraday/adapter/em_http.rb +150 -104
  11. data/lib/faraday/adapter/em_http_ssl_patch.rb +24 -18
  12. data/lib/faraday/adapter/em_synchrony.rb +110 -63
  13. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +18 -15
  14. data/lib/faraday/adapter/excon.rb +98 -54
  15. data/lib/faraday/adapter/httpclient.rb +83 -59
  16. data/lib/faraday/adapter/net_http_persistent.rb +68 -27
  17. data/lib/faraday/adapter/patron.rb +86 -37
  18. data/lib/faraday/adapter/rack.rb +30 -13
  19. data/lib/faraday/adapter/test.rb +103 -62
  20. data/lib/faraday/adapter/typhoeus.rb +7 -115
  21. data/lib/faraday/adapter_registry.rb +30 -0
  22. data/lib/faraday/autoload.rb +46 -36
  23. data/lib/faraday/connection.rb +336 -177
  24. data/lib/faraday/dependency_loader.rb +37 -0
  25. data/lib/faraday/encoders/flat_params_encoder.rb +105 -0
  26. data/lib/faraday/encoders/nested_params_encoder.rb +176 -0
  27. data/lib/faraday/error.rb +126 -37
  28. data/lib/faraday/file_part.rb +128 -0
  29. data/lib/faraday/logging/formatter.rb +105 -0
  30. data/lib/faraday/methods.rb +6 -0
  31. data/lib/faraday/middleware.rb +19 -25
  32. data/lib/faraday/middleware_registry.rb +129 -0
  33. data/lib/faraday/options.rb +39 -193
  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 -196
  41. data/lib/faraday/rack_builder.rb +77 -63
  42. data/lib/faraday/request.rb +94 -32
  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 +86 -48
  47. data/lib/faraday/request/retry.rb +209 -134
  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 +27 -23
  51. data/lib/faraday/response/logger.rb +22 -69
  52. data/lib/faraday/response/raise_error.rb +49 -14
  53. data/lib/faraday/utils.rb +38 -247
  54. data/lib/faraday/utils/headers.rb +139 -0
  55. data/lib/faraday/utils/params_hash.rb +61 -0
  56. data/lib/faraday/version.rb +5 -0
  57. data/spec/external_adapters/faraday_specs_setup.rb +14 -0
  58. data/spec/faraday/adapter/em_http_spec.rb +47 -0
  59. data/spec/faraday/adapter/em_synchrony_spec.rb +16 -0
  60. data/spec/faraday/adapter/excon_spec.rb +49 -0
  61. data/spec/faraday/adapter/httpclient_spec.rb +73 -0
  62. data/spec/faraday/adapter/net_http_persistent_spec.rb +57 -0
  63. data/spec/faraday/adapter/net_http_spec.rb +64 -0
  64. data/spec/faraday/adapter/patron_spec.rb +18 -0
  65. data/spec/faraday/adapter/rack_spec.rb +8 -0
  66. data/spec/faraday/adapter/test_spec.rb +260 -0
  67. data/spec/faraday/adapter/typhoeus_spec.rb +7 -0
  68. data/spec/faraday/adapter_registry_spec.rb +28 -0
  69. data/spec/faraday/adapter_spec.rb +55 -0
  70. data/spec/faraday/composite_read_io_spec.rb +80 -0
  71. data/spec/faraday/connection_spec.rb +691 -0
  72. data/spec/faraday/error_spec.rb +60 -0
  73. data/spec/faraday/middleware_spec.rb +52 -0
  74. data/spec/faraday/options/env_spec.rb +70 -0
  75. data/spec/faraday/options/options_spec.rb +297 -0
  76. data/spec/faraday/options/proxy_options_spec.rb +37 -0
  77. data/spec/faraday/options/request_options_spec.rb +19 -0
  78. data/spec/faraday/params_encoders/flat_spec.rb +42 -0
  79. data/spec/faraday/params_encoders/nested_spec.rb +142 -0
  80. data/spec/faraday/rack_builder_spec.rb +345 -0
  81. data/spec/faraday/request/authorization_spec.rb +88 -0
  82. data/spec/faraday/request/instrumentation_spec.rb +76 -0
  83. data/spec/faraday/request/multipart_spec.rb +302 -0
  84. data/spec/faraday/request/retry_spec.rb +242 -0
  85. data/spec/faraday/request/url_encoded_spec.rb +83 -0
  86. data/spec/faraday/request_spec.rb +120 -0
  87. data/spec/faraday/response/logger_spec.rb +220 -0
  88. data/spec/faraday/response/middleware_spec.rb +68 -0
  89. data/spec/faraday/response/raise_error_spec.rb +169 -0
  90. data/spec/faraday/response_spec.rb +75 -0
  91. data/spec/faraday/utils/headers_spec.rb +82 -0
  92. data/spec/faraday/utils_spec.rb +56 -0
  93. data/spec/faraday_spec.rb +37 -0
  94. data/spec/spec_helper.rb +132 -0
  95. data/spec/support/disabling_stub.rb +14 -0
  96. data/spec/support/fake_safe_buffer.rb +15 -0
  97. data/spec/support/helper_methods.rb +133 -0
  98. data/spec/support/shared_examples/adapter.rb +105 -0
  99. data/spec/support/shared_examples/params_encoder.rb +18 -0
  100. data/spec/support/shared_examples/request_method.rb +262 -0
  101. data/spec/support/streaming_response_checker.rb +35 -0
  102. data/spec/support/webmock_rack_app.rb +68 -0
  103. metadata +109 -10
  104. data/lib/faraday/adapter/net_http.rb +0 -135
  105. data/lib/faraday/upload_io.rb +0 -67
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stringio'
4
+
5
+ # multipart-post gem
6
+ require 'composite_io'
7
+ require 'parts'
8
+
9
+ module Faraday
10
+ # Multipart value used to POST a binary data from a file or
11
+ #
12
+ # @example
13
+ # payload = { file: Faraday::FilePart.new("file_name.ext", "content/type") }
14
+ # http.post("/upload", payload)
15
+ #
16
+
17
+ # @!method initialize(filename_or_io, content_type, filename = nil, opts = {})
18
+ #
19
+ # @param filename_or_io [String, IO] Either a String filename to a local
20
+ # file or an open IO object.
21
+ # @param content_type [String] String content type of the file data.
22
+ # @param filename [String] Optional String filename, usually to add context
23
+ # to a given IO object.
24
+ # @param opts [Hash] Optional Hash of String key/value pairs to describethis
25
+ # this uploaded file. Expected Header keys include:
26
+ # * Content-Transfer-Encoding - Defaults to "binary"
27
+ # * Content-Disposition - Defaults to "form-data"
28
+ # * Content-Type - Defaults to the content_type argument.
29
+ # * Content-ID - Optional.
30
+ #
31
+ # @return [Faraday::FilePart]
32
+ #
33
+ # @!attribute [r] content_type
34
+ # The uploaded binary data's content type.
35
+ #
36
+ # @return [String]
37
+ #
38
+ # @!attribute [r] original_filename
39
+ # The base filename, taken either from the filename_or_io or filename
40
+ # arguments in #initialize.
41
+ #
42
+ # @return [String]
43
+ #
44
+ # @!attribute [r] opts
45
+ # Extra String key/value pairs to make up the header for this uploaded file.
46
+ #
47
+ # @return [Hash]
48
+ #
49
+ # @!attribute [r] io
50
+ # The open IO object for the uploaded file.
51
+ #
52
+ # @return [IO]
53
+ FilePart = ::UploadIO
54
+
55
+ # Multipart value used to POST a file.
56
+ #
57
+ # @deprecated Use FilePart instead of this class. It behaves identically, with
58
+ # a matching name to ParamPart.
59
+ UploadIO = ::UploadIO
60
+
61
+ Parts = ::Parts
62
+
63
+ # Similar to, but not compatible with CompositeReadIO provided by the
64
+ # multipart-post gem.
65
+ # https://github.com/nicksieger/multipart-post/blob/master/lib/composite_io.rb
66
+ class CompositeReadIO
67
+ def initialize(*parts)
68
+ @parts = parts.flatten
69
+ @ios = @parts.map(&:to_io)
70
+ @index = 0
71
+ end
72
+
73
+ # @return [Integer] sum of the lengths of all the parts
74
+ def length
75
+ @parts.inject(0) { |sum, part| sum + part.length }
76
+ end
77
+
78
+ # Rewind each of the IOs and reset the index to 0.
79
+ #
80
+ # @return [void]
81
+ def rewind
82
+ @ios.each(&:rewind)
83
+ @index = 0
84
+ end
85
+
86
+ # Read from IOs in order until `length` bytes have been received.
87
+ #
88
+ # @param length [Integer, nil]
89
+ # @param outbuf [String, nil]
90
+ def read(length = nil, outbuf = nil)
91
+ got_result = false
92
+ outbuf = outbuf ? (+outbuf).replace('') : +''
93
+
94
+ while (io = current_io)
95
+ if (result = io.read(length))
96
+ got_result ||= !result.nil?
97
+ result.force_encoding('BINARY') if result.respond_to?(:force_encoding)
98
+ outbuf << result
99
+ length -= result.length if length
100
+ break if length&.zero?
101
+ end
102
+ advance_io
103
+ end
104
+ !got_result && length ? nil : outbuf
105
+ end
106
+
107
+ # Close each of the IOs.
108
+ #
109
+ # @return [void]
110
+ def close
111
+ @ios.each(&:close)
112
+ end
113
+
114
+ def ensure_open_and_readable
115
+ # Rubinius compatibility
116
+ end
117
+
118
+ private
119
+
120
+ def current_io
121
+ @ios[@index]
122
+ end
123
+
124
+ def advance_io
125
+ @index += 1
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'pp'
4
+ module Faraday
5
+ module Logging
6
+ # Serves as an integration point to customize logging
7
+ class Formatter
8
+ extend Forwardable
9
+
10
+ DEFAULT_OPTIONS = { headers: true, bodies: false,
11
+ log_level: :info }.freeze
12
+
13
+ def initialize(logger:, options:)
14
+ @logger = logger
15
+ @filter = []
16
+ @options = DEFAULT_OPTIONS.merge(options)
17
+ end
18
+
19
+ def_delegators :@logger, :debug, :info, :warn, :error, :fatal
20
+
21
+ def request(env)
22
+ request_log = proc do
23
+ "#{env.method.upcase} #{apply_filters(env.url.to_s)}"
24
+ end
25
+ public_send(log_level, 'request', &request_log)
26
+
27
+ log_headers('request', env.request_headers) if log_headers?(:request)
28
+ log_body('request', env[:body]) if env[:body] && log_body?(:request)
29
+ end
30
+
31
+ def response(env)
32
+ status = proc { "Status #{env.status}" }
33
+ public_send(log_level, 'response', &status)
34
+
35
+ log_headers('response', env.response_headers) if log_headers?(:response)
36
+ log_body('response', env[:body]) if env[:body] && log_body?(:response)
37
+ end
38
+
39
+ def filter(filter_word, filter_replacement)
40
+ @filter.push([filter_word, filter_replacement])
41
+ end
42
+
43
+ private
44
+
45
+ def dump_headers(headers)
46
+ headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
47
+ end
48
+
49
+ def dump_body(body)
50
+ if body.respond_to?(:to_str)
51
+ body.to_str
52
+ else
53
+ pretty_inspect(body)
54
+ end
55
+ end
56
+
57
+ def pretty_inspect(body)
58
+ body.pretty_inspect
59
+ end
60
+
61
+ def log_headers?(type)
62
+ case @options[:headers]
63
+ when Hash
64
+ @options[:headers][type]
65
+ else
66
+ @options[:headers]
67
+ end
68
+ end
69
+
70
+ def log_body?(type)
71
+ case @options[:bodies]
72
+ when Hash
73
+ @options[:bodies][type]
74
+ else
75
+ @options[:bodies]
76
+ end
77
+ end
78
+
79
+ def apply_filters(output)
80
+ @filter.each do |pattern, replacement|
81
+ output = output.to_s.gsub(pattern, replacement)
82
+ end
83
+ output
84
+ end
85
+
86
+ def log_level
87
+ unless %i[debug info warn error fatal].include?(@options[:log_level])
88
+ return :info
89
+ end
90
+
91
+ @options[:log_level]
92
+ end
93
+
94
+ def log_headers(type, headers)
95
+ headers_log = proc { apply_filters(dump_headers(headers)) }
96
+ public_send(log_level, type, &headers_log)
97
+ end
98
+
99
+ def log_body(type, body)
100
+ body_log = proc { apply_filters(dump_body(body)) }
101
+ public_send(log_level, type, &body_log)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Faraday
4
+ METHODS_WITH_QUERY = %w[get head delete trace].freeze
5
+ METHODS_WITH_BODY = %w[post put patch].freeze
6
+ end
@@ -1,37 +1,31 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
4
+ # Middleware is the basic base class of any Faraday middleware.
2
5
  class Middleware
3
6
  extend MiddlewareRegistry
7
+ extend DependencyLoader
4
8
 
5
- class << self
6
- attr_accessor :load_error
7
- private :load_error=
8
- end
9
-
10
- self.load_error = nil
11
-
12
- # Executes a block which should try to require and reference dependent libraries
13
- def self.dependency(lib = nil)
14
- lib ? require(lib) : yield
15
- rescue LoadError, NameError => error
16
- self.load_error = error
17
- end
9
+ attr_reader :app, :options
18
10
 
19
- def self.new(*)
20
- raise "missing dependency for #{self}: #{load_error.message}" unless loaded?
21
- super
22
- end
23
-
24
- def self.loaded?
25
- load_error.nil?
11
+ def initialize(app = nil, options = {})
12
+ @app = app
13
+ @options = options
26
14
  end
27
15
 
28
- def self.inherited(subclass)
29
- super
30
- subclass.send(:load_error=, self.load_error)
16
+ def call(env)
17
+ on_request(env) if respond_to?(:on_request)
18
+ app.call(env).on_complete do |environment|
19
+ on_complete(environment) if respond_to?(:on_complete)
20
+ end
31
21
  end
32
22
 
33
- def initialize(app = nil)
34
- @app = app
23
+ def close
24
+ if app.respond_to?(:close)
25
+ app.close
26
+ else
27
+ warn "#{app} does not implement \#close!"
28
+ end
35
29
  end
36
30
  end
37
31
  end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'monitor'
4
+
5
+ module Faraday
6
+ # Adds the ability for other modules to register and lookup
7
+ # middleware classes.
8
+ module MiddlewareRegistry
9
+ # Register middleware class(es) on the current module.
10
+ #
11
+ # @param autoload_path [String] Middleware autoload path
12
+ # @param mapping [Hash{
13
+ # Symbol => Module,
14
+ # Symbol => Array<Module, Symbol, String>,
15
+ # }] Middleware mapping from a lookup symbol to a reference to the
16
+ # middleware.
17
+ # Classes can be expressed as:
18
+ # - a fully qualified constant
19
+ # - a Symbol
20
+ # - a Proc that will be lazily called to return the former
21
+ # - an array is given, its first element is the constant or symbol,
22
+ # and its second is a file to `require`.
23
+ # @return [void]
24
+ #
25
+ # @example Lookup by a constant
26
+ #
27
+ # module Faraday
28
+ # class Whatever
29
+ # # Middleware looked up by :foo returns Faraday::Whatever::Foo.
30
+ # register_middleware foo: Foo
31
+ # end
32
+ # end
33
+ #
34
+ # @example Lookup by a symbol
35
+ #
36
+ # module Faraday
37
+ # class Whatever
38
+ # # Middleware looked up by :bar returns
39
+ # # Faraday::Whatever.const_get(:Bar)
40
+ # register_middleware bar: :Bar
41
+ # end
42
+ # end
43
+ #
44
+ # @example Lookup by a symbol and string in an array
45
+ #
46
+ # module Faraday
47
+ # class Whatever
48
+ # # Middleware looked up by :baz requires 'baz' and returns
49
+ # # Faraday::Whatever.const_get(:Baz)
50
+ # register_middleware baz: [:Baz, 'baz']
51
+ # end
52
+ # end
53
+ #
54
+ def register_middleware(autoload_path = nil, mapping = nil)
55
+ if mapping.nil?
56
+ mapping = autoload_path
57
+ autoload_path = nil
58
+ end
59
+ middleware_mutex do
60
+ @middleware_autoload_path = autoload_path if autoload_path
61
+ (@registered_middleware ||= {}).update(mapping)
62
+ end
63
+ end
64
+
65
+ # Unregister a previously registered middleware class.
66
+ #
67
+ # @param key [Symbol] key for the registered middleware.
68
+ def unregister_middleware(key)
69
+ @registered_middleware.delete(key)
70
+ end
71
+
72
+ # Lookup middleware class with a registered Symbol shortcut.
73
+ #
74
+ # @param key [Symbol] key for the registered middleware.
75
+ # @return [Class] a middleware Class.
76
+ # @raise [Faraday::Error] if given key is not registered
77
+ #
78
+ # @example
79
+ #
80
+ # module Faraday
81
+ # class Whatever
82
+ # register_middleware foo: Foo
83
+ # end
84
+ # end
85
+ #
86
+ # Faraday::Whatever.lookup_middleware(:foo)
87
+ # # => Faraday::Whatever::Foo
88
+ #
89
+ def lookup_middleware(key)
90
+ load_middleware(key) ||
91
+ raise(Faraday::Error, "#{key.inspect} is not registered on #{self}")
92
+ end
93
+
94
+ def middleware_mutex(&block)
95
+ @middleware_mutex ||= Monitor.new
96
+ @middleware_mutex.synchronize(&block)
97
+ end
98
+
99
+ def fetch_middleware(key)
100
+ defined?(@registered_middleware) && @registered_middleware[key]
101
+ end
102
+
103
+ def load_middleware(key)
104
+ value = fetch_middleware(key)
105
+ case value
106
+ when Module
107
+ value
108
+ when Symbol, String
109
+ middleware_mutex do
110
+ @registered_middleware[key] = const_get(value)
111
+ end
112
+ when Proc
113
+ middleware_mutex do
114
+ @registered_middleware[key] = value.call
115
+ end
116
+ when Array
117
+ middleware_mutex do
118
+ const, path = value
119
+ if (root = @middleware_autoload_path)
120
+ path = "#{root}/#{path}"
121
+ end
122
+ require(path)
123
+ @registered_middleware[key] = const
124
+ end
125
+ load_middleware(key)
126
+ end
127
+ end
128
+ end
129
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  # Subclasses Struct with some special helpers for converting from a Hash to
3
5
  # a Struct.
@@ -10,6 +12,7 @@ module Faraday
10
12
  # Public
11
13
  def each
12
14
  return to_enum(:each) unless block_given?
15
+
13
16
  members.each do |key|
14
17
  yield(key.to_sym, send(key))
15
18
  end
@@ -27,7 +30,7 @@ module Faraday
27
30
  new_value = value
28
31
  end
29
32
 
30
- self.send("#{key}=", new_value) unless new_value.nil?
33
+ send("#{key}=", new_value) unless new_value.nil?
31
34
  end
32
35
  self
33
36
  end
@@ -47,10 +50,14 @@ module Faraday
47
50
  # Public
48
51
  def merge!(other)
49
52
  other.each do |key, other_value|
50
- self_value = self.send(key)
53
+ self_value = send(key)
51
54
  sub_options = self.class.options_for(key)
52
- new_value = (self_value && sub_options && other_value) ? self_value.merge(other_value) : other_value
53
- self.send("#{key}=", new_value) unless new_value.nil?
55
+ new_value = if self_value && sub_options && other_value
56
+ self_value.merge(other_value)
57
+ else
58
+ other_value
59
+ end
60
+ send("#{key}=", new_value) unless new_value.nil?
54
61
  end
55
62
  self
56
63
  end
@@ -69,10 +76,10 @@ module Faraday
69
76
  def fetch(key, *args)
70
77
  unless symbolized_key_set.include?(key.to_sym)
71
78
  key_setter = "#{key}="
72
- if args.size > 0
79
+ if !args.empty?
73
80
  send(key_setter, args.first)
74
81
  elsif block_given?
75
- send(key_setter, Proc.new.call(key))
82
+ send(key_setter, yield(key))
76
83
  else
77
84
  raise self.class.fetch_error_class, "key not found: #{key.inspect}"
78
85
  end
@@ -96,11 +103,10 @@ module Faraday
96
103
  end
97
104
 
98
105
  # Public
99
- def each_key
106
+ def each_key(&block)
100
107
  return to_enum(:each_key) unless block_given?
101
- keys.each do |key|
102
- yield(key)
103
- end
108
+
109
+ keys.each(&block)
104
110
  end
105
111
 
106
112
  # Public
@@ -111,11 +117,10 @@ module Faraday
111
117
  alias has_key? key?
112
118
 
113
119
  # Public
114
- def each_value
120
+ def each_value(&block)
115
121
  return to_enum(:each_value) unless block_given?
116
- values.each do |value|
117
- yield(value)
118
- end
122
+
123
+ values.each(&block)
119
124
  end
120
125
 
121
126
  # Public
@@ -142,9 +147,9 @@ module Faraday
142
147
  value = send(member)
143
148
  values << "#{member}=#{value.inspect}" if value
144
149
  end
145
- values = values.empty? ? ' (empty)' : (' ' << values.join(", "))
150
+ values = values.empty? ? '(empty)' : values.join(', ')
146
151
 
147
- %(#<#{self.class}#{values}>)
152
+ %(#<#{self.class} #{values}>)
148
153
  end
149
154
 
150
155
  # Internal
@@ -162,8 +167,12 @@ module Faraday
162
167
  @attribute_options ||= {}
163
168
  end
164
169
 
165
- def self.memoized(key)
166
- memoized_attributes[key.to_sym] = Proc.new
170
+ def self.memoized(key, &block)
171
+ unless block_given?
172
+ raise ArgumentError, '#memoized must be called with a block'
173
+ end
174
+
175
+ memoized_attributes[key.to_sym] = block
167
176
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
168
177
  def #{key}() self[:#{key}]; end
169
178
  RUBY
@@ -175,7 +184,7 @@ module Faraday
175
184
 
176
185
  def [](key)
177
186
  key = key.to_sym
178
- if method = self.class.memoized_attributes[key]
187
+ if (method = self.class.memoized_attributes[key])
179
188
  super(key) || (self[key] = instance_eval(&method))
180
189
  else
181
190
  super
@@ -183,7 +192,7 @@ module Faraday
183
192
  end
184
193
 
185
194
  def symbolized_key_set
186
- @symbolized_key_set ||= Set.new(keys.map { |k| k.to_sym })
195
+ @symbolized_key_set ||= Set.new(keys.map(&:to_sym))
187
196
  end
188
197
 
189
198
  def self.inherited(subclass)
@@ -194,179 +203,16 @@ module Faraday
194
203
 
195
204
  def self.fetch_error_class
196
205
  @fetch_error_class ||= if Object.const_defined?(:KeyError)
197
- ::KeyError
198
- else
199
- ::IndexError
200
- end
201
- end
202
- end
203
-
204
- class RequestOptions < Options.new(:params_encoder, :proxy, :bind,
205
- :timeout, :open_timeout, :boundary, :oauth, :context)
206
-
207
- def []=(key, value)
208
- if key && key.to_sym == :proxy
209
- super(key, value ? ProxyOptions.from(value) : nil)
210
- else
211
- super(key, value)
212
- end
213
- end
214
- end
215
-
216
- class SSLOptions < Options.new(:verify, :ca_file, :ca_path, :verify_mode,
217
- :cert_store, :client_cert, :client_key, :certificate, :private_key, :verify_depth, :version)
218
-
219
- def verify?
220
- verify != false
221
- end
222
-
223
- def disable?
224
- !verify?
225
- end
226
- end
227
-
228
- class ProxyOptions < Options.new(:uri, :user, :password)
229
- extend Forwardable
230
- def_delegators :uri, :scheme, :scheme=, :host, :host=, :port, :port=, :path, :path=
231
-
232
- def self.from(value)
233
- case value
234
- when String
235
- value = {:uri => Utils.URI(value)}
236
- when URI
237
- value = {:uri => value}
238
- when Hash, Options
239
- if uri = value.delete(:uri)
240
- value[:uri] = Utils.URI(uri)
241
- end
242
- end
243
- super(value)
244
- end
245
-
246
- memoized(:user) { uri.user && Utils.unescape(uri.user) }
247
- memoized(:password) { uri.password && Utils.unescape(uri.password) }
248
- end
249
-
250
- class ConnectionOptions < Options.new(:request, :proxy, :ssl, :builder, :url,
251
- :parallel_manager, :params, :headers, :builder_class)
252
-
253
- options :request => RequestOptions, :ssl => SSLOptions
254
-
255
- memoized(:request) { self.class.options_for(:request).new }
256
-
257
- memoized(:ssl) { self.class.options_for(:ssl).new }
258
-
259
- memoized(:builder_class) { RackBuilder }
260
-
261
- def new_builder(block)
262
- builder_class.new(&block)
263
- end
264
- end
265
-
266
- class Env < Options.new(:method, :body, :url, :request, :request_headers,
267
- :ssl, :parallel_manager, :params, :response, :response_headers, :status,
268
- :reason_phrase)
269
-
270
- ContentLength = 'Content-Length'.freeze
271
- StatusesWithoutBody = Set.new [204, 304]
272
- SuccessfulStatuses = 200..299
273
-
274
- # A Set of HTTP verbs that typically send a body. If no body is set for
275
- # these requests, the Content-Length header is set to 0.
276
- MethodsWithBodies = Set.new [:post, :put, :patch, :options]
277
-
278
- options :request => RequestOptions,
279
- :request_headers => Utils::Headers, :response_headers => Utils::Headers
280
-
281
- extend Forwardable
282
-
283
- def_delegators :request, :params_encoder
284
-
285
- # Public
286
- def self.from(value)
287
- env = super(value)
288
- if value.respond_to?(:custom_members)
289
- env.custom_members.update(value.custom_members)
290
- end
291
- env
292
- end
293
-
294
- # Public
295
- def [](key)
296
- if in_member_set?(key)
297
- super(key)
298
- else
299
- custom_members[key]
300
- end
301
- end
302
-
303
- # Public
304
- def []=(key, value)
305
- if in_member_set?(key)
306
- super(key, value)
307
- else
308
- custom_members[key] = value
309
- end
310
- end
311
-
312
- # Public
313
- def success?
314
- SuccessfulStatuses.include?(status)
315
- end
316
-
317
- # Public
318
- def needs_body?
319
- !body && MethodsWithBodies.include?(method)
320
- end
321
-
322
- # Public
323
- def clear_body
324
- request_headers[ContentLength] = '0'
325
- self.body = ''
326
- end
327
-
328
- # Public
329
- def parse_body?
330
- !StatusesWithoutBody.include?(status)
331
- end
332
-
333
- # Public
334
- def parallel?
335
- !!parallel_manager
336
- end
337
-
338
- def inspect
339
- attrs = [nil]
340
- members.each do |mem|
341
- if value = send(mem)
342
- attrs << "@#{mem}=#{value.inspect}"
343
- end
344
- end
345
- if !custom_members.empty?
346
- attrs << "@custom=#{custom_members.inspect}"
347
- end
348
- %(#<#{self.class}#{attrs.join(" ")}>)
349
- end
350
-
351
- # Internal
352
- def custom_members
353
- @custom_members ||= {}
354
- end
355
-
356
- # Internal
357
- if members.first.is_a?(Symbol)
358
- def in_member_set?(key)
359
- self.class.member_set.include?(key.to_sym)
360
- end
361
- else
362
- def in_member_set?(key)
363
- self.class.member_set.include?(key.to_s)
364
- end
365
- end
366
-
367
- # Internal
368
- def self.member_set
369
- @member_set ||= Set.new(members)
206
+ ::KeyError
207
+ else
208
+ ::IndexError
209
+ end
370
210
  end
371
211
  end
372
212
  end
213
+
214
+ require 'faraday/options/request_options'
215
+ require 'faraday/options/ssl_options'
216
+ require 'faraday/options/proxy_options'
217
+ require 'faraday/options/connection_options'
218
+ require 'faraday/options/env'