为什么curl POST 请求会使我的Catalyst::Controller::REST 控制器崩溃?

发布于 2024-11-07 03:22:02 字数 1962 浏览 5 评论 0原文

我正在使用 Catalyst 构建 RESTful Web 服务,因此我以通常的方式创建一个 Catalyst 控制器

script/myapp_create.pl controller MyApp::Controller

,然后启动 Catalyst 测试服务器

script/zoo_server.pl -rd

到目前为止一切顺利 - 我现在可以访问 http://localhost:3000 /user 并看到消息“Matched MyApp::Controller::User in User”。

然后,我将 lib/MyApp/Controller/User.pm 中的第一行 BEGIN 替换为以下行

BEGIN { extends 'Catalyst::Controller::REST' }

在执行其他操作之前,我想检查我执行 POST 请求并观察响应的能力。因此,在另一个终端窗口中,我键入

curl http://localhost:3000/user --verbose --data "<test><m>whatever</m></test>" -H "Content-Type: text/xml"

At 此时,由于我尚未实现任何 POST 方法,因此我希望看到“405 Method Not allowed”响应。相反,我从curl 中看到的是这样的:

* 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

这似乎使catalyst 的测试服务器崩溃。服务器不记录任何内容,但将来尝试联系服务器,例如对“localhost:3000/user”执行另一个 GET 请求,会导致curl 出现“无法连接到主机”错误。

我注意到,只有当我使用 Catalyst::Controller::REST 时才会发生这种情况。如果我只是制作一个常规控制器,发布到它不会导致任何崩溃。所以我假设它发生在反序列化操作上,该操作将委托给 XML::Simple (根据 Catalyst::Controller::REST 的默认值)。有什么想法吗?

顺便说一句,我最终想做的是创建一个类似 sub thing :Local :ActionClass('REST') ... 的方法,以及相应的 sub thing_POST 。我的理解是,在 thing_POST 之前,对包含 XML 的 /user/thing 的 POST 请求应该自动反序列化并将其放入 $c->request->data 中叫。上述测试是对此的初步测试 - 旨在检查如果没有定义 POST 方法会发生什么。 (无论如何,如果我创建 sub thingsub thing_POST,然后使用curl 向 /user/thing 发出 POST 请求,我会得到完全相同的行为。 )

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 first 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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你是我的挚爱i 2024-11-14 03:22:02

我最终将其追溯到 XML::SAX。可重现的错误情况:

% cat >! test
<test><a>blah</a></test>
% perl -e 'use XML::SAX;my $sp = XML::SAX::ParserFactory->parser;my $tree = $sp->parse_uri("test")'
Segmentation fault

请注意,如果引用 XML,而不是在文件中,则它可以正常工作:

% perl -e 'use XML::SAX;my $sp = XML::SAX::ParserFactory->parser;my $tree = $sp->parse_string("<a><b>test</b></a>");print $tree'
HASH(0x1009c4470)

我猜我的 XML::SAX 安装出了问题。

I eventually traced this to XML::SAX. Reproducible bug condition:

% cat >! test
<test><a>blah</a></test>
% perl -e 'use XML::SAX;my $sp = XML::SAX::ParserFactory->parser;my $tree = $sp->parse_uri("test")'
Segmentation fault

Note that it works fine if the XML is quoted, rather than in a file:

% perl -e 'use XML::SAX;my $sp = XML::SAX::ParserFactory->parser;my $tree = $sp->parse_string("<a><b>test</b></a>");print $tree'
HASH(0x1009c4470)

Something wrong with my XML::SAX installation, I guess.

独闯女儿国 2024-11-14 03:22:02

您已经定义了附加了 :Local 属性的操作 thing,这意味着分派的路径是 /user/thing (而不是那样,您将数据发布到 /user)。可能您想检查 Catalyst 手册 - 操作类型介绍

或者,如果您仍然遇到一些问题,您可以尝试在官方 #catalyst irc 频道询问。

You've defined your action thing 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 - Action Types introduction

Alternatively, if you still experience some problems you could try asking at the official #catalyst irc channel.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文