通过Qt发送PUT请求时出现错误请求类型PUT,与curl

时间:2018-04-11 14:31:06

标签: python xml qt curl basehttprequesthandler

我已经将[{1}}分包并实施了BaseHTTPRequestHandlerdo_GET()do_POST()

我认为一切正常,直到我将Qt应用程序进行测试。 GET请求有效,服务器发送一个XML文档,其中包含应用程序处理的一些数据。 POST请求也有效,用于通过REST生成测试用例。

至于PUT,事情看起来很奇怪。

这是服务器端的PUT处理程序:

do_PUT()

在我的Qt应用程序中,我有一个名为def do_PUT(self): """ Processes PUT request. It can be tested using wget, curl or any other tool with support for http PUT. Use this to send reports about the current status of device and all of its slave devices Example: curl -X PUT -d "status=downloading" http://127.0.0.1:8090/so/updateProgress """ print('Processing PUT request...') params_parsed = urlparse(self.path) params = parse_qs(params_parsed.query) if len(params) > 0 or '/so/updateProgress' not in params_parsed.path: print('Use "/so/updateProgress" to report on update progress') self.__set_headers(data_type='text/html') self.send_error(501) return self.__set_headers(data_type='text/xml') report_raw = self.rfile.read(int(self.headers.getheader('Content-length'))) print('Received report') print('Parsing report...') # Generate XML from the raw data and validate it report = SoRequestHandler.Report.from_xml(report_raw) print('Parsing of report complete') report.write_to_file(log_path='report_log', append=True) self.send_response(200) 的类,它从连接到的所有设备(通过MQTT)获取一些报告,将报告聚合到一个报告中并将其发送到服务器,将其记录在文件中:

ReportPublisher

我必须诚实。我在Qt中从未做过PUT请求,到目前为止我所做的都是GET请求,所以在上面的代码中可能会有一些非常基本但很容易发现的错误。

服务器收到的数据如下所示:

void ReportPublisher::publishHttpReport(HttpReport report)
{
    QString reportXml = report.xml().toString();
    if (reportXml.isEmpty())
    {
        LOG(ERROR) << "Something went wrong with the generation of HTTP report";
        return;
    }

    LOG(INFO) << "Generated report for SO server: " << reportXml;
    QByteArray reportRaw = reportXml.toUtf8();

    QUrl target(this->urlServer);
    target.setPath(this->urlPath);
    QNetworkRequest req(target);
    req.setHeader(QNetworkRequest::ContentTypeHeader, QString("application/xml"));
    this->reply = this->nam->put(req, reportRaw);

    // TODO Read back response (expected code 200)?
}

如果我像这样使用<updateProgress xmlns='service.so.de/so'> <deviceTypeId>...</deviceTypeId> <packageId>...</packageId> <version>...</version> <status>...</status> </updateProgress>

curl

其中 192.168.120.61:8090 是服务器位于/正在接收传入请求的IP地址和端口我没有问题。

然而,有数据来自我的Qt应用程序,我得到了

root@obunit:~$ curl -X PUT -i 'http://192.168.120.61:8090/so/updateProgress' -d "<updateProgress xmlns='service.so.de/so'><deviceTypeId>...</deviceTypeId><packageId>...</packageId><version>...</version><status>...</status></updateProgress>"

在我的日志中( 192.168.120.172 是我的软件运行系统的IP地址。

从我的稀缺知识代码400 表示无效语法,这可能是由于以下两个原因(至少我现在能想到的):

  • 格式错误的数据(无效的XML,JSON等)
  • 数据编码不正确,这基本上等同于格式不正确的数据,但来自不同的来源。

我尝试使用192.168.120.172 - - [11/Apr/2018 15:32:37] code 400, message Bad HTTP/0.9 request type ('PUT') 192.168.120.172 - - [11/Apr/2018 15:32:37] "PUT HTTP/1.1" 400 - 将我生成的XML文档转换为QByteArray。我也尝试过(在代码中可以看到)将文档转换为QDomDocument::toByteArray(int i)然后转换为UTF-8 QString,但我无法让我的服务器处理数据。

甚至更奇怪的是(正如你在我的QByteArray实现中看到的那样)我的PUT处理程序从打印消息开始,消息永远不会出现在日志中,因此问题出现在更深层次的地方代码do_PUT()

1 个答案:

答案 0 :(得分:0)

问题相当简单但非常烦人。

根据@MrEricSir的建议,我确实使用了Wireshark来发现得到一些奇怪的TCP回溯。重传通常是由于网络拥塞而发生的,在我看来这是不可能的,但它确实表明网络问题与我发送的XML内容无关。

所以我再次启动了远程调试会话,并且更接近我发出PUT请求的位置。它就在那里!基本URL(IP:PORT)和路径之间缺少/。而不是

PUT 192.168.120.61:8090/so/updateProgress

我在做

PUT 192.168.120.61:8090so/updateProgress

最终导致PUT请求完全没有成功(因此代码400)。

只是提示将来阅读此内容的任何人 - 只要您使用QUrl::setPath(QString)手动设置该路径

QUrl target(this->urlServer);
target.setPath(this->urlPath);

始终确保您作为路径传递的字符串以/开头,因为Qt不会添加一个!