Thinking Sphinx and Frozen Rails

February 19th, 2010

Here’s the situation: you’re trying to get the thinking_sphinx gem working with your Rails project on your local machine, and it doesn’t work.  In fact, when you follow the installation instructions and require “thinking_sphinx/tasks” in your Rakefile, you can’t even run rake anymore.

Running “rake -T” nets you the following error:

C:\dev\project>rake -T
(in c:/dev/project)
rake aborted!
undefined method ‘map’ for nil:NilClass
C:/ruby/lib/ruby/gems/1.8/gems/rake-0.8.7/lib/rake.rb:2383:in `raw_load_rakefile’
(See full trace by running task with –trace)

Here is the issue: in order to talk to your database, Thinking Sphinx is loading its own ActiveSupport.  It loads this ActiveSupport from your machine’s gem list, even if your Rails project is using frozen (vendor) Rails.  If you are getting the error shown above when you attempt to start your server or run rake, it means that your environment.rb specifies a RAILS_GEM_VERSION that is not installed on your machine.

Example?  You might have Rails gem versions 2.3.3 and 2.3.5 installed on your machine, but the frozen Rails in your project’s vendor directory (and thus your project’s RAILS_GEM_VERSION) is 2.3.4.

Now, it would seem that avoiding this type of scenario is the reason you are freezing Rails, but luckily there’s an easy fix.  Just install the missing version of the Rails gem, like so:

C:\>gem install rails -v 2.3.4

Hopefully this saves someone somewhere the headache it gave me.

(in c:/dev/mobd-fleet)
rake aborted!
undefined method `map’ for nil:NilClass
C:/devtools/ruby/lib/ruby/

gems/1.8/gems/rake-0.8.7/lib/rake.rb:2383:in `raw_load_rakefile’
(See full trace by running task with –trace)

Handling SSL certificates during SOAP4R calls

February 2nd, 2010

I ran into a problem recently with a SOAP call that was being made from one of our Ruby applications.  Apparently, something had changed with the SSL certificate at the service endpoint, as we were receiving the following error:

at depth 0 – 20: unable to get local issuer certificate

OpenSSL::SSL::SSLError: certificate verify failed

Now, nothing had changed in our code, which was very simple — all of the details about service location and methods available are in the service’s WSDL file.  The method that was blowing up simply created the connection to an HTTPS SOAP service and then called a method on the endpoint, like so:

def status
 # Read WSDL and create driver
 driver = SOAP::WSDLDriverFactory.new(WSDL_URI).create_rpc_driver

 # SOAP headers, basic auth credentials, etc.
 driver.headerhandler << HeaderHelper.new

 # Make SOAP call
 driver.GetStatus
end

After doing some research, it was pretty clear that we were getting the error because the certificate being presented by the server was issued by someone that wasn’t in our trusted store.  More specifically, it was signed using an intermediate certificate (or “chained” certificate) that was then linked to a trusted certificate.

There are two ways to fix this problem.  The first way is the fastest, which is a plus if you need to get this issue solved immediately, or you’re only writing a test wrapper anyway.  Add the following line:

def status
 # Read WSDL and create driver
 driver = SOAP::WSDLDriverFactory.new(WSDL_URI).create_rpc_driver

 driver.options['protocol.http.ssl_config.verify_mode'] = OpenSSL::SSL::VERIFY_NONE

 # SOAP headers, basic auth credentials, etc.
 driver.headerhandler << HeaderHelper.new

 # Make SOAP call
 driver.GetStatus
end

By setting VERIFY_NONE, you’re telling the SSL client to ignore the certificate sent by server.  The issue here is that, well, you’re ignoring the certificate sent by the server.  As any security advocate will tell you, encryption without authentication is no security at all.

The longer, but correct, way to fix this issue is to figure out what intermediate certificates you are missing and then include them in your web application.  This is often as simple as visiting the issuer’s HTTPS website and examining the certificate chain.  (In Firefox: double-click the lock icon, click View Certificate and then select the Details tab.)

In our case, I was able to do exactly that.  I exported all the certificates below the root cert into the lib folder and added the following lines:

def status
 # Read WSDL and create driver
 driver = SOAP::WSDLDriverFactory.new(WSDL_URI).create_rpc_driver

 driver.options['protocol.http.ssl_config.ca_file'] = 'lib/signing_cert.pem'
 driver.options['protocol.http.ssl_config.ca_file'] = 'lib/intermed_cert.pem'

 # SOAP headers, basic auth credentials, etc.
 driver.headerhandler << HeaderHelper.new

 # Make SOAP call
 driver.GetStatus
end

The call now worked perfectly.  Note that you can set the ca_file option as many times as you need to include multiple certificate files, although generally you should only need one, as typically an issuer will use only one intermediate certificate.

Note that this code doesn’t do any validation of the server’s certificate itself.  If you’d like to do this as well, please check out this SOAP4R wiki entry.

CSS Keyboards

October 9th, 2009

New CSS Experiment: CSS Keyboards.

Fixing List Whitespace in IE

October 8th, 2009

After having been annoyed yet again by this issue, I thought I would do a quick write-up on it on my site.  If you are dealing with an issue in IE where a ul/li list has extra vertical whitespace that you can’t get rid of, check it out.

Fixing List Whitespace in IE

Where is the matchmaking?

September 28th, 2009

After having played the Firefight mode in Halo 3: ODST, I’m very disappointed that they weren’t able to include matchmaking.  I’m disappointed because Firefight mode is tons of fun, and the lack of any matchmaking or lobby system means that I won’t get to play nearly as much of it as I would like.

It’s bizarre to me the way people are rationalizing this decision.  Go to any XBox, Halo, or Bungie forum and you’ll find people complaining.  You’ll also find a boatload of people ready with one of these standard retorts: “we knew about this a long time ago and don’t care”, or “you must suck if you don’t have any friends to play with”.  That last one tends to get followed up with either “you would only want to play Firefight with friends anyway”, or “you can look for friends on this forum and play Firefight with them”.  The contradiction inherent in these two statements should be obvious.

Matchmaking is a huge boon to any game, because it allows you to focus on a singular goal, which in this case is playing a round of 4-player Firefight.  It allows you to accomplish that goal by matching you up with the pool of players around the world that have the same goal, long after all of your own friends have moved on to other games, and all those people you added from the forums (who you never really played with anyway) have stopped playing.  It allows you to take yourself and your cousin from out-of-town at 2:30 in the morning and hop into a 4-player game of Firefight, even though none of your friends are awake.  Is there anyone out there that really thinks this isn’t desirable?  Or, more to the point, expected — especially in a console shooter released in 2009?

I know Bungie told us all about this long ago.  And I know (thanks everybody!) that you can play Firefight mode with friends.  But the lack of matchmaking stops this game from being a “pull off the shelf twice a month for the next two years” purchase, and turns it into a “hold onto until Left 4 Dead 2″ rental.

Bummer.