How to get HTTPS and LWP working on Mac OSX

This is going to be a seriously nerdy entry: more nerdy than other things I’ve written lately. However, it appears to be a common problem that other people are struggling with at the moment. The other day, I wrote an article about how you can kick the Excel habit (the consultant’s penchant for using Excel to accomplish nearly everything) by taking advantage of some of the exciting new features offered by the Google Apps Spreadsheet. I also mentioned that the tips offered in that article barely scratched the surface of Google Apps and that really exciting things were possible by tapping into the Google Docs API.

I hoped to explore the API with Perl and come up with some more exciting things that I could share with others. When I was about to get started, I ran into a problem. At first, it didn’t make any sense (actually, it still doesn’t make much sense, but at least I got to the bottom of it). Basically, the newest version of the Apple operating system didn’t ship with one of the cryptographic libraries that accompanied earlier releases. Anyway, because of a missing cryptographic library, HTTPS calls made using the Perl’s LWP::UserAgent module failed.

Since the beginning step of using the Google Docs API requires you to collect an authentication token from Google, you have to do something like this:

#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;

# Create your user agent and post the data to Google
my $ua = LWP::UserAgent->new;
my $response = $ua->post(
	'https://www.google.com/accounts/ClientLogin',
	{
		accountType	=> 'GOOGLE',
		Email		=> 'your@emailAddre.ss',
		Passwd		=> 'yourPassword',
		service		=> 'apps',
		source		=> 'My Sandbox',
	}
);

die "\nError: ", $response->status_line unless $response->is_success;

# Extract the authentication token from the response
my $auth_token;
foreach my $line (split/\n/, $response->content) {
	if ($line =~ m/^Auth=(.+)$/) {
	$auth_token = $1;
	last;
	}
}
print "authentication token is $auth_token\n";

If you run that on Leopard, you wind up with this:

Error: 500 Can't connect to www.google.com:443 (Invalid argument) at google.pl line 21.

The problem is that Leopard (OS 10.5) didn’t ship with Crypt::SSLeay. Of course, like everything related to Perl, there are many ways to get the module:

  • You can use Fink, which you’ll need to compile from source
  • You can use MacPorts, which is available as disk image
  • You can download and build the module from CPAN

Although using Fink or MacPorts might be useful if you’re planning to download a lot of different modules, I don’t particularly want an entirely separate Perl environment on my computer, so I opted for the final option: install and build from CPAN. Regardless of which option you select, you’ll be compiling software from source, so if you don’t have it install already, install XCode from your Leopard DVD.

Once you’ve got XCode installed, the rest is fast and easy:

  1. Download Crypt::SSLeay from http://search.cpan.org/~dland/Crypt-SSLeay-0.57/SSLeay.pm
  2. Place the file into a temp/downloads directory
  3. Open a terminal window and switch into the directory where you put the file
  4. Untar/zip your file: tar -fxz Crypt-SSLeay-0.57.tar.gz (of course, your filename will differ depending on the version of Crypt::SSLeay you download)
  5. Switch into the Crypt-SSLeay-0.57 directory created during the untar
  6. Run the following commands, accepting any defaults along the way:
    • perl Makefile.pl
    • make
    • make test
    • sudo make install

The final make install command must be run as su because the installer needs to create a several directories in /System and /Library, and typical user accounts lack the necessary permissions to do so. When your install is finished, run your script. It should succeed and give you some output like this:

authentication token is DQAAAHkAAACVrZyIawDQ3UwrpPgJcKs9bs89d7s \
987d8s79ds87dwevhkjsdhsdkshdCeuNBcpNc6SndjaPI7DhiJhN9kaYfQXHfNsc1qSy7VuPdq9 \
l-etU-IoV0kkX1h1GYYyyXwtp0CpQ2eEWxOQ9nfc2gqD8cdH0Nwz6VJdQ

Finally, if you don’t feel like going through the trouble of installing XCode then downloading and building Crypt::SSLeay, you could always just use curl, which comes with SSL on Leopard:

curl -d "accountType=GOOGLE&Email=your@emailAddre.ss&Passwd=yourPassword& \
service=apps&source=MySandbox" https://www.google.com/accounts/ClientLogin

If you embed that as a system call in your Perl program, it will be nearly the same as having LWP::UserAgent fetch you the authentication token.

In any event, whether you use Perl or CURL, that’s likely the first step in doing something else with Google’s services, maybe something like Automating Billing with Perl and the Google Docs API.