[Catalyst] Converting a GET request to a POST request
Ronald J Kimball
rkimball at pangeamedia.com
Mon Nov 22 17:44:37 GMT 2010
I want to convert a GET request to a POST request, inside my Catalyst
app, before dispatching happens. For example, I want to take a
request like:
GET /foo?method=POST&body={"foo":1}&content-type=text/javascript
and convert it into a request like this:
POST /foo
Content-Type: text/javascript
{"foo":1}
Background: I'm implementing a REST API using
Catalyst::Controller::REST. The API will be accessed via Ajax running
on third party websites, using JSONP to get around the same-origin
policy. Unfortunately, JSONP can only make GET requests. So, I want
to take that GET request and turn it into a POST before
Catalyst::Action::Deserialize does its magic.
This is as far as I've gotten, in my app's base class:
around 'prepare' => sub {
my $orig = shift;
my $class = shift;
my $c = $class->$orig(@_);
if ($c->req->method eq 'GET' && $c->req->param('method') &&
$c->req->param('content-type')) {
my $type = $c->req->param('content-type');
my $body = $c->req->param('body');
$c->req->method(scalar $c->req->param('method'));
$c->req->content_type($type);
$c->req->_body(HTTP::Body->new($type, length $body));
$c->req->_body->add($body);
}
return $c;
};
This works for JSON requests (e.g. application/json), but not for
JSONP requests (e.g. text/javascript), because there is no
Catalyst::Action::Deserialize::JSONP. I guess I could create one that
extends Catalyst::Action::Deserialize::JSON...
Even then, this solution has some drawbacks: it covers every request,
not just those for the relevant controller/actions; it probably leaves
the request object's attributes in an inconsistent state; and it makes
me feel really dirty.
Is there a better way to modify the request, or a better way to solve
my general problem in the first place?
thanks,
Ronald
More information about the Catalyst
mailing list