10:32 am, 12 Jan 08
weird type flexibility (ruby-openid and chr)
So a couple of others have had trouble with the ruby-openid library. The problem is that starting up the whole thing with:
fails with
The problem is due to this interesting behavior of the CGI module.
Say you have a CGI parameter called 'foo' with the value of 'bar'. Then the following things are true:
But you're typically using OpenID in a web server context and that warning apparently isn't enough to trigger the "internal server error" result.
The fix is to instead use
where
I'm clearly rusty on this whole "dynamic language" thing, because I found the above kinda confusing. (Haskell and C++, which are what I mostly hack these days, are pretty different but also quite similar in some aspects of what you can't do.) Hopefully I've stuck enough text in this post for future Googler-seekers to see the problem.
consumer.begin(cgi['openid'])
fails with
undefined method `chr' for "foo":String
/var/lib/gems/1.8/gems/ruby-openid-2.0.2/l ib/openid/yadis/xri.rb:16:in `identifier_scheme'
/var/lib/gems/1.8/gems/ruby-openid-2.0.2/l ib/openid/consumer/discovery.rb:474:in `discover'
/var/lib/gems/1.8/gems/ruby-openid-2.0.2/l ib/openid/consumer.rb:333:in `discover'
/usr/lib/ruby/1.8/rubygems/custom_requir e.rb:27:in `to_proc'
/var/lib/gems/1.8/gems/ruby-openid-2.0.2/l ib/openid/consumer/discovery_manager.rb:5 1:in `get_next_service'
/var/lib/gems/1.8/gems/ruby-openid-2.0.2/l ib/openid/consumer.rb:222:in `begin'
The problem is due to this interesting behavior of the CGI module.
Say you have a CGI parameter called 'foo' with the value of 'bar'. Then the following things are true:
p cgi['foo'] # => 'bar' p cgi['foo'].class # => String p cgi['foo'][0] # => 'bar' p cgi['foo'].to_s[0] # => 'bar' p cgi['foo'].to_str # => 'bar' p cgi['foo'].to_str[0] # => 'bar'This is due to a questionable hack in the CGI module, where the string object is extended with a new method that breaks the string interface. It turns out it prints a warning if you try this:
/var/lib/gems/1.8/gems/ruby-openid-2.0.2/l ib/openid/yadis/xri.rb:16:in `identifier_scheme':CAUTION! cgi['key'] == cgi.params['key'][0]; if want Array, use cgi.params['key']
But you're typically using OpenID in a web server context and that warning apparently isn't enough to trigger the "internal server error" result.
The fix is to instead use
consumer.begin(cgi.params['openid'][0])
where
#params
just gives you the parameter value in a hash (with a default value of []
so it's safe to index without checking for the key).I'm clearly rusty on this whole "dynamic language" thing, because I found the above kinda confusing. (Haskell and C++, which are what I mostly hack these days, are pretty different but also quite similar in some aspects of what you can't do.) Hopefully I've stuck enough text in this post for future Googler-seekers to see the problem.
Is this that crazy Perlbal plugin that returns a response that never ends? I used it as a reference for how to do async responses to the Perlbal instance I embedded in DJabberd, but didn't really look into exactly what it did. That's kinda crazy. Now that I read that page you linked to, I vaugely remember this being mentioned somewhere.
read_multipart() is a pretty choice method that returns either a stringio *or* tempfile with a few extra methods punched in. Makes testing a real joy.