4

I'm using the following code to make a request and follow redirects:

require 'faraday'
require 'faraday_middleware'
conn = Faraday.new() do |f|
  f.use FaradayMiddleware::FollowRedirects, limit: 5
  f.adapter Faraday.default_adapter
end
resp = conn.get('http://www.example.com/redirect')
resp.status

This code outputs 200 because it followed the redirect, which is great. But is there anyway to know if a redirect existed or not? something like resp.redirected which is set to true if a redirect was followed or false if no redirect was followed?

I didn't see anything obvious in the FollowRedirects code.

Will I need to write my own custom middleware if I want to know this? Does anyone know of middleware out there that might do this already?

Russ Savage
  • 598
  • 4
  • 20
  • 1
    Check out Typhoeus https://github.com/typhoeus/typhoeus, search for followlocation. I don't know if it does what you want but it might. :-) You might want to run a debugger and check the response object for any hints. – Ollie Apr 16 '15 at 07:29
  • thanks! I think the code I have is following the redirect correctly. What i am interested in is knowing when a redirect was followed. I think i need to compare the resulting url with the original url and see if they are the same. I just don't know if the Faraday response has the final url anywhere in it. – Russ Savage Apr 16 '15 at 18:39
  • 1
    I know, I was just wondering if it had some helper method to tell you if it was redirected or not. :-) – Ollie Apr 17 '15 at 10:46
  • You did spark something that made me think of the answer below, so thank you. – Russ Savage Apr 17 '15 at 15:51

2 Answers2

4

I found a solution. You can pass a callback to FaradayMiddleware::FollowRedirects. The callback should live in a hash that the FollowRedirects takes a second parameter. Since we have to use the use function for middleware you can pass the hash as a second parameter to that function.

  redirects_opts = {}

  # Callback function for FaradayMiddleware::FollowRedirects
  # will only be called if redirected to another url
  redirects_opts[:callback] = proc do |old_response, new_response|

    # you can pull the new redirected URL with this line of code.
    # since you have access to the new url you can make a variable or 
    # instance vairable to keep track of the current URL

    puts 'new url', new_response.url
  end

  @base_client = Faraday.new(url: url, ssl: { verify: true, verify_mode: 0 }) do |c|
    c.request :multipart
    c.request :url_encoded
    c.response :json, content_type: /\bjson$/
    c.use FaradayMiddleware::FollowRedirects, redirects_opts //<- pass hash here
    c.adapter Faraday.default_adapter
  end
-1

Actually, I think I just found the answer based on the post here: https://stackoverflow.com/a/20818142/4701287

I need to compare the original url i passed in with the resulting url. Extending my example from above:

original_url = 'http://www.example.com/redirect'
resp = conn.get(original_url)
was_redirected = (original_url == resp.to_hash[:url].to_s)
Community
  • 1
  • 1
Russ Savage
  • 598
  • 4
  • 20