338 {
340 "httpclient",
341 [](const std::shared_ptr<Request>& req) {
342 VLOG(1) << req->getSocketContext()->getSocketConnection()->getConnectionName() << ": OnRequestStart";
343
344 req->url = "/";
345 req->set("Connection", "keep-alive");
346 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
348 });
349 req->url = "/";
350 req->set("Connection", "keep-alive");
351 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
353 });
354 req->url = "/index.html";
355 req->set("Connection", "keep-alive");
356 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
358 });
359 req->url = "/";
360 req->set("Connection", "keep-alive");
361 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
363 });
364 req->url = "/index.html";
365 req->set("Connection", "keep-alive");
366 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
368 });
369 req->url = "/";
370 req->set("Connection", "keep-alive");
371 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
373 });
374 req->url = "/index.html";
375 req->set("Connection", "keep-alive");
376 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
378 });
379 req->url = "/";
380 req->set("Connection", "keep-alive");
381 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
383 });
384 req->url = "/index.html";
385 req->set("Connection", "keep-alive");
386 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
388 });
389 req->url = "/";
390 req->set("Connection", "keep-alive");
391 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
393 });
394 req->url = "/index.html";
395 req->set("Connection", "keep-alive");
396 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
398 });
399 req->url = "/";
400 req->set("Connection", "keep-alive");
401 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
403 });
404 req->url = "/index.html";
405 req->set("Connection", "keep-alive");
406 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
408 });
409 req->url = "/";
410 req->set("Connection", "keep-alive");
411 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
413 });
414 req->url = "/index.html";
415 req->set("Connection", "keep-alive");
416 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
418 });
419 req->url = "/";
420 req->set("Connection", "keep-alive");
421 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
423 });
424 req->url = "/index.html";
425 req->set("Connection", "keep-alive");
426 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
428 });
429 req->url = "/";
430 req->set("Connection", "close");
431 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
433 });
434 },
435 []([[maybe_unused]] const std::shared_ptr<Request>& req) {
436 VLOG(1) << req->getSocketContext()->getSocketConnection()->getConnectionName() << ": OnRequestEnd";
437 });
438
439 client.setOnConnect([](SocketConnection* socketConnection) {
440 VLOG(1) << "OnConnect " << socketConnection->getConnectionName();
441
442 VLOG(1) << "\tLocal: " << socketConnection->getLocalAddress().toString();
443 VLOG(1) << "\tPeer: " << socketConnection->getRemoteAddress().toString();
444
445
446
447
448
449
450
451
452
453 });
454
455 client.setOnConnected([](SocketConnection* socketConnection) {
456 VLOG(1) << socketConnection->getConnectionName() << ": OnConnected";
457 X509* server_cert = SSL_get_peer_certificate(socketConnection->getSSL());
458 if (server_cert != nullptr) {
459 long verifyErr = SSL_get_verify_result(socketConnection->getSSL());
460
461 VLOG(1) << "\tPeer certificate verifyErr = " + std::to_string(verifyErr) + ": " +
462 std::string(X509_verify_cert_error_string(verifyErr));
463
464 char* str = X509_NAME_oneline(X509_get_subject_name(server_cert), nullptr, 0);
465 VLOG(1) << "\t Subject: " + std::string(str);
466 OPENSSL_free(str);
467
468 str = X509_NAME_oneline(X509_get_issuer_name(server_cert), nullptr, 0);
469 VLOG(1) << "\t Issuer: " + std::string(str);
470 OPENSSL_free(str);
471
472
473
474 GENERAL_NAMES* subjectAltNames =
475 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr));
476#ifdef __GNUC__
477#pragma GCC diagnostic push
478#ifdef __has_warning
479#if __has_warning("-Wused-but-marked-unused")
480#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
481#endif
482#endif
483#endif
484 int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
485#ifdef __GNUC_
486#pragma GCC diagnostic pop
487#endif
488 VLOG(1) << "\t Subject alternative name count: " << altNameCount;
489 for (int32_t i = 0; i < altNameCount; ++i) {
490#ifdef __GNUC__
491#pragma GCC diagnostic push
492#ifdef __has_warning
493#if __has_warning("-Wused-but-marked-unused")
494#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
495#endif
496#endif
497#endif
498 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
499#ifdef __GNUC_
500#pragma GCC diagnostic pop
501#endif
502 if (generalName->type == GEN_URI) {
503 std::string subjectAltName =
504 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
505 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
506 VLOG(1) << "\t SAN (URI): '" + subjectAltName;
507 } else if (generalName->type == GEN_DNS) {
508 std::string subjectAltName =
509 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
510 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
511 VLOG(1) << "\t SAN (DNS): '" + subjectAltName;
512 } else {
513 VLOG(1) << "\t SAN (Type): '" + std::to_string(generalName->type);
514 }
515 }
516#ifdef __GNUC__
517#pragma GCC diagnostic push
518#ifdef __has_warning
519#if __has_warning("-Wused-but-marked-unused")
520#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
521#endif
522#endif
523#endif
524 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
525#ifdef __GNUC_
526#pragma GCC diagnostic pop
527#endif
528 X509_free(server_cert);
529 } else {
530 VLOG(1) << "\tPeer certificate: no certificate";
531 }
532 });
533
534 client.setOnDisconnect([](SocketConnection* socketConnection) {
535 VLOG(1) << socketConnection->getConnectionName() << ": OnDisconnect";
536
537 VLOG(1) << "\tLocal: " << socketConnection->getLocalAddress().toString();
538 VLOG(1) << "\tPeer: " << socketConnection->getRemoteAddress().toString();
539 });
540
541 return client;
542 }
static void logResponse(const std::shared_ptr< web::http::client::Request > &req, const std::shared_ptr< web::http::client::Response > &res)
web::http::tls::NET::Client Client