Returning an specific HTTP status/return code and content with mod_perl 2
Making a simple PerlResponseHandler that does something like this:
sub handler {
my($r) = shift;
$r->content_type("text/plain");
$r->print("You suck.\n");
return Apache2::Const::HTTP_BAD_REQUEST;
}
…doesn't make what you'd be expecting. This is because mod_perl assumes, since you are specifying content type and something to print, that this is a legit and valid (200-ish) request. This is what you get:
POST http://myserver/resource --> 200 OK
Connection: close
Date: Mon, 05 Jan 2009 23:02:57 GMT
Content-Type: text/plain; charset=UTF-8
Client-Date: Mon, 05 Jan 2009 23:03:00 GMT
Client-Response-Num: 1
Client-Transfer-Encoding: chunked
[ some headers snipped ]
You suck.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>200 OK<</title>
</head><body>
<h1>OK</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
</body></html>
So, yes, I was expecting to return a 400 Bad Request return with just "You suck" on the response body. mod_perl disagrees, which, kind of sucks if you are trying to make a RESTful service with mod_perl HTTP handlers and filters.
To avoid this behaviour, this is one way to go:
sub handler {
my($r) = shift;
$r->status(400); # or the one you are interested in
$r->content_type("text/plain");
$r->print("You suck.");
return Apache2::Const::OK;
}
You can also take a look at status_line that overrides status. You can also avoid the content_type method call if you are sloth enough. Now, this is what you get:
GET https://myserver/resource --> 400 Bad Request
Connection: close
Date: Mon, 05 Jan 2009 23:27:08 GMT
Content-Type: text/plain; charset=UTF-8
Client-Date: Mon, 05 Jan 2009 23:27:10 GMT
Client-Peer: 209.234.249.38:443
Client-Response-Num: 1
[ some headers snipped
]
You suck.
And so, beer awaits.



I think this is apache design, not mod_perl.
Thomas
6 Jan 09 at 12:35 pm
Yes, it makes sense.
admin
6 Jan 09 at 12:37 pm