Class: Octokit::Middleware::FollowRedirects
Relationships & Source Files | |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
Faraday::Middleware
|
|
Instance Chain:
self,
Faraday::Middleware
|
|
Inherits: |
Faraday::Middleware
|
Defined in: | lib/octokit/middleware/follow_redirects.rb |
Overview
Public: Follow HTTP 301, 302, 303, and 307 redirects.
For HTTP 303, the original GET, POST, PUT, DELETE, or PATCH request gets converted into a GET. For HTTP 301, 302, and 307, the HTTP method remains unchanged.
This middleware currently only works with synchronous requests; i.e. it doesn't support parallelism.
Constant Summary
-
ALLOWED_METHODS =
HTTP methods for which 30x redirects can be followed
Set.new %i[head options get post put patch delete]
-
ENV_TO_CLEAR =
Keys in env hash which will get cleared between requests
Set.new %i[status response response_headers]
-
FOLLOW_LIMIT =
::Octokit::Default
value for max redirects followed3
-
REDIRECT_CODES =
HTTP redirect status codes that this middleware implements
Set.new [301, 302, 303, 307]
-
URI_UNSAFE =
Regex that matches characters that need to be escaped in URLs, sans the "%" character which we assume already represents an escaped sequence.
%r{[^\-_.!~*'()a-zA-Z\d;/?:@&=+$,\[\]%]}.freeze
Class Method Summary
-
.new(app, options = {}) ⇒ FollowRedirects
constructor
Public: Initialize the middleware.
Instance Method Summary
- #call(env)
- #convert_to_get?(response) ⇒ Boolean private
- #follow_limit private
- #follow_redirect?(env, response) ⇒ Boolean private
- #perform_with_redirection(env, follows) private
-
#safe_escape(uri)
private
Internal: Escapes unsafe characters from a URL which might be a path component only or a fully-qualified URI so that it can be joined onto a URI:HTTP using the
+
operator. - #same_host?(original_url, redirect_url) ⇒ Boolean private
- #update_env(env, request_body, response) private
Constructor Details
.new(app, options = {}) ⇒ FollowRedirects
Public: Initialize the middleware.
options - An options Hash (default: {}): :limit - A Integer redirect limit (default: 3).
# File 'lib/octokit/middleware/follow_redirects.rb', line 53
def initialize(app, = {}) super(app) @options = @convert_to_get = Set.new [303] end
Instance Method Details
#call(env)
[ GitHub ]# File 'lib/octokit/middleware/follow_redirects.rb', line 60
def call(env) perform_with_redirection(env, follow_limit) end
#convert_to_get?(response) ⇒ Boolean
(private)
# File 'lib/octokit/middleware/follow_redirects.rb', line 66
def convert_to_get?(response) !%i[head options].include?(response.env[:method]) && @convert_to_get.include?(response.status) end
#follow_limit (private)
[ GitHub ]# File 'lib/octokit/middleware/follow_redirects.rb', line 113
def follow_limit @options.fetch(:limit, FOLLOW_LIMIT) end
#follow_redirect?(env, response) ⇒ Boolean
(private)
# File 'lib/octokit/middleware/follow_redirects.rb', line 108
def follow_redirect?(env, response) ALLOWED_METHODS.include?(env[:method]) && REDIRECT_CODES.include?(response.status) end
#perform_with_redirection(env, follows) (private)
[ GitHub ]# File 'lib/octokit/middleware/follow_redirects.rb', line 71
def perform_with_redirection(env, follows) request_body = env[:body] response = @app.call(env) response.on_complete do |response_env| if follow_redirect?(response_env, response) raise(RedirectLimitReached, response) if follows.zero? new_request_env = update_env(response_env, request_body, response) response = perform_with_redirection(new_request_env, follows - 1) end end response end
#safe_escape(uri) (private)
Internal: Escapes unsafe characters from a URL which might be a path
component only or a fully-qualified URI so that it can be joined onto a
URI:HTTP using the +
operator. Doesn't escape "%" characters so to not
risk double-escaping.
# File 'lib/octokit/middleware/follow_redirects.rb', line 128
def safe_escape(uri) uri.to_s.gsub(URI_UNSAFE) do |match| "%#{match.unpack('H2' * match.bytesize).join('%').upcase}" end end
#same_host?(original_url, redirect_url) ⇒ Boolean
(private)
# File 'lib/octokit/middleware/follow_redirects.rb', line 117
def same_host?(original_url, redirect_url) original_uri = Addressable::URI.parse(original_url) redirect_uri = Addressable::URI.parse(redirect_url) redirect_uri.host.nil? || original_uri.host == redirect_uri.host end
#update_env(env, request_body, response) (private)
[ GitHub ]# File 'lib/octokit/middleware/follow_redirects.rb', line 86
def update_env(env, request_body, response) original_url = env[:url] env[:url] += safe_escape(response['location']) unless same_host?(original_url, env[:url]) # HACK: Faraday’s Authorization middlewares don’t touch the request if the `Authorization` header is set. # This is a workaround to drop authentication info. # See https://github.com/octokit/octokit.rb/pull/1359#issuecomment-925609697 env[:request_headers]['Authorization'] = 'dummy' end if convert_to_get?(response) env[:method] = :get env[:body] = nil else env[:body] = request_body end ENV_TO_CLEAR.each { |key| env.delete(key) } env end