faraday 0.16.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +1 -1
  3. data/README.md +347 -18
  4. data/lib/faraday/adapter/em_http.rb +99 -142
  5. data/lib/faraday/adapter/em_http_ssl_patch.rb +17 -23
  6. data/lib/faraday/adapter/em_synchrony/parallel_manager.rb +15 -18
  7. data/lib/faraday/adapter/em_synchrony.rb +60 -104
  8. data/lib/faraday/adapter/excon.rb +55 -100
  9. data/lib/faraday/adapter/httpclient.rb +39 -61
  10. data/lib/faraday/adapter/net_http.rb +51 -104
  11. data/lib/faraday/adapter/net_http_persistent.rb +27 -48
  12. data/lib/faraday/adapter/patron.rb +35 -54
  13. data/lib/faraday/adapter/rack.rb +12 -28
  14. data/lib/faraday/adapter/test.rb +53 -86
  15. data/lib/faraday/adapter/typhoeus.rb +1 -4
  16. data/lib/faraday/adapter.rb +22 -36
  17. data/lib/faraday/autoload.rb +36 -47
  18. data/lib/faraday/connection.rb +179 -321
  19. data/lib/faraday/error.rb +33 -67
  20. data/lib/faraday/middleware.rb +28 -4
  21. data/lib/faraday/options.rb +186 -35
  22. data/lib/faraday/parameters.rb +197 -4
  23. data/lib/faraday/rack_builder.rb +56 -67
  24. data/lib/faraday/request/authorization.rb +30 -42
  25. data/lib/faraday/request/basic_authentication.rb +7 -14
  26. data/lib/faraday/request/instrumentation.rb +27 -45
  27. data/lib/faraday/request/multipart.rb +48 -79
  28. data/lib/faraday/request/retry.rb +170 -197
  29. data/lib/faraday/request/token_authentication.rb +10 -15
  30. data/lib/faraday/request/url_encoded.rb +23 -41
  31. data/lib/faraday/request.rb +36 -68
  32. data/lib/faraday/response/logger.rb +69 -22
  33. data/lib/faraday/response/raise_error.rb +14 -36
  34. data/lib/faraday/response.rb +16 -23
  35. data/lib/faraday/upload_io.rb +67 -0
  36. data/lib/faraday/utils.rb +245 -28
  37. data/lib/faraday.rb +175 -93
  38. metadata +5 -22
  39. data/lib/faraday/adapter_registry.rb +0 -28
  40. data/lib/faraday/dependency_loader.rb +0 -37
  41. data/lib/faraday/encoders/flat_params_encoder.rb +0 -94
  42. data/lib/faraday/encoders/nested_params_encoder.rb +0 -171
  43. data/lib/faraday/file_part.rb +0 -128
  44. data/lib/faraday/logging/formatter.rb +0 -92
  45. data/lib/faraday/middleware_registry.rb +0 -129
  46. data/lib/faraday/options/connection_options.rb +0 -22
  47. data/lib/faraday/options/env.rb +0 -181
  48. data/lib/faraday/options/proxy_options.rb +0 -28
  49. data/lib/faraday/options/request_options.rb +0 -21
  50. data/lib/faraday/options/ssl_options.rb +0 -59
  51. data/lib/faraday/param_part.rb +0 -53
  52. data/lib/faraday/utils/headers.rb +0 -139
  53. data/lib/faraday/utils/params_hash.rb +0 -61
  54. data/spec/external_adapters/faraday_specs_setup.rb +0 -14
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: faraday
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rick Olson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-27 00:00:00.000000000 Z
11
+ date: 2019-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: multipart-post
@@ -52,24 +52,11 @@ files:
52
52
  - lib/faraday/adapter/rack.rb
53
53
  - lib/faraday/adapter/test.rb
54
54
  - lib/faraday/adapter/typhoeus.rb
55
- - lib/faraday/adapter_registry.rb
56
55
  - lib/faraday/autoload.rb
57
56
  - lib/faraday/connection.rb
58
- - lib/faraday/dependency_loader.rb
59
- - lib/faraday/encoders/flat_params_encoder.rb
60
- - lib/faraday/encoders/nested_params_encoder.rb
61
57
  - lib/faraday/error.rb
62
- - lib/faraday/file_part.rb
63
- - lib/faraday/logging/formatter.rb
64
58
  - lib/faraday/middleware.rb
65
- - lib/faraday/middleware_registry.rb
66
59
  - lib/faraday/options.rb
67
- - lib/faraday/options/connection_options.rb
68
- - lib/faraday/options/env.rb
69
- - lib/faraday/options/proxy_options.rb
70
- - lib/faraday/options/request_options.rb
71
- - lib/faraday/options/ssl_options.rb
72
- - lib/faraday/param_part.rb
73
60
  - lib/faraday/parameters.rb
74
61
  - lib/faraday/rack_builder.rb
75
62
  - lib/faraday/request.rb
@@ -83,10 +70,8 @@ files:
83
70
  - lib/faraday/response.rb
84
71
  - lib/faraday/response/logger.rb
85
72
  - lib/faraday/response/raise_error.rb
73
+ - lib/faraday/upload_io.rb
86
74
  - lib/faraday/utils.rb
87
- - lib/faraday/utils/headers.rb
88
- - lib/faraday/utils/params_hash.rb
89
- - spec/external_adapters/faraday_specs_setup.rb
90
75
  homepage: https://github.com/lostisland/faraday
91
76
  licenses:
92
77
  - MIT
@@ -95,20 +80,18 @@ post_install_message:
95
80
  rdoc_options: []
96
81
  require_paths:
97
82
  - lib
98
- - spec/external_adapters
99
83
  required_ruby_version: !ruby/object:Gem::Requirement
100
84
  requirements:
101
85
  - - ">="
102
86
  - !ruby/object:Gem::Version
103
- version: '2.3'
87
+ version: '1.9'
104
88
  required_rubygems_version: !ruby/object:Gem::Requirement
105
89
  requirements:
106
90
  - - ">="
107
91
  - !ruby/object:Gem::Version
108
92
  version: '0'
109
93
  requirements: []
110
- rubyforge_project:
111
- rubygems_version: 2.7.6.2
94
+ rubygems_version: 3.0.3
112
95
  signing_key:
113
96
  specification_version: 4
114
97
  summary: HTTP/REST API client library.
@@ -1,28 +0,0 @@
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 = @constants[name]
16
- return klass if klass
17
-
18
- Object.const_get(name).tap { |c| set(c, name) }
19
- end
20
-
21
- def set(klass, name = nil)
22
- name ||= klass.to_s
23
- @lock.synchronize do
24
- @constants[name] = klass
25
- end
26
- end
27
- end
28
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # DependencyLoader helps Faraday adapters and middleware load dependencies.
5
- module DependencyLoader
6
- attr_reader :load_error
7
-
8
- # Executes a block which should try to require and reference dependent
9
- # libraries
10
- def dependency(lib = nil)
11
- lib ? require(lib) : yield
12
- rescue LoadError, NameError => e
13
- self.load_error = e
14
- end
15
-
16
- def new(*)
17
- unless loaded?
18
- raise "missing dependency for #{self}: #{load_error.message}"
19
- end
20
-
21
- super
22
- end
23
-
24
- def loaded?
25
- load_error.nil?
26
- end
27
-
28
- def inherited(subclass)
29
- super
30
- subclass.send(:load_error=, load_error)
31
- end
32
-
33
- private
34
-
35
- attr_writer :load_error
36
- end
37
- end
@@ -1,94 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # FlatParamsEncoder manages URI params as a flat hash. Any Array values repeat
5
- # the parameter multiple times.
6
- module FlatParamsEncoder
7
- class << self
8
- extend Forwardable
9
- def_delegators :'Faraday::Utils', :escape, :unescape
10
- end
11
-
12
- # Encode converts the given param into a URI querystring. Keys and values
13
- # will converted to strings and appropriately escaped for the URI.
14
- #
15
- # @param params [Hash] query arguments to convert.
16
- #
17
- # @example
18
- #
19
- # encode({a: %w[one two three], b: true, c: "C"})
20
- # # => 'a=one&a=two&a=three&b=true&c=C'
21
- #
22
- # @return [String] the URI querystring (without the leading '?')
23
- def self.encode(params)
24
- return nil if params.nil?
25
-
26
- unless params.is_a?(Array)
27
- unless params.respond_to?(:to_hash)
28
- raise TypeError,
29
- "Can't convert #{params.class} into Hash."
30
- end
31
- params = params.to_hash
32
- params = params.map do |key, value|
33
- key = key.to_s if key.is_a?(Symbol)
34
- [key, value]
35
- end
36
- # Useful default for OAuth and caching.
37
- # Only to be used for non-Array inputs. Arrays should preserve order.
38
- params.sort!
39
- end
40
-
41
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
42
- buffer = +''
43
- params.each do |key, value|
44
- encoded_key = escape(key)
45
- if value.nil?
46
- buffer << "#{encoded_key}&"
47
- elsif value.is_a?(Array)
48
- value.each do |sub_value|
49
- encoded_value = escape(sub_value)
50
- buffer << "#{encoded_key}=#{encoded_value}&"
51
- end
52
- else
53
- encoded_value = escape(value)
54
- buffer << "#{encoded_key}=#{encoded_value}&"
55
- end
56
- end
57
- buffer.chop
58
- end
59
-
60
- # Decode converts the given URI querystring into a hash.
61
- #
62
- # @param query [String] query arguments to parse.
63
- #
64
- # @example
65
- #
66
- # decode('a=one&a=two&a=three&b=true&c=C')
67
- # # => {"a"=>["one", "two", "three"], "b"=>"true", "c"=>"C"}
68
- #
69
- # @return [Hash] parsed keys and value strings from the querystring.
70
- def self.decode(query)
71
- return nil if query.nil?
72
-
73
- empty_accumulator = {}
74
-
75
- split_query = (query.split('&').map do |pair|
76
- pair.split('=', 2) if pair && !pair.empty?
77
- end).compact
78
- split_query.each_with_object(empty_accumulator.dup) do |pair, accu|
79
- pair[0] = unescape(pair[0])
80
- pair[1] = true if pair[1].nil?
81
- if pair[1].respond_to?(:to_str)
82
- pair[1] = unescape(pair[1].to_str.tr('+', ' '))
83
- end
84
- if accu[pair[0]].is_a?(Array)
85
- accu[pair[0]] << pair[1]
86
- elsif accu[pair[0]]
87
- accu[pair[0]] = [accu[pair[0]], pair[1]]
88
- else
89
- accu[pair[0]] = pair[1]
90
- end
91
- end
92
- end
93
- end
94
- end
@@ -1,171 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Faraday
4
- # Sub-module for encoding parameters into query-string.
5
- module EncodeMethods
6
- # @param params [nil, Array, #to_hash] parameters to be encoded
7
- #
8
- # @return [String] the encoded params
9
- #
10
- # @raise [TypeError] if params can not be converted to a Hash
11
- def encode(params)
12
- return nil if params.nil?
13
-
14
- unless params.is_a?(Array)
15
- unless params.respond_to?(:to_hash)
16
- raise TypeError, "Can't convert #{params.class} into Hash."
17
- end
18
-
19
- params = params.to_hash
20
- params = params.map do |key, value|
21
- key = key.to_s if key.is_a?(Symbol)
22
- [key, value]
23
- end
24
- # Useful default for OAuth and caching.
25
- # Only to be used for non-Array inputs. Arrays should preserve order.
26
- params.sort!
27
- end
28
-
29
- # The params have form [['key1', 'value1'], ['key2', 'value2']].
30
- buffer = +''
31
- params.each do |parent, value|
32
- encoded_parent = escape(parent)
33
- buffer << "#{encode_pair(encoded_parent, value)}&"
34
- end
35
- buffer.chop
36
- end
37
-
38
- protected
39
-
40
- def encode_pair(parent, value)
41
- if value.is_a?(Hash)
42
- encode_hash(parent, value)
43
- elsif value.is_a?(Array)
44
- encode_array(parent, value)
45
- elsif value.nil?
46
- parent
47
- else
48
- encoded_value = escape(value)
49
- "#{parent}=#{encoded_value}"
50
- end
51
- end
52
-
53
- def encode_hash(parent, value)
54
- value = value.map { |key, val| [escape(key), val] }.sort
55
-
56
- buffer = +''
57
- value.each do |key, val|
58
- new_parent = "#{parent}%5B#{key}%5D"
59
- buffer << "#{encode_pair(new_parent, val)}&"
60
- end
61
- buffer.chop
62
- end
63
-
64
- def encode_array(parent, value)
65
- new_parent = "#{parent}%5B%5D"
66
- return new_parent if value.empty?
67
-
68
- buffer = +''
69
- value.each { |val| buffer << "#{encode_pair(new_parent, val)}&" }
70
- buffer.chop
71
- end
72
- end
73
-
74
- # Sub-module for decoding query-string into parameters.
75
- module DecodeMethods
76
- # @param query [nil, String]
77
- #
78
- # @return [Array<Array, String>] the decoded params
79
- #
80
- # @raise [TypeError] if the nesting is incorrect
81
- def decode(query)
82
- return nil if query.nil?
83
-
84
- params = {}
85
- query.split('&').each do |pair|
86
- next if pair.empty?
87
-
88
- key, value = pair.split('=', 2)
89
- key = unescape(key)
90
- value = unescape(value.tr('+', ' ')) if value
91
- decode_pair(key, value, params)
92
- end
93
-
94
- dehash(params, 0)
95
- end
96
-
97
- protected
98
-
99
- SUBKEYS_REGEX = /[^\[\]]+(?:\]?\[\])?/.freeze
100
-
101
- def decode_pair(key, value, context)
102
- subkeys = key.scan(SUBKEYS_REGEX)
103
- subkeys.each_with_index do |subkey, i|
104
- is_array = subkey =~ /[\[\]]+\Z/
105
- subkey = $` if is_array
106
- last_subkey = i == subkeys.length - 1
107
-
108
- context = prepare_context(context, subkey, is_array, last_subkey)
109
- add_to_context(is_array, context, value, subkey) if last_subkey
110
- end
111
- end
112
-
113
- def prepare_context(context, subkey, is_array, last_subkey)
114
- if !last_subkey || is_array
115
- context = new_context(subkey, is_array, context)
116
- end
117
- if context.is_a?(Array) && !is_array
118
- context = match_context(context, subkey)
119
- end
120
- context
121
- end
122
-
123
- def new_context(subkey, is_array, context)
124
- value_type = is_array ? Array : Hash
125
- if context[subkey] && !context[subkey].is_a?(value_type)
126
- raise TypeError, "expected #{value_type.name} " \
127
- "(got #{context[subkey].class.name}) for param `#{subkey}'"
128
- end
129
-
130
- context[subkey] ||= value_type.new
131
- end
132
-
133
- def match_context(context, subkey)
134
- context << {} if !context.last.is_a?(Hash) || context.last.key?(subkey)
135
- context.last
136
- end
137
-
138
- def add_to_context(is_array, context, value, subkey)
139
- is_array ? context << value : context[subkey] = value
140
- end
141
-
142
- # Internal: convert a nested hash with purely numeric keys into an array.
143
- # FIXME: this is not compatible with Rack::Utils.parse_nested_query
144
- # @!visibility private
145
- def dehash(hash, depth)
146
- hash.each do |key, value|
147
- hash[key] = dehash(value, depth + 1) if value.is_a?(Hash)
148
- end
149
-
150
- if depth.positive? && !hash.empty? && hash.keys.all? { |k| k =~ /^\d+$/ }
151
- hash.sort.map(&:last)
152
- else
153
- hash
154
- end
155
- end
156
- end
157
-
158
- # This is the default encoder for Faraday requests.
159
- # Using this encoder, parameters will be encoded respecting their structure,
160
- # so you can send objects such as Arrays or Hashes as parameters
161
- # for your requests.
162
- module NestedParamsEncoder
163
- class << self
164
- extend Forwardable
165
- def_delegators :'Faraday::Utils', :escape, :unescape
166
- end
167
-
168
- extend EncodeMethods
169
- extend DecodeMethods
170
- end
171
- end
@@ -1,128 +0,0 @@
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
@@ -1,92 +0,0 @@
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 }.freeze
11
-
12
- def initialize(logger:, options:)
13
- @logger = logger
14
- @filter = []
15
- @options = DEFAULT_OPTIONS.merge(options)
16
- end
17
-
18
- def_delegators :@logger, :debug, :info, :warn, :error, :fatal
19
-
20
- def request(env)
21
- info('request') do
22
- "#{env.method.upcase} #{apply_filters(env.url.to_s)}"
23
- end
24
- if log_headers?(:request)
25
- debug('request') { apply_filters(dump_headers(env.request_headers)) }
26
- end
27
- return unless env[:body] && log_body?(:request)
28
-
29
- debug('request') { apply_filters(dump_body(env[:body])) }
30
- end
31
-
32
- def response(env)
33
- info('response') { "Status #{env.status}" }
34
- if log_headers?(:response)
35
- debug('response') do
36
- apply_filters(dump_headers(env.response_headers))
37
- end
38
- end
39
- return unless env[:body] && log_body?(:response)
40
-
41
- debug('response') { apply_filters(dump_body(env[:body])) }
42
- end
43
-
44
- def filter(filter_word, filter_replacement)
45
- @filter.push([filter_word, filter_replacement])
46
- end
47
-
48
- private
49
-
50
- def dump_headers(headers)
51
- headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
52
- end
53
-
54
- def dump_body(body)
55
- if body.respond_to?(:to_str)
56
- body.to_str
57
- else
58
- pretty_inspect(body)
59
- end
60
- end
61
-
62
- def pretty_inspect(body)
63
- body.pretty_inspect
64
- end
65
-
66
- def log_headers?(type)
67
- case @options[:headers]
68
- when Hash
69
- @options[:headers][type]
70
- else
71
- @options[:headers]
72
- end
73
- end
74
-
75
- def log_body?(type)
76
- case @options[:bodies]
77
- when Hash
78
- @options[:bodies][type]
79
- else
80
- @options[:bodies]
81
- end
82
- end
83
-
84
- def apply_filters(output)
85
- @filter.each do |pattern, replacement|
86
- output = output.to_s.gsub(pattern, replacement)
87
- end
88
- output
89
- end
90
- end
91
- end
92
- end