【问题标题】:Boost asio synchronous https call- Json response have unintended characterBoost asio 同步 https 调用 - Json 响应具有意外字符
【发布时间】:2020-08-14 18:07:08
【问题描述】:

我们正在从 http 迁移到 https boost asio sysnchornous 调用,我正在使用下面的代码进行带有 ssl 证书验证的 https 同步调用,我们得到了多行响应;截至目前,我已经删除了换行符(\r\n)(上游系统说他们在单行中发送响应并且没有任何额外字符,如下所述)并尝试解析响应但有时我们得到键值对中带有额外字符的响应,如下所示:

try{
fast_ostringstream oss;
boost::asio::streambuf request_;
boost::asio::streambuf response_;
boost::system::error_code ec;
boost::asio::ssl::context ctx(boost::asio::ssl::context::sslv23);
ctx.set_verify_mode(boost::asio::ssl::verify_peer);
ctx.set_default_verify_paths(ec);
if (ec)
{
        fast_ostringstream oss;
        oss << "Issue in settign the default path:" << ec.message();
        PBLOG_INFO(oss.str());
}
oss << ec.message();
ctx.add_verify_path("/home/test/pemcert/");
ctx.set_options(boost::asio::ssl::context::default_workarounds |
       boost::asio::ssl::context::no_sslv2 |
       boost::asio::ssl::context::no_sslv3);
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(io_service,ctx);

std::ostream request_stream(&request_);
request_stream << "POST " << server_endpoint << " HTTP/1.1\r\n";
request_stream << "Host: " << hostname << "\r\n";
request_stream << "Accept: */*\r\n";
request_stream << authorization_token << "\r\n";
request_stream << client_name << "\r\n";
request_stream << "Content-Length: " << req_str.length() << "\r\n";
request_stream << "Content-Type: application/x-www-form-urlencoded \r\n";
request_stream << "Connection: close\r\n\r\n";
request_stream << req_str << "\r\n";
tcp::resolver resolver(io_service);
tcp::resolver resolver(io_service);
tcp::resolver::query query(hostname, port_no);

tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;

boost::system::error_code error  = boost::asio::error::host_not_found;
boost::asio::connect(socket.lowest_layer(), endpoint_iterator, error);
boost::system::error_code echs;
socket.handshake(boost::asio::ssl::stream_base::client, echs);
boost::asio::write(socket, request_);
PBLOG_INFO("Trac Request successfully sent");

// Read the response status line.
boost::asio::read_until(socket, response_, "\r\n");
string res=make_string(response_);

// 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/")
{
        PBLOG_WARN("Invalid response\n");
}
if (status_code != 200)
{
        fast_ostringstream oss;
        oss << "Response returned with status code: " << status_code << "\n";
        PBLOG_WARN(oss.str());
}
boost::asio::read(socket, response_, boost::asio::transfer_all(), error);
if (error.value() != 335544539 && strcmp(error.category().name(),"asio.ssl") != 0 )
{
    fast_ostringstream oss;
    oss << "Error : " << error.message() << "Value:" << error.value() << "Category Name:" << error.category().name();
    PBLOG_WARN(oss.str());
    return false;
}
else
{
     string message = make_string(response_);
     size_t pos = message.find( "header" );
     if( pos != std::string::npos)
     {
          pos = pos - 2;
          string msg = message.substr(pos, message.length());
          msg.erase(std::remove(msg.begin(),msg.end(),'\n'),msg.end());
          msg.erase(std::remove(msg.begin(),msg.end(),'\r'),msg.end());
          msg.erase(msg.size()-1); //to ignore the short read error
          response = msg;

     }
     else
     {
        fast_ostringstream oss;
          oss << "Invalid Response: " << message;
          PBLOG_WARN(oss.str());
          return false;
     }
     socket.lowest_layer().shutdown(tcp::socket::shutdown_both);
}
}

Json 响应:

由于安全原因,我无法粘贴完整的响应,但添加了额外字符的一小部分(这里是 21f0,而我们得到了响应)被添加如下所示:

"SGEType":{"decisionKey"21f0:"SGMtype","decisionValue":null,"decisionGroup":"partyTranslations","ruleName":"Party Details Translations"}

请让我知道我从套接字读取的数据是否准确或需要修改。

【问题讨论】:

    标签: https boost-asio


    【解决方案1】:

    由于安全原因,我无法粘贴完整的响应,但添加了额外字符的一小部分(这里是 21f0 在我们收到响应时被附加)如下所示:

    我们无从得知。反响有多大?我对事情的疯狂抨击是它可能使用了分块编码,因为您手动“非解析”HTTP响应,您可能会误处理?

    在这种情况下,我的earlier answer 可能有点预言:

    幸运的是,您还可以参考该实时示例,了解如何使用 Boost Beast 正确读取响应。

    Live On Coliru

    我也会重复总结,因为这节课很重要:


    旁注:只读到 EOF 可能适用于 HTTP/1.0。但服务器可能理所当然地拒绝该版本或选择以 HTTP/1.1 进行响应。

    【讨论】:

    • 嗨,嘿嘿,哪个版本的 boost 将包含野兽库以及我们必须在 redhat linux 中安装相同的 RPM 包?
    • boost.org/doc/libs/1_74_0/libs/beast/doc/html/beast/… - 在 boost 1.66 中引入。 Redhat 软件包版本取决于您运行的版本
    • 这里是关于如何查找软件包版本的提示unix.stackexchange.com/questions/6864/…我没有帐户
    • 我得到了 1.70 的 boost 版本,我需要在发送到目标系统之前将请求转换为在日志文件中打印,因为请求的类型是 http::request<:string_body> 请求;如何在日志中打印?
    • 我们正在使用 ostringstream 记录输出,在收到响应后,如何复制到字符串以仅提取所需的消息。(现在我也无法将消息复制到字符串。
    猜你喜欢
    • 1970-01-01
    • 2020-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2011-12-05
    • 2015-01-15
    • 2015-04-17
    • 1970-01-01
    相关资源
    最近更新 更多