Search code examples
perlhttp-postcatalysthttp-request

How come Catalyst::Controller::WrapCGI doesn't get any post data?


Whenever I POST something to a page with Catalyst::Controller::WrapCGI I notice that my old CGI script doesn't get any POST data.. Data inside the body of the HTTP request. What am I doing wrong and how do I fix this?


Solution

  • In my case, this was because I was using Catalyst::Controller::WrapCGI v0.35 and Catalyst::Controller::REST. This created a problem.. My configuration looked like this,

    package MyApp::Controller::REST;
    __PACKAGE__->config(namespace => '');
    BEGIN { extends 'Catalyst::Controller::REST' }
    

    and

    package MyApp::Controller::Root;
    __PACKAGE__->config(namespace => '');
    BEGIN { extends 'Catalyst::Controller::WrapCGI' }
    

    However, Catalyst::Controller::REST installs a begin action on line 298

    sub begin : ActionClass('Deserialize') { }
    

    And, that -- in my case -- was delegating to Catalyst::Action::Deserialize::JSON which is smart enough to seek($body,0,0) but too dumb and inconsiderate to do that for the next guy down the chain.... Code below from here

    if(openhandle $body) {
        seek($body, 0, 0); # in case something has already read from it
        while ( defined( my $line = <$body> ) ) {
            $rbody .= $line;
        }
    }
    

    And, to make matters even worse, the next guy down the chain in this example is Catalyst::Controller::WrapCGI which not just fails to clean up for the next guy, but fails to set it up for itself (code from here),

    if ($body) { # Slurp from body filehandle
      local $/; $body_content = <$body>;
    }
    

    That should look like (at the very least)

    if ($body) { # Slurp from body filehandle
      local $/;
      seek($body,0,0);
      $body_content = <$body>;
    }
    

    That's why we can't have nice things... I opened a bug in C:C:WrapCGI to get this resolved.