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.
-
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.
-
Ahhh… thankyou Tom! I too found the problem whilst the site was still in testing. Didn’t notice that in the Apache logs…
-
We came across this some time ago, but I never thought about trying to escape the semicolon. Excellent suggestion.
-
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')); }); } } });