Reputation: 13456
How can I write a Rack Middleware to redirect a user to a different subdomain based on the User Agent string? I need this to run before Rack::Cache in my rails app, and I also would like this middleware to be able to detect the presence of a cookie.
Currently if we set cache headers in our rails app for the home page, Rack::Cache caches the home page but when a mobile user visits the main "www" domain, Rack::Cache serves up the cached version of the page without hitting the rest of our rails app, so our mobile redirect is never executed.
It would seem as though I will have to move our mobile redirect solution into middleware that executes before Rack::Cache. For context, here is what our filters look like in our ApplicationController:
before_filter :set_mobile_preferences
before_filter :redirect_to_mobile_if_applicable
def set_mobile_preferences
if params[:mobile_site]
cookies.delete(:prefer_web)
elsif params[:full_site]
cookies.permanent[:prefer_web] = 1
redirect_to_full_site if mobile_request?
end
end
# before filter
def redirect_to_mobile_if_applicable
if mobile_device? && !mobile_request? && !prefers_full_site?
new_url = request.protocol + domain_prefixes[:mobile] + '.' +
request.host_with_port.gsub(/^#{domain_prefixes[:web]}?\./, '') +
request.fullpath
redirect_to new_url and return
end
end
Does anyone have experience with both caching pages and redirecting mobile users to an alternate domain? Does moving this redirection to middleware before the cache layer seem like the right solution?
Any tips, links, suggestions are greatly appreciated. Thanks!
Update: Maybe I can use the Vary: User-Agent
header to help with the cache issue? However, I'm concerned if I do this then the cache will fill up with multiple copies of the same page because of the hundreds of variations on User-Agent strings sent by browsers.
Upvotes: 3
Views: 993
Reputation: 13456
So, I've decided to write our own middleware to detect mobile user-agent strings, redirect to a subdomain, and also detect the presence of a site-preference cookie so we only redirect users based on user-agent only if they have not specified otherwise. I moved this up in the Rack stack so it executes before Rack::Cache and that seems to fix our issue. You can view the source here: https://gist.github.com/3630760
Upvotes: 4