Boost Asio同步https调用-Json响应具有意外字符 [英] Boost asio synchronous https call- Json response have unintended character

查看:144
本文介绍了Boost Asio同步https调用-Json响应具有意外字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

we are migrating from http to https boost asio sysnchornous call and I am using the below code to make https synchoronous call with ssl certificate validation and we got the response into multiple lines; as of now i have removed the line feed character(\r\n)(upstream system is saying that they are sending response in single line and without any extra character as described below) and tried to parse the response but sometimes we are getting the response with extra characters in key value pairs as shown below:

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,而我们获得了存储库)的情况如下:

I couldn't paste the full response due to security reason but small part where the extra character(here 21f0 is getting appended while we got the resposne)is getting added is shown below:

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

请让我知道我从插座上读取的是准确的还是需要修改的.

Please let me know whether i am reading from the socket is accurate or needs modification.

推荐答案

出于安全原因,我无法粘贴完整的响应,但其中添加了多余字符(在此位置添加了21f0的附加小字符)如下所示:

I couldn't paste the full response due to security reason but small part where the extra character(here 21f0 is getting appended while we got the response)is getting added is shown below:

我们无法知道.回应有多大?我遇到的麻烦是,它可能正在使用分块编码,您可能会对其进行错误处理,因为您是手动非分析"编码. HTTP响应?

We have no way of knowing. How big is the response? My wild stab at things is that it might be using chunked encoding which you are potentially mis-handling because you manually "non-parse" HTTP responses?

在那种情况下,我的先前的答案可能是预言性的:

In that case, my earlier answer might be kind of prophetic:

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

Luckily, you can also refer to that live example to see how to use Boost Beast to read the response correctly.

在Coliru上直播

Live On Coliru

我还将重复该摘要,因为该课程很重要:

I'll also repeat the summary because the lesson is an important one:

旁注:直到EOF才可能适用于HTTP/1.0.但是服务器可能会正确拒绝该版本,或者仍然选择使用HTTP/1.1进行响应.

Side note: Just reading until EOF would probably have worked for HTTP/1.0. But the server might rightfully reject that version or choose to respond with HTTP/1.1 anyways.

这篇关于Boost Asio同步https调用-Json响应具有意外字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆