OpenSource++
While hacking on some OX based controller code today I got an unsuspected error when parsing a POST request.
Can't use an undefined value as an ARRAY reference
at local/lib/perl5/Web/Request.pm line 426.
Huh.
As my usage of Web::Request seemed to be correct, I opened local/lib/perl5/Web/Request.pm
and looked at the code around line 426:
423: my $ret = { %{ $self->all_query_parameters } };
424: my $body_parameters = $self->all_body_parameters;
425: for my $key (keys %$body_parameters) {
426: push @{ $ret->{$key} ||= [] }, @{ $body_parameters->{key} };
427: }
The error was easy to spot: $body_parameters->{key}
should be $body_parameters->{$key}
(notice the $
in front of key
).
So I changed that (in my local copy). And my code worked! Yay!
But - being a good open source citizen - before committing my fix I also wanted to add a test case. This turned out to be a bit harder...
A POST Web::Request
The problem was that the bug was only triggered by x-www-form-urlencoded
POST requests. Obviously the test suite did not contain such a request (else the problem would have been spotted earlier). And I had no idea how to generate such a request using Web::Request
.
After a bit of acking the source (which by now I cloned on github and checked out to my machine) and looking at code and tests of related modules, I figured out that I had to pass the payload as an IO::Handle like object and set the correct HTTP headers.
Here's one way I came up with:
use IO::String;
my $payload="foo=bar&foo=baz&bar=bar";
my $io = IO::String->new($payload);
$req = Web::Request->new_from_env({
'REQUEST_METHOD' => 'POST',
'SCRIPT_NAME' => '/foo',
'CONTENT_LENGTH' => length($payload),
'CONTENT_TYPE' => "application/x-www-form-urlencoded",
'psgi.input' => $io,
});
I added this to an existing test file that seemed to test similar features. And send off the pull request.
As i figured that would take a while until my patch was reviewed & hopefully accepted, I added a fixed method to our subclass of Web::Request
. So I could continue hacking on my controller, which I happily did.
The Awesomeness of Open Source
After coming back from an evening run I checked my emails, only to find a short message from Jesse Luehrs (who is the maintainer of Web::Request
) telling me that he already merged my code. Yay!
Not only that, but he also pushed a new release to CPAN. Double-Yay!
And the moral of it is
It's easy to contribute! If you find a bug, at least report it, or better yet, fix it. Or at least try to come up with a failing test case.
It's very likely that your patch will be accepted, earning you not only working code (and thus less needs for hacky workarounds in your code base ( = more bugs)) but eternal fame and endless gratitude!