{"id":2181,"date":"2022-08-30T15:22:43","date_gmt":"2022-08-30T15:22:43","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/01\/04\/why-does-a-curl-post-request-crash-my-catalystcontrollerrest-controller-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:22:43","modified_gmt":"2022-08-30T15:22:43","slug":"why-does-a-curl-post-request-crash-my-catalystcontrollerrest-controller-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/why-does-a-curl-post-request-crash-my-catalystcontrollerrest-controller-collection-of-common-programming-errors\/","title":{"rendered":"Why does a curl POST request crash my Catalyst::Controller::REST controller?-Collection of common programming errors"},"content":{"rendered":"<p>I&#8217;m using Catalyst to build a RESTful web service, so I create a Catalyst controller in the usual way<\/p>\n<pre><code>script\/myapp_create.pl controller MyApp::Controller\n<\/code><\/pre>\n<p>I then fire up the catalyst test server<\/p>\n<pre><code>script\/zoo_server.pl -rd\n<\/code><\/pre>\n<p>So far so good &#8211; I can now go to <code>http:\/\/localhost:3000\/user<\/code> and see the message &#8220;Matched MyApp::Controller::User in User.&#8221;<\/p>\n<p>I then replace the first BEGIN line in lib\/MyApp\/Controller\/User.pm with the following line<\/p>\n<pre><code>BEGIN { extends 'Catalyst::Controller::REST' }\n<\/code><\/pre>\n<p>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<\/p>\n<pre><code>curl http:\/\/localhost:3000\/user --verbose --data \"whatever\" -H \"Content-Type: text\/xml\"\n<\/code><\/pre>\n<p>At this point, since I have not implemented any POST methods, I am expecting to see a &#8220;405 Method Not Allowed&#8221; response. Instead, what I see from curl is this:<\/p>\n<pre><code>* About to connect() to localhost port 3000 (#0)\n*   Trying 127.0.0.1... connected\n* Connected to localhost (127.0.0.1) port 3000 (#0)\n&gt; POST \/user HTTP\/1.1\n&gt; User-Agent: curl\/7.19.6 (i386-apple-darwin10.0.0) libcurl\/7.19.6 zlib\/1.2.5\n&gt; Host: localhost:3000\n&gt; Accept: *\/*\n&gt; Content-Type: text\/xml\n&gt; Content-Length: 28\n&gt; \n* Empty reply from server\n* Connection #0 to host localhost left intact\ncurl: (52) Empty reply from server\n* Closing connection #0\n<\/code><\/pre>\n<p>This then appears to crash catalyst&#8217;s test server. The server does not log anything, but future attempts to contact the server, e.g. doing another GET request to &#8220;localhost:3000\/user&#8221;, results in &#8220;couldn&#8217;t connect to host&#8221; errors from curl.<\/p>\n<p>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&#8217;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?<\/p>\n<p>What I eventually want to do, by the way, is create a method like <code>sub thing :Local :ActionClass('REST') ...<\/code>, and a corresponding <code>sub thing_POST<\/code>. My understanding is that POST requests to \/user\/thing containing XML should then automatically get deserialized and put it into <code>$c-&gt;request-&gt;data<\/code>, before <code>thing_POST<\/code> is called. The above tests are a preliminary to this &#8211; designed to check what happens if <em>no<\/em> POST method is defined. (For what it&#8217;s worth, I get exactly the same behavior if I create <code>sub thing<\/code> and <code>sub thing_POST<\/code>, and then use curl to issue a POST request to \/user\/thing.)<\/p>\n<ol>\n<li>\n<p>I eventually traced this to XML::SAX. Reproducible bug condition:<\/p>\n<pre><code>% cat &gt;! test\nblah\n% perl -e 'use XML::SAX;my $sp = XML::SAX::ParserFactory-&gt;parser;my $tree = $sp-&gt;parse_uri(\"test\")'\nSegmentation fault\n<\/code><\/pre>\n<p>Note that it works fine if the XML is quoted, rather than in a file:<\/p>\n<pre><code>% perl -e 'use XML::SAX;my $sp = XML::SAX::ParserFactory-&gt;parser;my $tree = $sp-&gt;parse_string(\"<b>test<\/b>\");print $tree'\nHASH(0x1009c4470)\n<\/code><\/pre>\n<p>Something wrong with my XML::SAX installation, I guess.<\/p>\n<\/li>\n<li>\n<p>You&#8217;ve defined your action <em>thing<\/em> with :Local attribute attached, which means the path which is dispatched is \/user\/thing (instead of that, you are posting your data to \/user). May be you would like to check the Catalyst Manual &#8211; Action Types introduction<\/p>\n<p>Alternatively, if you still experience some problems you could try asking at the official #catalyst irc channel.<\/p>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2014-01-04 02:51:56. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>I&#8217;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 &#8211; I can now go to http:\/\/localhost:3000\/user and see the message &#8220;Matched MyApp::Controller::User in User.&#8221; I then replace the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2181","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2181","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=2181"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/2181\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=2181"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=2181"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=2181"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}