POST over mod_perl handlers with unusual content types
Recently I had to deal with POST requests on mod_perl 2 on a custom XML-RPC webservice server we have been developing and maintaining over the last year (we are actually moving it to REST some time in the middle future). It was time to move some of our base modules from a couple of CGIs to the power and muscle of mod_perl.
So, while dealing with POST requests (like XML-RPC is actually specified) I faced the issue that I wasn’t being able to get the POST data on the PerlResponseHandler phase. I was probably not reading it correctly, I got deeply into it and even read some libapreq source code. All I was getting was some nifty message like “not supported”. After reading some documentation (and, to my own shame, the Apache2::Request front page pod) I found out that the usual:
use Apache2::Request;
$req = Apache2::Request->new($r);
@foo = $req->param("foo");
$bar = $req->args("bar");
will not work on your POST if the content type is different than application/x-www-form-urlencoded or multipart/form-data. For example, say, XML-RPC! So, in case you actually need to read POST data on your mod_perl 2 handler where it’s not a form or a file upload, you can read the data manually (I didn’t find a simpler way to read the data, actually):
sub handler {
my $r = shift;
return Apache2::Const::HTTP_BAD_REQUEST unless
$r->method eq "POST" and
$r->headers_in->{'Content-Type'} eq 'text/xml' and
$r->headers_in->{'Content-Length'};
my $length = $r->headers_in->{'Content-Length'};
my $xml;
while ($length) {
$r->read($xml, ($length [less than symbol] 2048) ? $length : 2048);
$length -= length($xml);
}
...
And you are ready for booze.

