faraday_middleware 0.10.0 → 1.2.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.
- checksums.yaml +5 -5
- data/README.md +16 -22
- data/lib/faraday_middleware/backwards_compatibility.rb +16 -12
- data/lib/faraday_middleware/gzip.rb +51 -15
- data/lib/faraday_middleware/instrumentation.rb +8 -2
- data/lib/faraday_middleware/rack_compatible.rb +18 -11
- data/lib/faraday_middleware/redirect_limit_reached.rb +16 -0
- data/lib/faraday_middleware/request/encode_json.rb +12 -9
- data/lib/faraday_middleware/request/method_override.rb +7 -6
- data/lib/faraday_middleware/request/oauth.rb +13 -10
- data/lib/faraday_middleware/request/oauth2.rb +37 -12
- data/lib/faraday_middleware/response/caching.rb +55 -21
- data/lib/faraday_middleware/response/chunked.rb +10 -6
- data/lib/faraday_middleware/response/follow_redirects.rb +57 -26
- data/lib/faraday_middleware/response/mashify.rb +2 -0
- data/lib/faraday_middleware/response/parse_dates.rb +6 -3
- data/lib/faraday_middleware/response/parse_json.rb +10 -10
- data/lib/faraday_middleware/response/parse_marshal.rb +3 -1
- data/lib/faraday_middleware/response/parse_xml.rb +4 -2
- data/lib/faraday_middleware/response/parse_yaml.rb +18 -11
- data/lib/faraday_middleware/response/rashify.rb +3 -1
- data/lib/faraday_middleware/response_middleware.rb +27 -18
- data/lib/faraday_middleware/version.rb +4 -1
- data/lib/faraday_middleware.rb +21 -17
- metadata +8 -32
- data/CHANGELOG.md +0 -10
- data/CONTRIBUTING.md +0 -46
- data/faraday_middleware.gemspec +0 -20
- data/lib/faraday_middleware/addressable_patch.rb +0 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b9533a5d53e299a95e8b2aa19d277ac32ed800930c0abd4d92c67f025c98101d
|
4
|
+
data.tar.gz: 7261d4f25c4e0edeaaba0718947af74439d2fef8a114278a74f8de63f0f6c575
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ae2e4ea996bb4a2ad2762a7c0812c8734879205adb05eb88aed062f0be24b26fa18de82e6cc33c7c86dfc8f7c4fa8694522732c457643c8a4d3991e50ac095a
|
7
|
+
data.tar.gz: 512f5e9888e8adf5ac0d93c501470028079b463e407697353d55ef603b3a2590f46b9a6530a0a688a54e391fe9033302551f133b6d216281bf01c451e1a73f85
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
Faraday Middleware
|
2
2
|
==================
|
3
|
+
[](https://rubygems.org/gems/faraday_middleware)
|
4
|
+

|
3
5
|
|
4
6
|
A collection of useful [Faraday][] middleware. [See the documentation][docs].
|
5
7
|
|
@@ -8,15 +10,20 @@ A collection of useful [Faraday][] middleware. [See the documentation][docs].
|
|
8
10
|
Dependencies
|
9
11
|
------------
|
10
12
|
|
13
|
+
Ruby >= 2.3.0
|
14
|
+
|
15
|
+
#### As of v0.16.0, `faraday` and `faraday_middleware` no longer officially support JRuby or Rubinius.
|
16
|
+
|
11
17
|
Some dependent libraries are needed only when using specific middleware:
|
12
18
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
19
|
+
| Middleware | Library | Notes |
|
20
|
+
| --------------------------- | -------------- | ----- |
|
21
|
+
| [FaradayMiddleware::Instrumentation](https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/instrumentation.rb) | [`activesupport`](https://rubygems.org/gems/activesupport) | |
|
22
|
+
| [FaradayMiddleware::OAuth](https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/request/oauth.rb) | [`simple_oauth`](https://rubygems.org/gems/simple_oauth) | |
|
23
|
+
| [FaradayMiddleware::ParseXml](https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/response/parse_xml.rb) | [`multi_xml`](https://rubygems.org/gems/multi_xml) | |
|
24
|
+
| [FaradayMiddleware::ParseYaml](https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/response/parse_yaml.rb) | [`safe_yaml`](https://rubygems.org/gems/safe_yaml) | Not backwards compatible with versions of this middleware prior to `faraday_middleware` v0.12. See code comments for alternatives. |
|
25
|
+
| [FaradayMiddleware::Mashify](https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/response/mashify.rb) | [`hashie`](https://rubygems.org/gems/hashie) | |
|
26
|
+
| [FaradayMiddleware::Rashify](https://github.com/lostisland/faraday_middleware/blob/main/lib/faraday_middleware/response/rashify.rb) | [`rash_alt`](https://rubygems.org/gems/rash_alt) | Make sure to uninstall original `rash` gem to avoid conflict. |
|
20
27
|
|
21
28
|
Examples
|
22
29
|
--------
|
@@ -24,29 +31,16 @@ Examples
|
|
24
31
|
``` rb
|
25
32
|
require 'faraday_middleware'
|
26
33
|
|
27
|
-
## in Faraday 0.8 or above:
|
28
34
|
connection = Faraday.new 'http://example.com/api' do |conn|
|
29
35
|
conn.request :oauth2, 'TOKEN'
|
30
36
|
conn.request :json
|
31
37
|
|
32
|
-
conn.response :xml, :
|
33
|
-
conn.response :json, :
|
38
|
+
conn.response :xml, content_type: /\bxml$/
|
39
|
+
conn.response :json, content_type: /\bjson$/
|
34
40
|
|
35
41
|
conn.use :instrumentation
|
36
42
|
conn.adapter Faraday.default_adapter
|
37
43
|
end
|
38
|
-
|
39
|
-
## with Faraday 0.7:
|
40
|
-
connection = Faraday.new 'http://example.com/api' do |builder|
|
41
|
-
builder.use FaradayMiddleware::OAuth2, 'TOKEN'
|
42
|
-
builder.use FaradayMiddleware::EncodeJson
|
43
|
-
|
44
|
-
builder.use FaradayMiddleware::ParseXml, :content_type => /\bxml$/
|
45
|
-
builder.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
|
46
|
-
|
47
|
-
builder.use FaradayMiddleware::Instrumentation
|
48
|
-
builder.adapter Faraday.default_adapter
|
49
|
-
end
|
50
44
|
```
|
51
45
|
|
52
46
|
|
@@ -1,15 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
Faraday
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Faraday
|
4
|
+
# Autoload classes for Faraday::Request.
|
5
|
+
class Request
|
6
|
+
autoload :OAuth, 'faraday_middleware/request/oauth'
|
7
|
+
autoload :OAuth2, 'faraday_middleware/request/oauth2'
|
8
|
+
end
|
7
9
|
|
8
|
-
Faraday::
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
# Autoload classes for Faraday::Request.
|
11
|
+
class Response
|
12
|
+
autoload :Mashify, 'faraday_middleware/response/mashify'
|
13
|
+
autoload :Rashify, 'faraday_middleware/response/rashify'
|
14
|
+
autoload :ParseJson, 'faraday_middleware/response/parse_json'
|
15
|
+
autoload :ParseXml, 'faraday_middleware/response/parse_xml'
|
16
|
+
autoload :ParseMarshal, 'faraday_middleware/response/parse_marshal'
|
17
|
+
autoload :ParseYaml, 'faraday_middleware/response/parse_yaml'
|
18
|
+
end
|
15
19
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
|
3
5
|
module FaradayMiddleware
|
@@ -13,20 +15,40 @@ module FaradayMiddleware
|
|
13
15
|
class Gzip < Faraday::Middleware
|
14
16
|
dependency 'zlib'
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
def self.optional_dependency(lib = nil)
|
19
|
+
lib ? require(lib) : yield
|
20
|
+
true
|
21
|
+
rescue LoadError, NameError
|
22
|
+
false
|
23
|
+
end
|
24
|
+
|
25
|
+
BROTLI_SUPPORTED = optional_dependency 'brotli'
|
26
|
+
|
27
|
+
def self.supported_encodings
|
28
|
+
encodings = %w[gzip deflate]
|
29
|
+
encodings << 'br' if BROTLI_SUPPORTED
|
30
|
+
encodings
|
31
|
+
end
|
32
|
+
|
33
|
+
ACCEPT_ENCODING = 'Accept-Encoding'
|
34
|
+
CONTENT_ENCODING = 'Content-Encoding'
|
35
|
+
CONTENT_LENGTH = 'Content-Length'
|
36
|
+
SUPPORTED_ENCODINGS = supported_encodings.join(',').freeze
|
21
37
|
|
22
38
|
def call(env)
|
23
39
|
env[:request_headers][ACCEPT_ENCODING] ||= SUPPORTED_ENCODINGS
|
24
40
|
@app.call(env).on_complete do |response_env|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
if response_env[:body].empty?
|
42
|
+
reset_body(response_env, &method(:raw_body))
|
43
|
+
else
|
44
|
+
case response_env[:response_headers][CONTENT_ENCODING]
|
45
|
+
when 'gzip'
|
46
|
+
reset_body(response_env, &method(:uncompress_gzip))
|
47
|
+
when 'deflate'
|
48
|
+
reset_body(response_env, &method(:inflate))
|
49
|
+
when 'br'
|
50
|
+
reset_body(response_env, &method(:brotli_inflate))
|
51
|
+
end
|
30
52
|
end
|
31
53
|
end
|
32
54
|
end
|
@@ -39,16 +61,30 @@ module FaradayMiddleware
|
|
39
61
|
|
40
62
|
def uncompress_gzip(body)
|
41
63
|
io = StringIO.new(body)
|
42
|
-
gzip_reader =
|
43
|
-
Zlib::GzipReader.new(io, :encoding => 'ASCII-8BIT')
|
44
|
-
else
|
45
|
-
Zlib::GzipReader.new(io)
|
46
|
-
end
|
64
|
+
gzip_reader = Zlib::GzipReader.new(io, encoding: 'ASCII-8BIT')
|
47
65
|
gzip_reader.read
|
48
66
|
end
|
49
67
|
|
50
68
|
def inflate(body)
|
69
|
+
# Inflate as a DEFLATE (RFC 1950+RFC 1951) stream
|
51
70
|
Zlib::Inflate.inflate(body)
|
71
|
+
rescue Zlib::DataError
|
72
|
+
# Fall back to inflating as a "raw" deflate stream which
|
73
|
+
# Microsoft servers return
|
74
|
+
inflate = Zlib::Inflate.new(-Zlib::MAX_WBITS)
|
75
|
+
begin
|
76
|
+
inflate.inflate(body)
|
77
|
+
ensure
|
78
|
+
inflate.close
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def brotli_inflate(body)
|
83
|
+
Brotli.inflate(body)
|
84
|
+
end
|
85
|
+
|
86
|
+
def raw_body(body)
|
87
|
+
body
|
52
88
|
end
|
53
89
|
end
|
54
90
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
|
3
5
|
module FaradayMiddleware
|
@@ -7,11 +9,15 @@ module FaradayMiddleware
|
|
7
9
|
#
|
8
10
|
# Examples
|
9
11
|
#
|
10
|
-
# ActiveSupport::Notifications.
|
12
|
+
# ActiveSupport::Notifications.
|
13
|
+
# subscribe('request.faraday') do |name, starts, ends, _, env|
|
11
14
|
# url = env[:url]
|
12
15
|
# http_method = env[:method].to_s.upcase
|
13
16
|
# duration = ends - starts
|
14
|
-
# $stderr.puts '[%s] %s %s (%.3f s)' % [url.host,
|
17
|
+
# $stderr.puts '[%s] %s %s (%.3f s)' % [url.host,
|
18
|
+
# http_method,
|
19
|
+
# url.request_uri,
|
20
|
+
# duration]
|
15
21
|
# end
|
16
22
|
class Instrumentation < Faraday::Middleware
|
17
23
|
dependency 'active_support/notifications'
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'stringio'
|
2
4
|
|
3
5
|
module FaradayMiddleware
|
4
|
-
# Wraps a handler originally written for Rack
|
6
|
+
# Wraps a handler originally written for Rack for Faraday compatibility.
|
5
7
|
#
|
6
8
|
# Experimental. Only handles changes in request headers.
|
7
9
|
class RackCompatible
|
@@ -22,7 +24,7 @@ module FaradayMiddleware
|
|
22
24
|
finalize_response(env, rack_response)
|
23
25
|
end
|
24
26
|
|
25
|
-
|
27
|
+
NON_PREFIXED_HEADERS = %w[CONTENT_LENGTH CONTENT_TYPE].freeze
|
26
28
|
|
27
29
|
# faraday to rack-compatible
|
28
30
|
def prepare_env(faraday_env)
|
@@ -31,7 +33,11 @@ module FaradayMiddleware
|
|
31
33
|
url = faraday_env[:url]
|
32
34
|
env['rack.url_scheme'] = url.scheme
|
33
35
|
env['PATH_INFO'] = url.path
|
34
|
-
env['SERVER_PORT'] = url.respond_to?(:inferred_port)
|
36
|
+
env['SERVER_PORT'] = if url.respond_to?(:inferred_port)
|
37
|
+
url.inferred_port
|
38
|
+
else
|
39
|
+
url.port
|
40
|
+
end
|
35
41
|
env['QUERY_STRING'] = url.query
|
36
42
|
env['REQUEST_METHOD'] = faraday_env[:method].to_s.upcase
|
37
43
|
|
@@ -45,7 +51,7 @@ module FaradayMiddleware
|
|
45
51
|
rack_env = {}
|
46
52
|
env[:request_headers].each do |name, value|
|
47
53
|
name = name.upcase.tr('-', '_')
|
48
|
-
name = "HTTP_#{name}" unless
|
54
|
+
name = "HTTP_#{name}" unless NON_PREFIXED_HEADERS.include? name
|
49
55
|
rack_env[name] = value
|
50
56
|
end
|
51
57
|
rack_env
|
@@ -58,8 +64,9 @@ module FaradayMiddleware
|
|
58
64
|
headers.clear
|
59
65
|
|
60
66
|
rack_env.each do |name, value|
|
61
|
-
next unless String
|
62
|
-
|
67
|
+
next unless name.is_a?(String) && value.is_a?(String)
|
68
|
+
|
69
|
+
if NON_PREFIXED_HEADERS.include?(name) || name.start_with?('HTTP_')
|
63
70
|
name = name.sub(/^HTTP_/, '').downcase.tr('_', '-')
|
64
71
|
headers[name] = value
|
65
72
|
end
|
@@ -72,12 +79,12 @@ module FaradayMiddleware
|
|
72
79
|
|
73
80
|
def finalize_response(env, rack_response)
|
74
81
|
status, headers, body = rack_response
|
75
|
-
body = body.inject
|
76
|
-
headers = Faraday::Utils::Headers.new(headers) unless Faraday::Utils::Headers
|
82
|
+
body = body.inject { |str, part| str << part }
|
83
|
+
headers = Faraday::Utils::Headers.new(headers) unless headers.is_a?(Faraday::Utils::Headers)
|
77
84
|
|
78
|
-
env.update :
|
79
|
-
:
|
80
|
-
:
|
85
|
+
env.update status: status.to_i,
|
86
|
+
body: body,
|
87
|
+
response_headers: headers
|
81
88
|
|
82
89
|
env[:response] ||= Faraday::Response.new(env)
|
83
90
|
env[:response]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'faraday'
|
4
|
+
|
5
|
+
module FaradayMiddleware
|
6
|
+
# Exception thrown when the maximum amount of requests is
|
7
|
+
# exceeded.
|
8
|
+
class RedirectLimitReached < Faraday::ClientError
|
9
|
+
attr_reader :response
|
10
|
+
|
11
|
+
def initialize(response)
|
12
|
+
super "too many redirects; last one to: #{response['location']}"
|
13
|
+
@response = response
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
|
3
5
|
module FaradayMiddleware
|
@@ -9,8 +11,9 @@ module FaradayMiddleware
|
|
9
11
|
#
|
10
12
|
# Doesn't try to encode bodies that already are in string form.
|
11
13
|
class EncodeJson < Faraday::Middleware
|
12
|
-
CONTENT_TYPE
|
13
|
-
MIME_TYPE
|
14
|
+
CONTENT_TYPE = 'Content-Type'
|
15
|
+
MIME_TYPE = 'application/json'
|
16
|
+
MIME_TYPE_REGEX = %r{^application/(vnd\..+\+)?json$}.freeze
|
14
17
|
|
15
18
|
dependency do
|
16
19
|
require 'json' unless defined?(::JSON)
|
@@ -24,23 +27,23 @@ module FaradayMiddleware
|
|
24
27
|
end
|
25
28
|
|
26
29
|
def encode(data)
|
27
|
-
::JSON.
|
30
|
+
::JSON.generate data
|
28
31
|
end
|
29
32
|
|
30
33
|
def match_content_type(env)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
34
|
+
return unless process_request?(env)
|
35
|
+
|
36
|
+
env[:request_headers][CONTENT_TYPE] ||= MIME_TYPE
|
37
|
+
yield env[:body] unless env[:body].respond_to?(:to_str)
|
35
38
|
end
|
36
39
|
|
37
40
|
def process_request?(env)
|
38
41
|
type = request_type(env)
|
39
|
-
has_body?(env)
|
42
|
+
has_body?(env) && (type.empty? || MIME_TYPE_REGEX =~ type)
|
40
43
|
end
|
41
44
|
|
42
45
|
def has_body?(env)
|
43
|
-
body = env[:body]
|
46
|
+
(body = env[:body]) && !(body.respond_to?(:to_str) && body.empty?)
|
44
47
|
end
|
45
48
|
|
46
49
|
def request_type(env)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
|
3
5
|
module FaradayMiddleware
|
@@ -11,8 +13,7 @@ module FaradayMiddleware
|
|
11
13
|
# Rack::MethodOverride module. See
|
12
14
|
# http://rack.rubyforge.org/doc/classes/Rack/MethodOverride.html
|
13
15
|
class MethodOverride < Faraday::Middleware
|
14
|
-
|
15
|
-
HEADER = "X-Http-Method-Override".freeze
|
16
|
+
HEADER = 'X-Http-Method-Override'
|
16
17
|
|
17
18
|
# Public: Initialize the middleware.
|
18
19
|
#
|
@@ -22,10 +23,10 @@ module FaradayMiddleware
|
|
22
23
|
# (default: all but GET and POST)
|
23
24
|
def initialize(app, options = nil)
|
24
25
|
super(app)
|
25
|
-
@methods = options
|
26
|
+
@methods = options&.fetch(:rewrite)&.map do |method|
|
26
27
|
method = method.downcase if method.respond_to? :downcase
|
27
28
|
method.to_sym
|
28
|
-
|
29
|
+
end
|
29
30
|
end
|
30
31
|
|
31
32
|
def call(env)
|
@@ -35,8 +36,8 @@ module FaradayMiddleware
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def rewrite_request?(method)
|
38
|
-
if @methods.nil?
|
39
|
-
method != :get
|
39
|
+
if @methods.nil? || @methods.empty?
|
40
|
+
(method != :get) && (method != :post)
|
40
41
|
else
|
41
42
|
@methods.include? method
|
42
43
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
require 'forwardable'
|
3
5
|
|
@@ -23,14 +25,12 @@ module FaradayMiddleware
|
|
23
25
|
class OAuth < Faraday::Middleware
|
24
26
|
dependency 'simple_oauth'
|
25
27
|
|
26
|
-
AUTH_HEADER = 'Authorization'
|
27
|
-
CONTENT_TYPE = 'Content-Type'
|
28
|
-
TYPE_URLENCODED = 'application/x-www-form-urlencoded'
|
28
|
+
AUTH_HEADER = 'Authorization'
|
29
|
+
CONTENT_TYPE = 'Content-Type'
|
30
|
+
TYPE_URLENCODED = 'application/x-www-form-urlencoded'
|
29
31
|
|
30
32
|
extend Forwardable
|
31
|
-
|
32
|
-
parser_module = ::Faraday::Utils.respond_to?(parser_method) ? 'Faraday::Utils' : 'Rack::Utils'
|
33
|
-
def_delegator parser_module, parser_method
|
33
|
+
def_delegator :'Faraday::Utils', :parse_nested_query
|
34
34
|
|
35
35
|
def initialize(app, options)
|
36
36
|
super(app)
|
@@ -54,7 +54,7 @@ module FaradayMiddleware
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def oauth_options(env)
|
57
|
-
if extra = env[:request][:oauth]
|
57
|
+
if (extra = env[:request][:oauth]) && extra.is_a?(Hash) && !extra.empty?
|
58
58
|
@options.merge extra
|
59
59
|
else
|
60
60
|
@options
|
@@ -73,12 +73,15 @@ module FaradayMiddleware
|
|
73
73
|
|
74
74
|
def include_body_params?(env)
|
75
75
|
# see RFC 5849, section 3.4.1.3.1 for details
|
76
|
-
!(type = env[:request_headers][CONTENT_TYPE])
|
76
|
+
!(type = env[:request_headers][CONTENT_TYPE]) || (type == TYPE_URLENCODED)
|
77
77
|
end
|
78
78
|
|
79
79
|
def signature_params(params)
|
80
|
-
params.empty?
|
81
|
-
params
|
80
|
+
if params.empty?
|
81
|
+
params
|
82
|
+
else
|
83
|
+
params.reject { |_k, v| v.respond_to?(:content_type) }
|
84
|
+
end
|
82
85
|
end
|
83
86
|
end
|
84
87
|
end
|
@@ -1,11 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'faraday'
|
2
4
|
require 'forwardable'
|
3
5
|
|
4
6
|
module FaradayMiddleware
|
5
7
|
# Public: A simple middleware that adds an access token to each request.
|
6
8
|
#
|
7
|
-
#
|
8
|
-
# "Authorization" HTTP request header.
|
9
|
+
# By default, the token is added as both "access_token" query parameter
|
10
|
+
# and the "Authorization" HTTP request header. It can alternatively be
|
11
|
+
# added exclusively as a bearer token "Authorization" header by specifying
|
12
|
+
# a "token_type" option of "bearer". However, an explicit "access_token"
|
9
13
|
# parameter or "Authorization" header for the current request are not
|
10
14
|
# overriden.
|
11
15
|
#
|
@@ -17,14 +21,17 @@ module FaradayMiddleware
|
|
17
21
|
# # configure query parameter name:
|
18
22
|
# OAuth2.new(app, 'abc123', :param_name => 'my_oauth_token')
|
19
23
|
#
|
24
|
+
# # use bearer token authorization header only
|
25
|
+
# OAuth2.new(app, 'abc123', :token_type => 'bearer')
|
26
|
+
#
|
20
27
|
# # default token value is optional:
|
21
28
|
# OAuth2.new(app, :param_name => 'my_oauth_token')
|
22
29
|
class OAuth2 < Faraday::Middleware
|
30
|
+
PARAM_NAME = 'access_token'
|
31
|
+
TOKEN_TYPE = 'param'
|
32
|
+
AUTH_HEADER = 'Authorization'
|
23
33
|
|
24
|
-
|
25
|
-
AUTH_HEADER = 'Authorization'.freeze
|
26
|
-
|
27
|
-
attr_reader :param_name
|
34
|
+
attr_reader :param_name, :token_type
|
28
35
|
|
29
36
|
extend Forwardable
|
30
37
|
def_delegators :'Faraday::Utils', :parse_query, :build_query
|
@@ -34,8 +41,13 @@ module FaradayMiddleware
|
|
34
41
|
token = params[param_name]
|
35
42
|
|
36
43
|
if token.respond_to?(:empty?) && !token.empty?
|
37
|
-
|
38
|
-
|
44
|
+
case @token_type.downcase
|
45
|
+
when 'param'
|
46
|
+
env[:url].query = build_query params
|
47
|
+
env[:request_headers][AUTH_HEADER] ||= %(Token token="#{token}")
|
48
|
+
when 'bearer'
|
49
|
+
env[:request_headers][AUTH_HEADER] ||= %(Bearer #{token})
|
50
|
+
end
|
39
51
|
end
|
40
52
|
|
41
53
|
@app.call env
|
@@ -43,14 +55,27 @@ module FaradayMiddleware
|
|
43
55
|
|
44
56
|
def initialize(app, token = nil, options = {})
|
45
57
|
super(app)
|
46
|
-
|
47
|
-
|
58
|
+
if token.is_a? Hash
|
59
|
+
options = token
|
60
|
+
token = nil
|
61
|
+
end
|
62
|
+
@token = token&.to_s
|
48
63
|
@param_name = options.fetch(:param_name, PARAM_NAME).to_s
|
49
|
-
|
64
|
+
@token_type = options.fetch(:token_type, TOKEN_TYPE).to_s
|
65
|
+
|
66
|
+
raise ArgumentError, ":param_name can't be blank" if @token_type == 'param' && @param_name.empty?
|
67
|
+
|
68
|
+
return unless options[:token_type].nil?
|
69
|
+
|
70
|
+
warn "\nWarning: FaradayMiddleware::OAuth2 initialized with default "\
|
71
|
+
'token_type - token will be added as both a query string parameter '\
|
72
|
+
'and an Authorization header. In the next major release, tokens will '\
|
73
|
+
'be added exclusively as an Authorization header by default. Please '\
|
74
|
+
'see https://github.com/lostisland/faraday_middleware/wiki.'
|
50
75
|
end
|
51
76
|
|
52
77
|
def query_params(url)
|
53
|
-
if url.query.nil?
|
78
|
+
if url.query.nil? || url.query.empty?
|
54
79
|
{}
|
55
80
|
else
|
56
81
|
parse_query url.query
|