[英]Boost Asio C++ HTTPS Request not hitting server. No errors
我試圖使用Boost asio ssl C ++命中一個端點。 一切順利,沒有任何錯誤。 但請求只是沒有擊中服務器。 以下是代碼:
string protocol,domain,port,path;
boost::regex ex("(http|https)://([^/ :]+):?([^/ ]*)(/?[^ #?]*)\\x3f?([^ #]*)#?([^ ]*)");
boost::cmatch what;
if(regex_match(url.c_str(), what, ex))
{
protocol= string(what[1].first, what[1].second);
domain= string(what[2].first, what[2].second);
port= string(what[3].first, what[3].second);
path= string(what[4].first, what[4].second);
}
// Get a list of endpoints corresponding to the server name.
boost::asio::io_service io_service;
boost::asio::ssl::context ctx(ssl::context::sslv23);
ctx.set_default_verify_paths();
ctx.set_options(boost::asio::ssl::context::default_workarounds |
boost::asio::ssl::context::verify_none );
ssl_socket socket(io_service, ctx);
tcp::resolver resolver(io_service);
tcp::resolver::query query(domain.c_str(), port.c_str());
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
socket.set_verify_mode(boost::asio::ssl::context::verify_none);
// Try each endpoint until we successfully establish a connection.
socket.set_verify_callback(verify_certificate);
boost::asio::connect(socket.lowest_layer(), endpoint_iterator);
socket.handshake(ssl_socket::client);
socket.lowest_layer().set_option(tcp::no_delay(true));
// 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 "<<path<<"/ssl HTTP/1.1 \r\n";
request_stream << "Host:" << domain<<":"<<port << "\r\n";
request_stream << "User-Agent: C/1.0";
request_stream << "Content-Type: application/vnd.api+json; charset=utf-8 \r\n";
request_stream << "Accept: */*\r\n";
request_stream << "Content-Length: " << json.length() << "\r\n";
request_stream << "Connection: close\r\n\r\n"; //NOTE THE Double line feed
request_stream << json<<"\r\n";
request_stream << std::cin.rdbuf() << std::flush;
int a=boost::asio::write(socket, request);
bool verify_certificate(bool preverified, boost::asio::ssl::verify_context& ctx)
{
/* char subject_name[256];
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying:\n" << subject_name << std::endl;*/
return true;
}
我使用的是自簽名證書,我堅信這就是問題所在。 但是,我也沒有得到任何握手錯誤。 我在這做錯了什么?
編輯:我得到以下輸出:
Connected to:
Response: short read
現在我不確定為什么連接到零件是空的。 我調試並交叉檢查了主機,端口和路徑變量不為空的事實。
如果port
為空,您的方法將失敗。
此外,如果用戶代理缺少行結束:
request_stream << "User-Agent: C/1.0\r\n";
我試過了
std::string url = "https://209.85.203.105:443/";
和
//std::string url = "https://www.google.com:443/";
它有效。
#include <boost/asio.hpp>
#include <boost/regex.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>
namespace ssl = boost::asio::ssl;
using tcp = boost::asio::ip::tcp;
using ssl_socket = ssl::stream<tcp::socket>;
bool verify_certificate(bool /*preverified*/, boost::asio::ssl::verify_context& /*ctx*/)
{
/* char subject_name[256];
X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
std::cout << "Verifying:\n" << subject_name << std::endl;*/
return true;
}
int main() {
std::string url = "https://www.stackoverflow.com:443/";
//std::string url = "https://209.85.203.105:443/";
std::string json = "{ \"hello\" : \"world\" }";
std::string protocol,domain,port,path;
boost::regex ex("(http|https)://([^/ :]+):?([^/ ]*)(/?[^ #?]*)\\x3f?([^ #]*)#?([^ ]*)");
boost::cmatch what;
if(regex_match(url.c_str(), what, ex))
{
protocol= std::string(what[1].first, what[1].second);
domain= std::string(what[2].first, what[2].second);
port= std::string(what[3].first, what[3].second);
path= std::string(what[4].first, what[4].second);
}
std::cout << "protocol: " << protocol << "\n";
std::cout << "domain: " << domain << "\n";
std::cout << "port: " << port << "\n";
std::cout << "path: " << path << "\n";
// Get a list of endpoints corresponding to the server name.
boost::asio::io_service io_service;
boost::asio::ssl::context ctx(ssl::context::sslv23);
ctx.set_default_verify_paths();
ctx.set_options(boost::asio::ssl::context::default_workarounds | boost::asio::ssl::context::verify_none);
ssl_socket socket(io_service, ctx);
tcp::resolver resolver(io_service);
tcp::resolver::query query(domain.c_str(), port.c_str());
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
socket.set_verify_mode(boost::asio::ssl::context::verify_none);
// Try each endpoint until we successfully establish a connection.
socket.set_verify_callback(verify_certificate);
std::cout << "Connecting... " << std::flush;
boost::asio::connect(socket.lowest_layer(), endpoint_iterator);
std::cout << "Connected to " << socket.lowest_layer().remote_endpoint() << "\n";
socket.handshake(ssl_socket::client);
socket.lowest_layer().set_option(tcp::no_delay(true));
// 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 << "GET " << path << " HTTP/1.1\r\n";
request_stream << "Host:" << domain << ":" << port << "\r\n";
//request_stream << "Host:" << domain << "\r\n";
request_stream << "User-Agent: C/1.0\r\n";
//request_stream << "Content-Type: application/vnd.api+json; charset=utf-8 \r\n";
request_stream << "Accept: */*\r\n";
//request_stream << "Content-Length: " << json.length() << "\r\n";
request_stream << "Connection: close\r\n\r\n";
//request_stream << json << "\r\n";
//request_stream << std::cin.rdbuf() << std::flush;
int a = boost::asio::write(socket, request);
std::cout << a << " byte sent\n";
std::vector<char> response(10 * 1024);
boost::system::error_code ec;
auto bytes_received = boost::asio::read(socket, boost::asio::buffer(response), boost::asio::transfer_all(), ec);
response.resize(a);
std::cout << "Response: " << ec.message() << "\n----------------\n";
std::cout.write(response.data(), bytes_received) << std::flush;
}
打印
protocol: https
domain: www.stackoverflow.com
port: 443
path: /
Connecting... Connected to 151.101.129.69:443
101 byte sent
Response: End of file
----------------
HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=UTF-8
Location: http://stackoverflow.com/
Content-Length: 148
Accept-Ranges: bytes
Date: Thu, 08 Sep 2016 07:13:08 GMT
Via: 1.1 varnish
Connection: close
X-Served-By: cache-ams4420-AMS
X-Cache: MISS
X-Cache-Hits: 0
X-Timer: S1473318788.479431,VS0,VE342
X-DNS-Prefetch-Control: off
Set-Cookie: prov=90860619-8a76-9233-21d1-43de9920a25c; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:00 GMT; path=/; HttpOnly
<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="http://stackoverflow.com/">here</a></body>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.