Subject: | Re: Catalyst::Controller::REST crashes on POST |
Date: | Sat, 14 May 2011 10:38:44 -0700 |
To: | bug-Catalyst-Action-REST [...] rt.cpan.org |
From: | Ian Holmes <ihh [...] berkeley.edu> |
Update: this now appears to be an XML::Simple bug, triggered on
deserialization.
% cat >! test
<test><a>blah</a></test>
% perl -e 'use XML::Simple;my $xs = XML::Simple->new();my $rdata =
$xs->XMLin("test")'
Segmentation fault
Note this works fine if the XML is quoted
% perl -e 'use XML::Simple;my $xs = XML::Simple->new();my$rdata =
$xs->XMLin( "<test><a>blah</a></test>" );print $rdata'
HASH(0x1009c4470)
Anyway - it appears not to be a Catalyst bug.
On 5/14/11 9:57 AM, Ian Holmes wrote:
Show quoted text
> Hi, this is a repost of a question posted at stackoverflow; as it
> appears to be a bug, rafl on #catalyst suggested I direct it here.
>
> Unfortunately, I can only reproduce this on one of my machines, so I
> think it may be of limited use. Here it is anyway.
>
> http://stackoverflow.com/questions/5987810/why-does-a-curl-post-request-crash-my-catalystcontrollerrest-controller
>
>
> So, I'm using Catalyst to build a RESTful web service, so I create a
> Catalyst controller in the usual way
>
> script/myapp_create.pl controller MyApp::Controller
>
> I then fire up the catalyst test server
>
> script/zoo_server.pl -rd
>
> So far so good - I can now go to http://localhost:3000/user and see the
> message "Matched MyApp::Controller::User in User."
>
> I then replace the BEGIN line in lib/MyApp/Controller/User.pm with the
> following line
>
> BEGIN { extends 'Catalyst::Controller::REST' }
>
> Before doing anything else, I want to check my ability to execute a POST
> request and watch the response. So in another terminal window, I type
>
> curl http://localhost:3000/user --verbose --data
> "<test><m>whatever</m></test>" -H "Content-Type: text/xml"
>
> At this point, since I have not implemented any POST methods, I am
> expecting to see a "405 Method Not Allowed" response. Instead, what I
> see from curl is this:
>
> * About to connect() to localhost port 3000 (#0)
> * Trying 127.0.0.1... connected
> * Connected to localhost (127.0.0.1) port 3000 (#0)
> > POST /user HTTP/1.1
> > User-Agent: curl/7.19.6 (i386-apple-darwin10.0.0) libcurl/7.19.6
> zlib/1.2.5
> > Host: localhost:3000
> > Accept: */*
> > Content-Type: text/xml
> > Content-Length: 28
> >
> * Empty reply from server
> * Connection #0 to host localhost left intact
> curl: (52) Empty reply from server
> * Closing connection #0
>
> This then appears to crash catalyst's test server. The server does not
> log anything, but future attempts to contact the server, e.g. doing
> another GET request to "localhost:3000/user", results in "couldn't
> connect to host" errors from curl.
>
> I note that this only happens if I use Catalyst::Controller::REST. If I
> just make a regular controller, POSTing to it does not crash anything.
> So I'm assuming it happens on the deserialization action, which will be
> delegated to XML::Simple (as per the default for
> Catalyst::Controller::REST). Any ideas?
>
> What I eventually want to do, by the way, is create a method like sub
> thing :Local :ActionClass('REST') ..., and a corresponding sub
> thing_POST. My understanding is that POST requests to /user/thing
> containing XML should then automatically get deserialized and put it
> into $c->request->data, before thing_POST is called. The above tests are
> a preliminary to this - designed to check what happens if no POST method
> is defined. (For what it's worth, I get exactly the same behavior if I
> create sub thing and sub thing_POST, and then use curl to issue a POST
> request to /user/thing.)