class Puppet::HTTP::Redirector

Handle HTTP redirects

@api private

Public Class Methods

new(redirect_limit) click to toggle source

Create a new redirect handler

@param [Integer] redirect_limit maximum number of redirects allowed

@api private

   # File lib/puppet/http/redirector.rb
11 def initialize(redirect_limit)
12   @redirect_limit = redirect_limit
13 end

Public Instance Methods

redirect?(request, response) click to toggle source

Determine of the HTTP response code indicates a redirect

@param [Net::HTTP] request request that received the response @param [Puppet::HTTP::Response] response

@return [Boolean] true if the response code is 301, 302, or 307.

@api private

   # File lib/puppet/http/redirector.rb
23 def redirect?(request, response)
24   # Net::HTTPRedirection is not used because historically puppet
25   # has only handled these, and we're not a browser
26   case response.code
27   when 301, 302, 307
28     true
29   else
30     false
31   end
32 end
redirect_to(request, response, redirects) click to toggle source

Implement the HTTP request redirection

@param [Net::HTTP] request request that has been redirected @param [Puppet::HTTP::Response] response @param [Integer] redirects the current number of redirects

@return [Net::HTTP] A new request based on the original request, but with

the redirected location

@api private

   # File lib/puppet/http/redirector.rb
44 def redirect_to(request, response, redirects)
45   raise Puppet::HTTP::TooManyRedirects.new(request.uri) if redirects >= @redirect_limit
46 
47   location = parse_location(response)
48   url = request.uri.merge(location)
49 
50   new_request = request.class.new(url)
51   new_request.body = request.body
52   request.each do |header, value|
53     unless Puppet[:location_trusted]
54       # skip adding potentially sensitive header to other hosts
55       next if header.casecmp('Authorization').zero? && request.uri.host.casecmp(location.host) != 0
56       next if header.casecmp('Cookie').zero? && request.uri.host.casecmp(location.host) != 0
57     end
58     new_request[header] = value
59   end
60 
61   # mimic private Net::HTTP#addr_port
62   new_request['Host'] = if (location.scheme == 'https' && location.port == 443) ||
63                            (location.scheme == 'http' && location.port == 80)
64                           location.host
65                         else
66                           "#{location.host}:#{location.port}"
67                         end
68 
69   new_request
70 end

Private Instance Methods

parse_location(response) click to toggle source
   # File lib/puppet/http/redirector.rb
74 def parse_location(response)
75   location = response['location']
76   raise Puppet::HTTP::ProtocolError.new(_("Location response header is missing")) unless location
77 
78   URI.parse(location)
79 rescue URI::InvalidURIError => e
80   raise Puppet::HTTP::ProtocolError.new(_("Location URI is invalid: %{detail}") % { detail: e.message}, e)
81 end