Skip to navigation

Safari, URLs, the semi-colon and one night in Paris

Published September 19, 2006 - Updated March 09, 2007

Update: Manfred (of fingertips) has released a plugin to fix Safari whilst we wait for Apple to update OS X.

My production site is spitting the dummy with Safari whenever there’s a semi-colon in the URL.

As far as I can tell you don’t need to escape semi-colons, and every other browser works just fine.

In the mean time, here’s the dirtiest of dirty hacks to ensure semi-colons get escaped.

In application.rb:


def url_for(options = {}, *parameters_for_method_reference)
  (result = super).is_a?(String) ? result.gsub(';','%3B') : result
end

Surely there’s people running on Rails edge using the Rest stuff with Safari? I wonder what’s causing it on this site.

Any recommendations on software for OS X to sniff the requests between Safari and Apache?

Update_: After further discussion on rails-corethread/thread/9f7d8d2ae530a5da/0cae138836e0e558#0cae138836e0e558, the following would probably lock things down further:


def url_for(options = {}, *parameters_for_method_reference)
  if safari? && authenticated?
    (url = super).is_a?(String) ? url.gsub(';','%3B') : url
  else
    super
  end
end

def safari?
  request.env['HTTP_USER_AGENT'].to_s.include?('AppleWebKit')
end

@@auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)
def authenticated?
  @@auth_headers.any? { |h| request.env.has_key?(h) }
end

Archived comments

Comments were previously allowed on articles. Though no new comments are being accepted you can see the old comments below.

  1. Tom Riley

    I had the same problem on my test site (it worked fine for me locally). I was using http authentication to hide my test site from the world. and it turned out that safari wasn’t sending the authentication information if the semicolon is present in the URL so lighttpd was returning a 401 error. You can spot this in the server access logs (note the 3rd element, the username, is blank).

    So unprotecting the site fixes the problem.

  2. Tim Lucas

    Ahhh… thankyou Tom! I too found the problem whilst the site was still in testing. Didn’t notice that in the Apache logs…

  3. Thijs van der Vossen

    We came across this some time ago, but I never thought about trying to escape the semicolon. Excellent suggestion.

  4. Dan Kubb

    I don’t like escaping the URLs in ruby code, since I use caching alot, and I don’t want other browsers to get one of those URLs.

    Instead I do the escaping on the client side using JavaScript. Here’s an example of how I do it using the jQuery library:

    
    $(document).ready(function() {
      if(jQuery.browser.safari) {
        tags = { a: 'href', form: 'action' }
        for ( var t in tags ) {
          $(t + '[@' + tags[t] + '*=;]').each(function() {
            $(this).attr(tags[t], $(this).attr(tags[t]).replace(/;/g, '%3B'));
          });
        }
      }
    });
    

Previously: Resource feeder rocks

Next up: Web Connections

Thoughts

toolmantim

I’m Tim Lucas, a user experience developer currently in Sydney Australia.

I occasionally write, snap photos, present on various technical topics, tweet my going-ons, share teh codes and post tidbits to the scrapbook.

Most recently I published Simplifying ticket sales on sydneyoperahouse.com (February 16, 2010)

Work with me via Agency Rainford, or shoot an email to and say hello.

Powered by procrastination