class Github::Response::FollowRedirects

def call(env)

def call(env)
  perform_with_redirection(env, follow_limit)
end

def callback

def callback
  @options[:callback]
end

def convert_to_get?(response)

def convert_to_get?(response)
  ![:head, :options].include?(response.env[:method]) &&
    @convert_to_get.include?(response.status)
end

def follow_limit

def follow_limit
  @options.fetch(:limit, FOLLOW_LIMIT)
end

def follow_redirect?(env, response)

def follow_redirect?(env, response)
  ALLOWED_METHODS.include? env[:method] and
    REDIRECT_CODES.include? response.status
end

def initialize(app, options = {})

with the old and new envs
:callback - A callable that will be called on redirects
(default: false)
the HTTP spec when following 301/302
:standards_compliant - A Boolean indicating whether to respect
:limit - A Numeric redirect limit (default: 3)
options - An options Hash (default: {}):

Public: Initialize the middleware.
def initialize(app, options = {})
  super(app)
  @options = options
  @convert_to_get = Set.new [303]
  @convert_to_get << 301 << 302 unless standards_compliant?
end

def perform_with_redirection(env, follows)

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.dup, request_body, response)
      callback.call(response_env, new_request_env) if callback
      response = perform_with_redirection(new_request_env, follows - 1)
    end
  end
  response
end

def safe_escape(uri)

risk double-escaping.
URI:HTTP using the `+` operator. Doesn't escape "%" characters so to not
component only or a fully qualified URI so that it can be joined onto an
Internal: escapes unsafe characters from an URL which might be a path
def safe_escape(uri)
  uri = uri.split('#')[0] # we want to remove the fragment if present
  uri.to_s.gsub(URI_UNSAFE) { |match|
    '%' + match.unpack('H2' * match.bytesize).join('%').upcase
  }
end

def standards_compliant?

def standards_compliant?
  @options.fetch(:standards_compliant, false)
end

def update_env(env, request_body, response)

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