-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathHTTP_Client_Async_SSL.h
140 lines (112 loc) · 5.15 KB
/
HTTP_Client_Async_SSL.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#pragma once
#ifndef HTTP_CLIENT_ASYNC_SSL
#define HTTP_CLIENT_ASYNC_SSL
// Example taken from: https://github.com/boostorg/beast/blob/develop/example/http/client/async-ssl/http_client_async_ssl.cpp
//
// Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// Official repository: https://github.com/boostorg/beast
//
//------------------------------------------------------------------------------
//
// Example: HTTP client, asynchronous, SSL
//
//------------------------------------------------------------------------------
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/ssl.hpp>
#include <boost/beast/version.hpp>
#include <boost/asio/strand.hpp>
#include "StdAfx.h"
namespace beast = boost::beast; // from <boost/beast.hpp>
namespace http = beast::http; // from <boost/beast/http.hpp>
namespace net = boost::asio; // from <boost/asio.hpp>
namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
//------------------------------------------------------------------------------
// Report a failure
inline void boostFail_secure(beast::error_code ec, char const* what)
{
//std::cerr << what << ": " << ec.message() << "\n";
string error = what;
error += ": " + ec.message() + "\n";
DEBUG_PRINT(error.c_str())
}
// Performs an HTTP GET and prints the response
class SSL_session : public std::enable_shared_from_this<SSL_session>
{
tcp::resolver resolver_;
beast::ssl_stream<beast::tcp_stream> stream_;
beast::flat_buffer buffer_; // (Must persist between reads)
http::request<http::string_body> req_;
http::response<http::string_body> res_;
public:
explicit
SSL_session(
net::executor ex,
ssl::context& ctx)
: resolver_(ex)
, stream_(ex, ctx)
{
}
// Start the asynchronous operation
http::response<http::string_body>* run(Json::Value dataToSend, char const* host, char const* port, char const* target, int version);
void on_resolve(beast::error_code ec, tcp::resolver::results_type results);
void on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type);
void on_handshake(beast::error_code ec);
void on_write(beast::error_code ec, std::size_t bytes_transferred);
void on_read(beast::error_code ec, std::size_t bytes_transferred);
void on_shutdown(beast::error_code ec);
};
inline void load_root_certificates(ssl::context& ctx)
{
boost::system::error_code ec;
string const cert =
"-----BEGIN CERTIFICATE-----\n"
"MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/\n"
"MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT\n"
"DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow\n"
"PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD\n"
"Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\n"
"AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O\n"
"rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq\n"
"OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b\n"
"xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw\n"
"7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD\n"
"aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV\n"
"HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG\n"
"SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69\n"
"ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr\n"
"AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz\n"
"R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5\n"
"JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo\n"
"Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ\n"
"-----END CERTIFICATE-----\n"
;
ctx.add_certificate_authority(
boost::asio::buffer(cert.data(), cert.size()), ec);
if (ec) throw boost::system::system_error{ ec };
}
inline http::response<http::string_body> upload_data_secure(Json::Value dataToSend, char const* target = "/api/benchmarkData") {
char const* host = "syslat.com";
char const* port = "443";
int version = 11;
// The io_context is required for all I/O
net::io_context ioc;
// The SSL context is required, and holds certificates
ssl::context ctx{ ssl::context::tlsv13_client };
//beast::error_code ec2;
// This holds the root certificate used for verification
load_root_certificates(ctx);
// Verify the remote server's certificate
ctx.set_verify_mode(ssl::verify_peer);
auto sharedPointer = std::make_shared<SSL_session>(net::make_strand(ioc),ctx);
auto prv = sharedPointer->run(dataToSend, host, port, target, version);
ioc.run();
http::response<http::string_body> rv = *prv;
return rv;
}
#endif