我已经子类化BaseHTTPRequestHandler
并实现了do_GET()
,do_POST()
和do_PUT()
.
我认为一切正常,直到我对我的 Qt 应用程序进行测试。GET 请求有效,服务器发送一个 XML 文档,其中包含应用程序处理的一些数据。POST 请求也有效,用于通过 REST 生成测试用例。
至于 PUT,事情看起来很奇怪。
这是服务器端的 PUT 处理程序:
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)
在我的 Qt 应用程序中,我有一个名为 的类ReportPublisher
,它从它连接到的所有设备(通过 MQTT)获取一些报告,将报告聚合成一个单一的报告并将其发送到服务器,服务器将其记录在一个文件中:
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)?
}
我必须诚实。我从来没有在 Qt 中做过 PUT 请求,到目前为止我所做的只是 GET 请求,所以上面的代码中可能存在一些非常基本但很容易发现的错误。
服务器接收到的数据如下所示:
<updateProgress xmlns='service.so.de/so'>
<deviceTypeId>...</deviceTypeId>
<packageId>...</packageId>
<version>...</version>
<status>...</status>
</updateProgress>
如果我curl
这样使用
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.61:8090是 IP 地址和服务器所在/侦听传入请求的端口我没有问题。
但是,对于来自我的 Qt 应用程序的数据,我得到了
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 -
在我的日志中(192.168.120.172是运行我的软件的系统的 IP 地址。
根据我稀缺的知识,代码 400表示语法无效,这可能是由于以下两个原因(至少我现在能想到的):
- 格式错误的数据(无效的 XML、JSON 等)
- 数据编码不正确,这基本上等同于格式错误的数据,但来自不同的来源。
我尝试将生成的 XML 文档转换为QByteArray
使用QDomDocument::toByteArray(int i)
. 我也尝试过(如您在代码中看到的那样)将文档转换为QString
UTF-8,然后再转换为 UTF-8 QByteArray
,但我无法让我的服务器处理数据。
更奇怪的是(如您在我do_PUT()
的BaseHTTPRequestHandler
.