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";
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";
152 VLOG(1) <<
"OnConnect";
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 const int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
190 VLOG(1) <<
"\t Subject alternative name count: " << altNameCount;
191 for (int32_t i = 0; i < altNameCount; ++i) {
192 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
193 if (generalName->type == GEN_URI) {
194 const std::string subjectAltName =
195 std::string(
reinterpret_cast<
const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
196 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
197 VLOG(1) <<
"\t SAN (URI): '" + subjectAltName;
198 }
else if (generalName->type == GEN_DNS) {
199 const std::string subjectAltName =
200 std::string(
reinterpret_cast<
const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
201 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
202 VLOG(1) <<
"\t SAN (DNS): '" + subjectAltName;
204 VLOG(1) <<
"\t SAN (Type): '" + std::to_string(generalName->type);
208 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
210 X509_free(server_cert);
212 VLOG(1) <<
" Server certificate: no certificate";
215 socketConnection
->sendToPeer("GET /index.html HTTP/1.1\r\nConnection: close\r\n\r\n");
218 VLOG(1) <<
"OnDisconnect";
230 const core::socket::
State& state) {
233 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
236 VLOG(1) << instanceName <<
": disabled";
239 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
242 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
261 VLOG(1) <<
"OnConnect";
267 VLOG(1) <<
"OnConnected";
269 socketConnection
->sendToPeer("GET /index.html HTTP/1.1\r\nConnection: close\r\n\r\n");
272 VLOG(1) <<
"OnDisconnect";
283 VLOG(1) <<
"###############': " << remoteAddress
.toString();
288 const core::socket::
State& state) {
291 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
294 VLOG(1) << instanceName <<
": disabled";
297 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
300 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
310int main(
int argc,
char* argv[]) {
321 const core::socket::
State& state) {
324 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
327 VLOG(1) << instanceName <<
": disabled";
330 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
333 LOG(FATAL) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
345 const core::socket::
State& state) {
348 VLOG(1) << instanceName <<
": connected to '" << socketAddress
.toString() <<
"'";
351 VLOG(1) << instanceName <<
": disabled";
354 LOG(ERROR) << instanceName <<
": " << socketAddress
.toString() <<
": " << state
.what();
357 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
const SocketClient & 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)
net::in::stream::legacy::SocketClient< apps::http::SimpleSocketProtocolFactory > SocketClient
SocketClient::SocketAddress SocketAddress
SocketClient::SocketConnection SocketConnection
SocketClient getLegacyClient()
net::in::stream::SocketClient< core::socket::stream::legacy::SocketConnector, net::in::stream::legacy::config::ConfigSocketClient, SocketContextFactoryT, Args... > SocketClient
net::in::stream::SocketClient< core::socket::stream::tls::SocketConnector, net::in::stream::tls::config::ConfigSocketClient, SocketContextFactoryT, Args... > SocketClient
net::in::stream::tls::SocketClient< apps::http::SimpleSocketProtocolFactory > SocketClient
SocketClient::SocketConnection SocketConnection
SocketClient::SocketAddress SocketAddress