[offtopic] HTTP Authentication in Safari is broken for RESTful Rails

17 views
Skip to first unread message

Thijs van der Vossen

unread,
Nov 24, 2006, 2:35:32 PM11/24/06
to rubyonra...@googlegroups.com
There's currently a bug in Safari, or more likely somewhere in the OS
X HTTP API that breaks HTTP Authentication when there is a semicolon
in the path part of the URL. This means it's impossible to use HTTP
Authentication when you're building a RESTful Rails app that needs to
work in Safari.

More details can be found at http://bugs.webkit.org/show_bug.cgi?
id=10073

There's a test page at http://onautopilot.com/test;webkit that should
ask you for a username and a password.

Right now this still seems to be broken in Leopard. It would be great
if somebody who knows the right people inside Apple could try to
raise awareness of this issue. It would be somewhat ironic if Leopard
Server ships with Rails while this is still broken.

Kind regards,
Thijs

Tim Lucas

unread,
Nov 24, 2006, 6:01:15 PM11/24/06
to rubyonra...@googlegroups.com
On 25/11/2006, at 6:35 AM, Thijs van der Vossen wrote:

>
> There's currently a bug in Safari, or more likely somewhere in the OS
> X HTTP API that breaks HTTP Authentication when there is a semicolon
> in the path part of the URL. This means it's impossible to use HTTP
> Authentication when you're building a RESTful Rails app that needs to
> work in Safari.

I stumbled across this in September, and it required this ugly, ugly
work around:
http://toolmantim.com/article/2006/9/19/
safari_urls_the_semi_colon_and_one_night_in_paris

Thanks for raising the issue properly and trying to get it addressed.

-- tim

Thijs van der Vossen

unread,
Nov 29, 2006, 8:09:37 AM11/29/06
to rubyonra...@googlegroups.com

Great idea to try escaping the semicolon!
For those interested, you can work around this issue by adding the
following to your ApplicationController in app/controllers/
application.rb:

# make HTTP Authentication work on Safari for RESTful Rails
alias_method :orig_url_for, :url_for
def url_for(options = {}, *parameters_for_method_reference)
result = orig_url_for(options, parameters_for_method_reference)
if request.env['HTTP_USER_AGENT'].to_s.include? 'AppleWebKit'
result.is_a?(String) ? result.gsub(';', '%3B') : result
else
result
end
end

Kind regards,
Thijs

Jamis Buck

unread,
Nov 29, 2006, 10:11:42 AM11/29/06
to rubyonra...@googlegroups.com

Very nice, Thijs. A minor nitpick, and nothing to do with the actual
solution: when overriding a method in a subclass, you can just call
'super' to get at the original. You don't actually need to alias the
original. The alias trick is only needed when you are altering a
method of the current class. For instance, if you were monkeypatching
a new url_for implementation into ActionController::Base itself,
you'd need to use alias there to preserve the original url_for.

- Jamis Buck
ja...@37signals.com


Tim Lucas

unread,
Nov 29, 2006, 8:48:04 PM11/29/06
to rubyonra...@googlegroups.com

Thanks Thijs, updated accordingly (with slightly cleaner code):
http://toolmantim.com/article/2006/9/19/
safari_urls_the_semi_colon_and_one_night_in_paris

-- tim


Thijs van der Vossen

unread,
Nov 30, 2006, 4:05:15 AM11/30/06
to rubyonra...@googlegroups.com

At first I tried to call super as Tim did, but I ended up with an url
without the ';edit' part while using the url helpers generated by
ActionController::Resources.

I've looked into this again and it seems that I need to explicitly
pass the parameters to super to make it work. Like this:

def url_for(options = {}, *parameters_for_method_reference)

result = super(options, parameters_for_method_reference)


if request.env['HTTP_USER_AGENT'].to_s.include? 'AppleWebKit'
result.is_a?(String) ? result.gsub(';','%3B') : result
else
result
end
end

My understanding of super was that it passed the original method's
parameters, but maybe not in this case.

Kind regards,
Thijs

PGP.sig
Reply all
Reply to author
Forward
0 new messages