Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Redirect Mobile User-Agent to Subdomain as Rack Middleware (in Rails)
module YourApp
class Application < Rails::Application
# ...
config.middleware.insert_before "Rack::Cache", "SubdomainRedirect"
# ...
end
end
class SubdomainRedirect
# we could set these values with the options array if needed
def initialize(app, options = {})
@app = app
@regex_ua_targeted = /iPhone|iPod|Android|RIM|BlackBerry|webOS|Mobile/i
@subdomain_mobile = 'm'
@subdomain_full = 'www'
end
def call(env)
# we need ActionDispatch::Request for cookie access
request = ActionDispatch::Request.new(env)
if request.GET.has_key?('mobile_site')
request.cookie_jar.permanent[:site_pref] = @subdomain_mobile
return redirect_to_mobile_site(request) unless mobile_site?(request)
elsif request.GET.has_key?('full_site')
request.cookie_jar.permanent[:site_pref] = @subdomain_full
return redirect_to_full_site(request) unless full_site?(request)
end
mobile_device = request.user_agent =~ @regex_ua_targeted
if !mobile_site?(request) && (prefers_mobile_site?(request) || (mobile_device && !prefers_full_site?(request)))
return redirect_to_mobile_site(request)
end
if !full_site?(request) && (prefers_full_site?(request) || (!mobile_device && !prefers_mobile_site?(request)))
return redirect_to_full_site(request)
end
@app.call(env)
end
def redirect_to_mobile_site(request)
[301, {"Location" => request.url.sub(/\/\/(#{@subdomain_full}\.)?/i, "//#{@subdomain_mobile}.")}, self]
end
def redirect_to_full_site(request)
[301, {"Location" => request.url.sub(/\/\/(#{@subdomain_mobile}\.)?/i, "//#{@subdomain_full}.")}, self]
end
def prefers_mobile_site?(request)
request.cookie_jar[:site_pref] == @subdomain_mobile
end
def prefers_full_site?(request)
request.cookie_jar[:site_pref] == @subdomain_full
end
def full_site?(request)
request.host =~ /^#{@subdomain_full}/i
end
def mobile_site?(request)
request.host =~ /^#{@subdomain_mobile}/i
end
def each(&block)
end
end
@stereoscott
Copy link
Author

stereoscott commented Sep 5, 2012

Redirect targeted user-agents to a mobile subdomain before rack::cache serves up a cached version of the URL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment