Public: Follow HTTP 301, 302, 303, and 307 redirects.
For HTTP 301, 302, and 303, the original GET, POST, PUT, DELETE, or PATCH request gets converted into a GET. With `:standards_compliant => true`, however, the HTTP method after 301/302 remains unchanged. This allows you to opt into HTTP/1.1 compliance and act unlike the major web browsers.
This middleware currently only works with synchronous requests; i.e. it doesn't support parallelism.
If you wish to persist cookies across redirects, you could use the faraday-cookie_jar gem:
Faraday.new(:url => url) do |faraday| faraday.use FaradayMiddleware::FollowRedirects faraday.use :cookie_jar faraday.adapter Faraday.default_adapter end
HTTP methods for which 30x redirects can be followed
Keys in env hash which will get cleared between requests
Default value for max redirects followed
HTTP redirect status codes that this middleware implements
Regex that matches characters that need to be escaped in URLs, sans the “%” character which we assume already represents an escaped sequence.
Public: Initialize the middleware.
options - An options Hash (default: {}):
:limit - A Numeric redirect limit (default: 3) :standards_compliant - A Boolean indicating whether to respect the HTTP spec when following 301/302 (default: false)
# File lib/faraday_middleware/response/follow_redirects.rb, line 55 def initialize(app, options = {}) super(app) @options = options @convert_to_get = Set.new [303] @convert_to_get << 301 << 302 unless standards_compliant? end
# File lib/faraday_middleware/response/follow_redirects.rb, line 63 def call(env) perform_with_redirection(env, follow_limit) end
# File lib/faraday_middleware/response/follow_redirects.rb, line 69 def convert_to_get?(response) ![:head, :options].include?(response.env[:method]) && @convert_to_get.include?(response.status) end
# File lib/faraday_middleware/response/follow_redirects.rb, line 108 def follow_limit @options.fetch(:limit, FOLLOW_LIMIT) end
# File lib/faraday_middleware/response/follow_redirects.rb, line 103 def follow_redirect?(env, response) ALLOWED_METHODS.include? env[:method] and REDIRECT_CODES.include? response.status end
# File lib/faraday_middleware/response/follow_redirects.rb, line 74 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
Internal: escapes unsafe characters from an URL which might be a path component only or a fully qualified URI so that it can be joined onto an URI:HTTP using the `+` operator. Doesn't escape “%” characters so to not risk double-escaping.
# File lib/faraday_middleware/response/follow_redirects.rb, line 120 def safe_escape(uri) uri.to_s.gsub(URI_UNSAFE) { |match| '%' + match.unpack('H2' * match.bytesize).join('%').upcase } end
# File lib/faraday_middleware/response/follow_redirects.rb, line 112 def standards_compliant? @options.fetch(:standards_compliant, false) end
# File lib/faraday_middleware/response/follow_redirects.rb, line 88 def update_env(env, request_body, response) env[:url] += safe_escape(response['location']) 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