有一个谨慎的小量 boost::asio::ssl http://en.wikipedia.org/wiki/Transport_Layer_Security小型 C++ 在线教育代码库。甚至更少boost::asio::ssl::context::load_verify_file http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/reference/ssl__context/load_verify_file.html所以我找到了一个来自here https://stackoverflow.com/questions/7046370/https-request-with-boost-asio-and-openssl代码修改最少 - 使用 boost 1.47.0 编译并运行:
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <istream>
#include <ostream>
#include <string>
class client
{
public:
client(boost::asio::io_service& io_service, boost::asio::ssl::context& context, boost::asio::ip::tcp::resolver::iterator endpoint_iterator)
: socket_(io_service, context)
{
socket_.set_verify_mode(boost::asio::ssl::context::verify_none);
socket_.set_verify_callback(boost::bind(&client::verify_certificate, this, _1, _2));
boost::asio::async_connect(socket_.lowest_layer(), endpoint_iterator, boost::bind(&client::handle_connect, this, boost::asio::placeholders::error));
}
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 preverified;
}
void handle_connect(const boost::system::error_code& error)
{
if(!error){
std::cout << "Connection OK!" << std::endl;
socket_.async_handshake(boost::asio::ssl::stream_base::client, boost::bind(&client::handle_handshake, this, boost::asio::placeholders::error));
}else{
std::cout << "Connect failed: " << error.message() << std::endl;
}
}
void handle_handshake(const boost::system::error_code& error)
{
if(!error){
std::cout << "Sending request: " << std::endl;
std::stringstream request_;
request_ << "GET /api/0/data/ticker.php HTTP/1.1\r\n";
request_ << "Host: mtgox.com\r\n";
request_ << "Accept-Encoding: *\r\n";
request_ << "\r\n";
std::cout << request_.str() << std::endl;
boost::asio::async_write(socket_, boost::asio::buffer(request_.str()), boost::bind(&client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}else{
std::cout << "Handshake failed: " << error.message() << std::endl;
}
}
void handle_write(const boost::system::error_code& error, size_t bytes_transferred)
{
if (!error){
std::cout << "Sending request OK!" << std::endl;
boost::asio::async_read(socket_, boost::asio::buffer(reply_, bytes_transferred), boost::bind(&client::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}else{
std::cout << "Write failed: " << error.message() << std::endl;
}
}
void handle_read(const boost::system::error_code& error, size_t bytes_transferred)
{
if (!error){
std::cout << "Reply: ";
std::cout.write(reply_, bytes_transferred);
std::cout << "\n";
}else{
std::cout << "Read failed: " << error.message() << std::endl;
}
}
private:
boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_;
char reply_[0x1 << 16];
};
int main(int argc, char* argv[])
{
try{
boost::asio::io_service io_service;
boost::asio::ip::tcp::resolver resolver(io_service);
boost::asio::ip::tcp::resolver::query query("mtgox.com", "443");
boost::asio::ip::tcp::resolver::iterator iterator = resolver.resolve(query);
boost::asio::ssl::context context(boost::asio::ssl::context::sslv23);
//context.load_verify_file("key.pem"); // uncomment this line
client c(io_service, context, iterator);
io_service.run();
}catch (std::exception& e){
std::cerr << "Exception: " << e.what() << "\n";
}
std::cin.get();
return 0;
}
这是一行非常奇怪的行:context.load_verify_file("key.pem");
所以我对此有一些疑问:
- 作为 http 客户端,这对我意味着什么?
- 是否发送到服务器?
- 如何创建这样的文件?
- 到底是为了什么?
- 代码无需它即可编译和运行。可以吗?如果没有这个,我们与服务器的连接是否安全
key.pem
?
- 我想使用谷歌或其他大型 ssl 主机。我该怎么办?