class Gems::RedirectHandler
Handles HTTP redirects for API requests @api private
Constants
- DEFAULT_MAX_REDIRECTS
-
Default maximum number of redirects to follow
Attributes
The connection for making requests @api private @return [Connection] the connection for making requests @example Get the connection
handler.connection
The request builder for creating requests @api private @return [RequestBuilder] the request builder for creating requests @example Get the request builder
handler.request_builder
Public Class Methods
Initialize a new RedirectHandler
@api private @param connection [Connection] the connection for making requests @param request_builder [RequestBuilder] the request builder for creating requests @param max_redirects [Integer] the maximum number of redirects to follow @return [RedirectHandler] a new instance @example Create a redirect handler
handler = Gems::RedirectHandler.new(connection: conn, request_builder: builder)
# File lib/gems/redirect_handler.rb, line 64 def initialize(connection: Connection.new, request_builder: RequestBuilder.new, max_redirects: DEFAULT_MAX_REDIRECTS) @connection = connection @request_builder = request_builder self.max_redirects = max_redirects end
Public Instance Methods
Handle redirects for an HTTP response
A redirect to another scheme, host, or port is followed without the credentials of the request, as curl and browsers do, so that a redirect cannot send them to a host they were not meant for. The headers the caller asked for are dropped along with them, since a header of the caller’s own may carry a credential too. A later redirect back to the original host does not restore either.
A redirect that cannot be followed, such as 304 Not Modified or one whose Location header is missing, is not a valid URL, or is not an HTTP or HTTPS URL, is returned as it is, so that the caller raises the HTTPError of its status.
A 307 or 308 redirect is followed with the method of the request and the body it was built from, which is given as it was given to {RequestBuilder#build}, since a multipart body cannot be read back from the request. One to another scheme, host, or port is not followed at all when the request has a body, and is returned as a redirect that cannot be followed is: the credentials of a request are not all carried by the headers a cross-origin redirect drops, since {API::APIKeyEndpoints#update_api_key} sends an API key as a form field and the trusted publishing token exchange sends an ID token as a JSON field, and a body replayed to the host the redirect names would take them there.
@api private @param response [Net::HTTPResponse] the HTTP response to handle @param request [Net::HTTPRequest] the original HTTP request @param authenticator [Authenticator] the authenticator for requests @param body [Hash, Array, String, nil] the body the request was built from @param content_type [String, nil] the content type the request was built with, for a String body @param headers [Hash{String => String}] the headers the request was built with @param redirect_count [Integer] the current redirect count @return [Net::HTTPResponse] the final HTTP response after following redirects @raise [TooManyRedirects] if the maximum number of redirects is exceeded @example Handle a response
response = handler.handle(response: resp, request: req)
# File lib/gems/redirect_handler.rb, line 102 def handle(response:, request:, authenticator: Authenticator.new, body: nil, content_type: nil, headers: {}, redirect_count: 0) return response unless response.is_a?(Net::HTTPRedirection) raise TooManyRedirects, "Too many redirects" if redirect_count >= max_redirects new_uri = build_new_uri(response, request) return response if new_uri.nil? follow(response:, request:, uri: new_uri, authenticator:, body:, content_type:, headers:, redirect_count:) end