Проблема при передаче через файл cpp-httplib - PullRequest
0 голосов
/ 25 января 2019

В 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, хеш-код на стороне сервера отличается от хеш-кода на стороне клиента. Файл QTeoraryFile на стороне сервера поврежден и отличается от файла на стороне клиента, поэтому результат сканирования не является ожидаемым.

Попробовал с почтальоном, и результаты те же. Попробовал возиться, например, с помощью

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

и другие, похожие варианты, но результаты те же. Файл .mp4 и файл .png повреждены на стороне сервера, тогда как файлы .txt и .sh доставляются без проблем.

1 Ответ

0 голосов
/ 25 января 2019

При записи во временный файл вы используете:

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...