Daniel Doubrovkine bio photo

Daniel Doubrovkine

aka dB., CTO at artsy.net, fun at playplay.io, NYC

Email Twitter LinkedIn Github

Let’s filter out some unwanted browsers from displaying broken pages in our Rails application. We could disallow IE6, for example, but allow IE7, 8 and 9.

Bring in the useragent gem – we’ll need to take it from a popular jillion fork – it has a ton of fixes that became too hard to merge back to its parent. The latter has many bugs in version comparisons to make it useful for our purposes as of the time of writing this.

gem "useragent", :git => "https://github.com/jilion/useragent.git"

We can add an app_initialization _to _ApplicationController that all controllers derive from which will render an error page if the browser is not supported.

class ApplicationController < ActionController::Base
  include ApplicationHelper

  before_filter :app_initialization

  def app_initialization
    if is_browser_unsupported?
      render :template => "errors/browser", :status => 406, :layout => false
    end
  end

end

The template can be a page placed in app/views/errors/browser.html.haml.

%html
  %head
    = include_stylesheets :common
    = include_stylesheets :errors
  %body

    %h1 Your browser is not supported. We're working on it.

    .user_agent
      = @user_agent

Finally, declare an array of supported and an array of unsupported browsers within ApplicationController. A supported browser is a structure of browser name and version. An unsupported browser name is sufficient. We first check whether the browser is explicitly unsupported, then whether the version of a supported browser is bigger or equal to a specific one.

Browser = Struct.new(:browser, :version)
SUPPORTED_BROWSERS = [
  Browser.new("Chrome", "10.0"),
  Browser.new("Safari", "3.0"),
  Browser.new("Firefox", "3.6"),
  Browser.new("Internet Explorer", "9.0"),
]

UNSUPPORTED_BROWSERS = [
  "Opera", "Opera Mini"
]

Finally, we let everyone with an unknown browser through – we can’t possibly whitelist hundreds of search engine user-agents.

def is_browser_unsupported?
  return false if (Rails.env.test? and request.user_agent.blank?)
  @user_agent = UserAgent.parse(request.user_agent)
  return true if UNSUPPORTED_BROWSERS.include?(@user_agent.browser)
  return true if SUPPORTED_BROWSERS.any? { |browser| @user_agent < browser }
  false
end