【问题标题】:Problem when transferring over a file using cpp-httplib使用 cpp-httplib 传输文件时出现问题
【发布时间】:2019-01-25 13:31:38
【问题描述】:

在 linux 上,我使用https://github.com/yhirose/cpp-httplib 设置一个简单的 REST 服务器作为学生项目。它必须做的一件事是接收文件并在本地扫描它。我为发布请求实现了一个功能,如下所示:

svr.Post("/scan", [&](const httplib::Request& req, httplib::Response& res){
    std::string body = req.body;

    qDebug() << "Creating local file...";
    QTemporaryFile inputFile;
    inputFile.open();
    qDebug() << "Writing to local file...";

    if(inputFile.write(body.c_str()) != -1){
        qDebug() << "Writing finished. Closing local file...";
        qDebug() << "Scanning local file...";
        QCryptographicHash hash(QCryptographicHash::Algorithm::Sha1);
        hash.addData(&inputFile);
        qDebug() << "hash: " << QString::fromStdString( hash.result().toHex().toStdString() );
        res.set_content(myEngine.scan(inputFile).toJson().toStdString(), "text/plain");
    }else{
        res.set_content("Failed to write file", "text/plain");
        qDebug() << "Failed writing. Closing local file...";
    }
    inputFile.close();
});

我用 QT 创建了一个临时文件,打开它,使用它的 write() 函数将请求的正文写入文件。在我写入它之后,我写出它的 SHA1 用于调试目的,然后使用“myEngine.scan()”函数对其进行扫描。 'myengine.scan()' 函数返回一个包含扫描结果的 JsonDocument,我将其转换为字符串作为回复发送。

现在,“myEngine.scan()”按预期工作,它基本上只是检查文件的哈希是否包含在数据库中。

然后我使用 curl 发送请求:

curl -X POST --data-binary "@music_video.mp4" localhost:1234/scan  

当我发送一个简单的文件,例如一个 .sh 可运行脚本或一个 .txt 文本文件时,文件会继续,它被扫描,返回预期值,一切都很好。服务器端的哈希码与客户端的哈希码相同。

但是,当我通过 .mp4 媒体文件或 .png 屏幕截图文件发送时,服务器端的哈希码与客户端的哈希码不同。服务器端的 QTemporaryFile 已损坏,与客户端文件不同,因此扫描结果不是预期结果。

用postman试了一下,结果是一样的。 尝试过胡闹,比如使用

curl -X POST --header "Content-Type:text/plain;charset=UTF-8" --data-raw "@screenfetch.png" http://localhost:1234/scan

和其他类似的变体,但结果是相同的。 .mp4 文件和 .png 文件在服务器端损坏,而 .txt 和 .sh 文件到达时没有问题。

【问题讨论】:

    标签: c++ qt curl


    【解决方案1】:

    写入临时文件时,您使用:

    inputFile.write(body.c_str()),它使用QIODevice::write(const char*) (doc)

    将数据从 8 位字符的零终止字符串写入 设备。返回实际写入的字节数,或 -1 如果发生错误

    您可以假设您发布的文件肯定包含至少一个等于 0 的字节。遇到后什么都不写,您只在临时文件中写入原始文件的截断版本。

    你应该像这样使用QIODevice::write(const char *data, qint64 maxSize) (doc):

    if (inputFile.write(body.c_str(), body.size()) == body.size()) {
        // The temporary file has been written
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 2011-09-28
      • 2020-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-02
      • 1970-01-01
      相关资源
      最近更新 更多