2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
42#include "core/SNodeC.h"
43#include "core/socket/stream/SocketContext.h"
44#include "core/socket/stream/SocketContextFactory.h"
45#include "net/in/stream/legacy/SocketClient.h"
46#include "net/in/stream/tls/SocketClient.h"
47#include "web/http/client/ResponseParser.h"
49#ifndef DOXYGEN_SHOULD_SKIP_THIS
51#include "log/Logger.h"
54#include <openssl/ssl.h>
55#include <openssl/x509v3.h>
73 VLOG(1) <<
"++ OnStarted";
75 []([[maybe_unused]] web::http::client::
Response&& res) {
76 VLOG(1) <<
"++ OnParsed";
78 [](
int status,
const std::string& reason) {
79 VLOG(1) <<
"++ OnError: " + std::to_string(status) +
" - " + reason;
82 return responseParser;
95 VLOG(1) <<
"SimpleSocketProtocol connected";
98 VLOG(1) <<
"SimpleSocketProtocol disconnected";
145 using SocketAddress = SocketClient::SocketAddress;
146 using SocketConnection = SocketClient::SocketConnection;
149 SocketClient tlsClient(
151 [](SocketConnection* socketConnection) {
152 VLOG(1) <<
"OnConnect";
166 [](SocketConnection* socketConnection) {
167 VLOG(1) <<
"OnConnected";
169 X509* server_cert = SSL_get_peer_certificate(socketConnection
->getSSL());
170 if (server_cert !=
nullptr) {
171 const long verifyErr = SSL_get_verify_result(socketConnection
->getSSL());
173 VLOG(1) <<
" Server certificate: " + std::string(X509_verify_cert_error_string(verifyErr));
175 char* str = X509_NAME_oneline(X509_get_subject_name(server_cert),
nullptr, 0);
176 VLOG(1) <<
" Subject: " + std::string(str);
179 str = X509_NAME_oneline(X509_get_issuer_name(server_cert),
nullptr, 0);
180 VLOG(1) <<
" Issuer: " + std::string(str);
185 GENERAL_NAMES* subjectAltNames =
186 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(server_cert, NID_subject_alt_name,
nullptr,
nullptr));
188#pragma GCC diagnostic push
190#if __has_warning
("-Wused-but-marked-unused")
191#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
195 const int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
197#pragma GCC diagnostic pop
199 VLOG(1) <<
"\t Subject alternative name count: " << altNameCount;
200 for (int32_t i = 0; i < altNameCount; ++i) {
202#pragma GCC diagnostic push
204#if __has_warning
("-Wused-but-marked-unused")
205#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
209 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
211#pragma GCC diagnostic pop
213 if (generalName->type == GEN_URI) {
214 const std::string subjectAltName =
215 std::string(
reinterpret_cast<
const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
216 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
217 VLOG(1) <<
"\t SAN (URI): '" + subjectAltName;
218 }
else if (generalName->type == GEN_DNS) {
219 const std::string subjectAltName =
220 std::string(
reinterpret_cast<
const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
221 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
222 VLOG(1) <<
"\t SAN (DNS): '" + subjectAltName;
224 VLOG(1) <<
"\t SAN (Type): '" + std::to_string(generalName->type);
228#pragma GCC diagnostic push
230#if __has_warning
("-Wused-but-marked-unused")
231#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
235 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
237#pragma GCC diagnostic pop
239 X509_free(server_cert);
241 VLOG(1) <<
" Server certificate: no certificate";
244 socketConnection
->sendToPeer("GET /index.html HTTP/1.1\r\nConnection: close\r\n\r\n");
246 [](SocketConnection* socketConnection) {
247 VLOG(1) <<
"OnDisconnect";
254 const SocketAddress remoteAddress
("localhost", 8088
);
258 const SocketAddress& socketAddress,
259 const core::socket::
State& state) {
262 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
265 VLOG(1) << instanceName <<
": disabled";
268 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
271 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
283 using SocketAddress = SocketClient::SocketAddress;
284 using SocketConnection = SocketClient::SocketConnection;
287 SocketClient legacyClient(
289 [](SocketConnection* socketConnection) {
290 VLOG(1) <<
"OnConnect";
295 [](SocketConnection* socketConnection) {
296 VLOG(1) <<
"OnConnected";
298 socketConnection
->sendToPeer("GET /index.html HTTP/1.1\r\nConnection: close\r\n\r\n");
300 [](SocketConnection* socketConnection) {
301 VLOG(1) <<
"OnDisconnect";
307 SocketAddress remoteAddress
("localhost", 8080
);
312 VLOG(1) <<
"###############': " << remoteAddress
.toString();
316 const tls::SocketAddress& socketAddress,
317 const core::socket::
State& state) {
320 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
323 VLOG(1) << instanceName <<
": disabled";
326 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
329 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
339int main(
int argc,
char* argv[]) {
343 const legacy::SocketAddress legacyRemoteAddress
("localhost", 8080
);
349 const tls::SocketAddress& socketAddress,
350 const core::socket::
State& state) {
353 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
356 VLOG(1) << instanceName <<
": disabled";
359 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
362 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
367 const tls::SocketAddress tlsRemoteAddress =
tls::SocketAddress
("localhost", 8088
);
373 const tls::SocketAddress& socketAddress,
374 const core::socket::
State& state) {
377 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
380 VLOG(1) << instanceName <<
": disabled";
383 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
386 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
core::socket::stream::SocketContext * create(core::socket::stream::SocketConnection *socketConnection) override
~SimpleSocketProtocolFactory() override
void onDisconnected() override
~SimpleSocketProtocol() override
web::http::client::ResponseParser * responseParser
SimpleSocketProtocol(core::socket::stream::SocketConnection *socketConnection)
bool onSignal(int signum) override
void onConnected() override
void onReadError(int errnum) override
void onWriteError(int errnum) override
std::size_t onReceivedFromPeer() override
static void init(int argc, char *argv[])
static int start(const utils::Timeval &timeOut={LONG_MAX, 0})
Config & getConfig() const
static constexpr int DISABLED
static constexpr int ERROR
static constexpr int FATAL
void connect(const SocketAddress &remoteAddress, const std::function< void(const SocketAddress &, core::socket::State)> &onStatus) const
const SocketAddress & getRemoteAddress() const final
const SocketAddress & getLocalAddress() const final
void sendToPeer(const std::string &data)
SocketContext(core::socket::stream::SocketConnection *socketConnection)
void onReadError(int errnum) override
void shutdownWrite(bool forceClose=false)
void onWriteError(int errnum) override
const std::string & getInstanceName() const
SocketAddress(const std::string &ipOrHostname, uint16_t port)
std::string getCanonName() const
std::string toString(bool expanded=true) const override
void init(const Hints &hints={.aiFlags=0,.aiSockType=0,.aiProtocol=0})
ResponseParser(core::socket::stream::SocketContext *socketContext, const std::function< void()> &onResponseStart, const std::function< void(Response &&)> &onResponseParsed, const std::function< void(int, const std::string &)> &onResponseParseError)
int main(int argc, char *argv[])
static web::http::client::ResponseParser * getResponseParser(core::socket::stream::SocketContext *socketContext)
SocketClient getLegacyClient()