CppRestSDK如何发布多部分数据

时间:2019-06-07 15:33:37

标签: c++ http c++17 multipart cpprest-sdk

我正在尝试将Multipart数据发布到服务器,我正在从CPR切换到CPPRestSDK,但似乎找不到任何文档

来自CPR,https://github.com/whoshuu/cpr

意思是我已经尝试过该代码,但是似乎在cpprestsdk上找不到任何有关多部分数据的文档。

    cpr::Multipart multipart_data{};

    for (size_t i = 0; i < files.size(); i++) {
        if (!is_image_or_gif(files[i].filepath)) {
            std::string entire_file = read_entire_file(files[i].filepath);
            std::string custom_filename{ files[i].spoiler ? "SPOILER_" : "" };
            multipart_data.parts.emplace_back(
                "file" + std::to_string(i),
                cpr::Buffer{ entire_file.begin(),
                             entire_file.end(),
                             custom_filename + files[i].filename },
                "application/octet-stream");
        } else {
            multipart_data.parts.emplace_back("file" + std::to_string(i),
                                              cpr::File(files[i].filepath),
                                              "application/octet-stream");
        }
    }

    auto payload_json = nlohmann::json{
        { "content", content },
        { "tts", tts }
    }.dump();
    multipart_data.parts.emplace_back("payload_json", payload_json);

    auto response = cpr::Post(
        cpr::Url{ endpoint("/channels/%/messages", id) },
        cpr::Header{ { "Authorization", format("Bot %", discord::detail::bot_instance->token) },
                     { "Content-Type", "multipart/form-data" },
                     { "User-Agent", "DiscordBot (http://www.github.com/yuhanun/dpp, 0.0.0)" },
                     { "Connection", "keep-alive" } },
        multipart_data);

file结构很明显的地方。

标题,很好,我想通了,我基本上只需要一些帮助即可发送多部分数据:)

我的预期结果是让服务器使用已发送消息的“成功” json(在本例中为Message对象)进行响应,但是,现在,我什至不知道从哪里开始。 / p>

2 个答案:

答案 0 :(得分:1)

这是一种方法:

// Form a multipart/form-data scheme 
// 1.Create a boundary ( a random value that you know is unique)
// KabezOf... is something goofie I just wrote, make sure you use 
// something that you know does not exist in  the actual messages.
std::string boundary = "----KabezOfFireDegelDegelGoGoniDaijobo";
// 2.Embed different fields 
std::stringstream bodyContent;
std::map<std::string, std::string> keyValues{ {"key1", "value1"},
                                              {"key2", "value2"},
                                              {"key3", "value3" } };

for (auto& [key, value] : keyValues)
{
    bodyContent << "--" << boundary << "\r\n"
                << "Content-Disposition: form-data; name=\"" << key << "\"\r\n\r\n"
                << value << "\r\n";
}
// 3. if you have any files to send as well, Now is the time
// here we are sending an image file, as you can see, like
// previous block, you can put this into a loop and instead
// of 1 file, have several files.
// reading the image 
std::ifstream inputFile;
inputFile.open(imagePath, std::ios::binary | std::ios::in);
std::ostringstream imgContent;
std::copy(std::istreambuf_iterator<char>(inputFile),
          std::istreambuf_iterator<char>(),
          std::ostreambuf_iterator<char>(imgContent));

auto imageFilename =  std::filesystem::path(imagePath).filename().string();
bodyContent << "--" << boundary<<"\r\n"
            << "Content-Disposition: form-data; name=\"image\"; filename=\"" << imageFilename << "\"\r\n"
            << "Content-Type: " << contentType << "\r\n\r\n"
            << imgContent.str() << "\r\n"
            << "--" << boundary << "--";

web::http::client::http_client client(your_uri);
web::http::http_request requestMessage{ methods::POST };
requestMessage.set_body(bodyContent.str(), "multipart/form-data; boundary=" + boundary);

auto result = client.request(requestMessage);


答案 1 :(得分:0)

由于某种原因,这引起了一些反对,所以我想回答这个问题。

我很久以前解决了这个问题,您可以查看我的存储库以了解其准确性。

https://github.com/Yuhanun/DPP/blob/master/src/channel.cpp#L108

https://github.com/Yuhanun/DPP/blob/master/src/utils.cpp#L180

享受解决方案。