使用Boost Asio和OpenSSL创建HTTPS请求

7

我创建了一个简单的HTTP请求,向服务器发送GET、POST和PUT请求。接下来,我想使用Boost Asio库切换到HTTPS连接,我应该怎么做?

我有一个Executor类来解析并连接到服务器,还有一个RequestCreator类来创建请求。

2个回答

12

我碰巧在评论中发布了这样一件事情:

你只需通过ssl连接。@Milind coliru.stacked-crooked.com/a/9546326fd1def416

也许对你有帮助。

在Coliru上实时查看

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <iostream>

int main() {
    boost::system::error_code ec;
    using namespace boost::asio;

    // what we need
    io_service svc;
    ssl::context ctx(svc, ssl::context::method::sslv23_client);
    ssl::stream<ip::tcp::socket> ssock(svc, ctx);
    ssock.lowest_layer().connect({ {}, 8087 }); // http://localhost:8087 for test
    ssock.handshake(ssl::stream_base::handshake_type::client);

    // send request
    std::string request("GET /newGame?name=david HTTP/1.1\r\n\r\n");
    boost::asio::write(ssock, buffer(request));

    // read response
    std::string response;

    do {
        char buf[1024];
        size_t bytes_transferred = ssock.read_some(buffer(buf), ec);
        if (!ec) response.append(buf, buf + bytes_transferred);
    } while (!ec);

    // print and exit
    std::cout << "Response received: '" << response << "'\n";
}

为了演示目的,我一直在使用来自Asio示例(https://dev59.com/fIzda4cB1Zd3GeqPop69#31201907)的证书和参数来模拟服务器。

更新: 这里有一个版本,它使用解析器来解析端点(Coliru不允许我们这样做,但在非限制性机器上可以工作)。

在Coliru上实时运行

ip::tcp::resolver resolver(svc);
auto it = resolver.resolve({"localhost", "8087"}); // http://localhost:8087 for test
boost::asio::connect(ssock.lowest_layer(), it);

// and the rest unaltered
ssock.handshake(ssl::stream_base::handshake_type::client);

@DevMac,我找到时间回复你的评论了,请看更新。你找到比这更令人困惑的在线示例了吗? - sehe
你在这里使用了auto,这是依赖于编译器的,对吧? - DevMac
如果出现任何错误,您如何优雅地关闭连接/套接字?@sehe - DevMac
2
auto 不依赖于编译器。它是标准版本相关的,因为 c++11 引入了它。所有编译器都支持在 c++11 模式下使用它。你所说的“优雅关闭”是什么意思?也许现在是搜索现有答案来回答你不同的问题的时候了。如果一切都失败了,你可以提出一个新的问题。 - sehe
我基本上是在 boost::asio::ip::tcp::resolver::iterator 中获取 resolver.resolve(query) 的结果 - DevMac
显示剩余4条评论

0
简单示例:
#include<string>
#include<iostream>

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
#include <boost/beast.hpp>

using namespace boost::beast;
using namespace boost::asio;

using std::string;
using std::cout;


int
main() {

    const string host = "www.google.com";
    const string path = "/";
    const string port = "443";

    io_service svc;

    ssl::context ctx(ssl::context::sslv23_client);
    ssl::stream<ip::tcp::socket> ssocket = { svc, ctx };
    ip::tcp::resolver resolver(svc);
    auto it = resolver.resolve(host, port);
    connect(ssocket.lowest_layer(), it);
    ssocket.handshake(ssl::stream_base::handshake_type::client);
    http::request<http::string_body> req{ http::verb::get, path, 11 };
    req.set(http::field::host, host);
    http::write(ssocket, req);
    http::response<http::string_body> res;
    flat_buffer buffer;
    http::read(ssocket, buffer, res);
    cout << "Headers" << std::endl;
    cout << res.base() << std::endl << std::endl;
    cout << "Body" << std::endl;
    cout << res.body() << std::endl << std::endl;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接