Skip to content

Commit

Permalink
Use stateful CookieJar in Redirector
Browse files Browse the repository at this point in the history
As [mentioned](../issues/264#issuecomment-157070867) in #264, CookieJar
implements cookie domain scoping rules, which is useful when issuing
redirects across domains.

Resolves: #264
  • Loading branch information
Kache committed Jun 15, 2020
1 parent dbc73e3 commit b03076a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
14 changes: 13 additions & 1 deletion lib/http/redirector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ class EndlessRedirectError < TooManyRedirectsError; end
# @param [Hash] opts
# @option opts [Boolean] :strict (true) redirector hops policy
# @option opts [#to_i] :max_hops (5) maximum allowed amount of hops
# @option opts [HTTP::CookieJar] :jar (HTTP::CookieJar.new) stateful CookieJar used across hops
def initialize(opts = {}) # rubocop:disable Style/OptionHash
@strict = opts.fetch(:strict, true)
@max_hops = opts.fetch(:max_hops, 5).to_i
@jar = opts.fetch(:jar, CookieJar.new)
end

# Follows redirects until non-redirect response found
Expand All @@ -50,6 +52,13 @@ def perform(request, response)
@response = response
@visited = []

# load first request's cookies into CookieJar,
# treating them as if they were there to begin with
sent_cookies_raw = @request.headers.get(HTTP::Headers::COOKIE).join("; ")
sent_cookies_raw.split("; ").each do |name_val|
@jar << Cookie.new(*name_val.split("=", 2), :origin => request.uri, :secure => request.uri.https?)
end

while REDIRECT_CODES.include? @response.status.code
@visited << "#{@request.verb} #{@request.uri}"

Expand All @@ -61,6 +70,7 @@ def perform(request, response)
# XXX(ixti): using `Array#inject` to return `nil` if no Location header.
@request = redirect_to(@response.headers.get(Headers::LOCATION).inject(:+))
@response = yield @request
@response.cookies.inject(@jar, :<<)
end

@response
Expand Down Expand Up @@ -94,8 +104,10 @@ def redirect_to(uri)
end

verb = :get if !SEE_OTHER_ALLOWED_VERBS.include?(verb) && 303 == code
redirect_uri = @request.uri.join(uri)
cookies_raw = @jar.each(redirect_uri).map(&:cookie_value).join("; ")

@request.redirect(uri, verb)
@request.redirect(uri, verb, :cookies_raw => cookies_raw)
end
end
end
3 changes: 2 additions & 1 deletion lib/http/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,10 @@ def initialize(opts)
end

# Returns new Request with updated uri
def redirect(uri, verb = @verb)
def redirect(uri, verb = @verb, cookies_raw: nil)
headers = self.headers.dup
headers.delete(Headers::HOST)
headers[Headers::COOKIE] = cookies_raw if cookies_raw

self.class.new(
:verb => verb,
Expand Down

0 comments on commit b03076a

Please sign in to comment.