Take the 2-minute tour ×

I want to pass a serialized Perl data structure as a GET variable to a CGI application. I tried Data::Serializer as my first option. Unfortunately the serialized string is too long for my comfort, in addition to containing options joined by '^' (a caret).

Is there a way I can create short encoded strings from perl data structures so that I can safely pass them as GET variables to a perl CGI application?

I would also appreciate being told that this (serialized, encoded strings) is a bad way to pass complex data structures to web applications and suggestions on how I could accomplish this

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

If you need to send URL's to your users that contains a few key datapoints and you want to ensure it can't be forged you can do this with a Digest (such as from Digest::SHA) and a shared secret. This lets you put the data out there in your messages without needing to keep a local database to track it all. My example doesn't include a time element, but that would be easy enough to add in if you want.

use Digest::SHA qw(sha1_base64);
my $base_url = 'http://example.com/thing.cgi';

my $email = 'guy@somewhere.com';
my $msg_id = '123411';

my $secret = 'mysecret';
my $data = join(":", $email, $msg_id, $secret);
my $digest = sha1_base64($data);

my $url = $base_url . '?email=' . $email . '&msg_id=' . $msg_id' . '&sign=' . $digest;

Then send it along.

In your "thing.cgi" script you just need to extract the parameters and see if the digest submitted in the script matches the one you locally regenerate (using $email and $msg_id, and of course your $secret). If they don't match, don't authorize them, if they do then you have a legitimately authorized request.

I wrote the "raw" methods into Data::Serializer to make translating between serializers much easier and that in fact does help with going between languages (to a point). But that of course is a separate discussion as you really shouldn't ever use a serializer for exchanging data on a web form.

share|improve this answer
Thanks - this is exactly what I was looking for. –  Ya. Perelman Nov 29 '09 at 4:44
add comment

One of the drawbacks of the approach — using a perl-specific serializer, that is — is that if you ever want to communicate between the client and server using something other than perl it will probably be more work than something like JSON or even XML would be. The size limitations of GET requests you've already run in to, but that's problematic for any encoding scheme.

It's more likely to be a problem for the next guy down the road who maintains this code than it is for you. I have a situation now where a developer who worked on a large system before I did decided to store several important bits of data as perl Storable objects. Not a horrible decision in and of itself, but it's making it more difficult than it should be to access the data with tools that aren't written in perl.

share|improve this answer
Agreed that using Storable/Serializer are not portable across languages. Would be interested in hearing how you plan to solve your problem. –  Ya. Perelman Nov 28 '09 at 16:45
add comment

Passing serialized encoded strings is a bad way to pass complex data structures to web applications.

If you are trying to pass state from page to page, you can use server side sessions which would only require you to pass around a session key.

If you need to email a link to someone, you can still create a server-side session with a reasonable expiry time (you'll also need to decide if additional authentication is necessary) and then send the session id in the link. You can/should expire the session immediately once the requested action is taken.

share|improve this answer
"this" would be "passing a data structure to a CGI application". You are right about using sessions being the right way of passing data from page to page. However, the situation I have is that I want to create a link (URL) and mail it to an email address. When the recipient of the mail clicks on the link, I want to have access to all data corresponding to that user to handle his request (unsubscribe from a mailing list for example) –  Ya. Perelman Nov 28 '09 at 15:54
Nothing! Other than the fact that I never thought you could do this :). Will definitely evaluate this - Thanks –  Ya. Perelman Nov 28 '09 at 16:31
@Gurunandan Bhat: FYI: I deleted my comment and put my suggestion in the answer itself. –  Sinan Ünür Nov 28 '09 at 16:35
@Gurunandan Bhat: Why would you have to create thousands of server side sessions? –  Sinan Ünür Nov 28 '09 at 16:38
Sorry - Might not work for what I want to do. On first thoughts, would have to create thousands of server-side sessions one for each recipient. Seems excessive on first thoughts. Or am I reading you incorrectly? –  Ya. Perelman Nov 28 '09 at 16:39
show 4 more comments

Your Answer


