【问题标题】:I tried to download a file with Boost Asio, but it doesn't work, it just looks like downloaded small portion of file我试图用 Boost Asio 下载一个文件,但它不起作用,它看起来像下载了一小部分文件
【发布时间】:2021-03-23 03:03:37
【问题描述】:

我尝试了使用 boost asio 从 Rest API 下载文件的代码攻击,结果是它看起来像响应正文中的一小部分文件,我不知道我做错了什么,Boost 是Win7机器上VS2013内的最新版本

    boost::asio::io_service io_service;

    // Get a list of endpoints corresponding to the server name.
    boost::asio::ip::tcp::resolver resolver(io_service);
    boost::asio::ip::tcp::resolver::query query(host, port);
    boost::asio::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);

    // Try each endpoint until we successfully establish a connection.
    boost::asio::ip::tcp::socket socket(io_service);
    boost::asio::connect(socket, endpoint_iterator);

    // Form the request. We specify the "Connection: close" header so that the
    // server will close the socket after transmitting the response. This will
    // allow us to treat all data up until the EOF as the content.
    boost::asio::streambuf request;
    std::ostream request_stream(&request);
    request_stream << "POST " << target << " HTTP/1.1\r\n";
    request_stream << "Host: " << host << "\r\n";
    request_stream << "Accept: " << acceptwstr << "\r\n";
    request_stream << "Content-Type: " << ContentTypewstr << "\r\n";
    request_stream << "Content-Length: " << jsondata.length() << "\r\n";
    request_stream << "x-tif-paasid: " << accessKey << "\r\n";
    request_stream << "x-tif-timestamp: " << msecondstr << "\r\n";
    request_stream << "x-tif-nonce: " << uuidstr << "\r\n";
    request_stream << "x-tif-signature: " << signature << "\r\n";
    request_stream << "Connection: Close\r\n\r\n";
    request_stream << jsondata << "\r\n";

    // Send the request.
    boost::asio::write(socket, request);

    // Read the response status line. The response streambuf will automatically
    // grow to accommodate the entire line. The growth may be limited by passing
    // a maximum size to the streambuf constructor.
    boost::asio::streambuf response;
    boost::asio::read_until(socket, response, "\r\n");

    // Check that response is OK.
    std::istream response_stream(&response);
    std::string http_version;
    response_stream >> http_version;
    unsigned int status_code;
    response_stream >> status_code;
    std::string status_message;
    std::getline(response_stream, status_message);
    if (!response_stream || http_version.substr(0, 5) != "HTTP/")
    {
        //std::cout << "Invalid response\n";
        return 9002;
         
    }
    if (status_code != 200)
    {
        //std::cout << "Response returned with status code " << status_code << "\n";
        return 9003;
    }

    // Read the response headers, which are terminated by a blank line.
    boost::asio::read_until(socket, response, "\r\n\r\n");

    // Process the response headers.
    std::string header;
    std::string fullHeader = "";
    while (std::getline(response_stream, header) && header != "\r")
        fullHeader.append(header).append("\n");

    // Write whatever content we already have to output.
    std::string fullResponse = "";
    if (response.size() > 0)
    {
        std::stringstream ss;
        ss << &response;
        fullResponse = ss.str();
     
    
    }

    // Read until EOF, writing data to output as we go.
    std::string fullSth = "";
    boost::system::error_code error;
    while (boost::asio::read(socket, response,
        boost::asio::transfer_at_least(1), error))
    {
        std::ostringstream ss;
        ss << &response;
        fullSth = ss.str();
    }
    if (error != boost::asio::error::eof)
        throw boost::system::system_error(error);
}
catch (std::exception& e)
{
    write_text_to_log_file(e.what());
    return 9001;
}

fullHeader 的值为

 x-proxy-by: Tif-APIGate
 Set-Cookie: XSRF-TOKEN=ebcf70d2-8b00-46b9-a8f9-6dcbbc535ee9; Path=/
 Content-Disposition: attachment; filename="202012303333629003180526491.txt.zip"
 X-Content-Type-Options: nosniff
 X-XSS-Protection: 1; mode=block
 Cache-Control: no-cache, no-store, max-age=0, must-revalidate
 Pragma: no-cache
 Expires: 0
 Content-Type: application/octet-stream;charset=UTF-8
 Transfer-Encoding: chunked
 Date: Tue, 23 Mar 2021 02:34:38 GMT
 connection: Close
 x-tif-nonce: kmlen6de-122075580

fullResponse 的值为

 2a4
 PK

【问题讨论】:

  • fullRespose 似乎只包含读取标题后缓冲区中剩余的任何内容?

标签: c++ boost-asio


【解决方案1】:

如果您打算阅读到 EOF,似乎应该说 transfer_at_least(1) 而不是 transfer_all()

另外,如果您确实编写了循环,则应该使用结果,而不是覆盖它。所以,例如而不是

        fullSth = ss.str();

我希望有更多类似的东西

        fullSth += ss.str();

【讨论】:

  • 感谢您的宝贵时间,我发现问题是分块传输,它比正常传输更复杂,因为它没有提及响应标头中的长度,我正在尝试其他类似的东西stackoverflow.com/questions/40780782/…,
  • 非常感谢您的帮助
  • @Ken 我可以建议做的更简单:stackoverflow.com/questions/66730771/…。真的没有必要为什么有人仍然像 1992 年一样复制粘贴糟糕的 HTTP 实现(Asio 文档应该明确说明这些示例仅用于说明目的,并且存在 Boost Beast)
  • 您好,很抱歉迟到了,这些天我在 Google 上搜索了如何处理 Chunked 编码数据,感谢您的启发,我知道如何处理它,现在我正在尝试解析它,非常感谢,真的很感激——
猜你喜欢
  • 1970-01-01
  • 2019-12-27
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多