360 {
362 "httpclient",
363 [](const std::shared_ptr<Request>& req) {
364 VLOG(1) << req->getSocketContext()->getSocketConnection()->getConnectionName() << ": OnRequestStart";
365
366 req->url = "/";
367 req->set("Connection", "keep-alive");
368 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
370 });
371 req->url = "/";
372 req->set("Connection", "keep-alive");
373 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
375 });
376 req->url = "/index.html";
377 req->set("Connection", "keep-alive");
378 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
380 });
381 req->url = "/";
382 req->set("Connection", "keep-alive");
383 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
385 });
386 req->url = "/index.html";
387 req->set("Connection", "keep-alive");
388 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
390 });
391 req->url = "/";
392 req->set("Connection", "keep-alive");
393 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
395 });
396 req->url = "/index.html";
397 req->set("Connection", "keep-alive");
398 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
400 });
401 req->url = "/";
402 req->set("Connection", "keep-alive");
403 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
405 });
406 req->url = "/index.html";
407 req->set("Connection", "keep-alive");
408 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
410 });
411 req->url = "/";
412 req->set("Connection", "keep-alive");
413 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
415 });
416 req->url = "/index.html";
417 req->set("Connection", "keep-alive");
418 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
420 });
421 req->url = "/";
422 req->set("Connection", "keep-alive");
423 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
425 });
426 req->url = "/index.html";
427 req->set("Connection", "keep-alive");
428 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
430 });
431 req->url = "/";
432 req->set("Connection", "keep-alive");
433 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
435 });
436 req->url = "/index.html";
437 req->set("Connection", "keep-alive");
438 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
440 });
441 req->url = "/";
442 req->set("Connection", "keep-alive");
443 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
445 });
446 req->url = "/index.html";
447 req->set("Connection", "keep-alive");
448 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
450 });
451 req->url = "/";
452 req->set("Connection", "close");
453 req->end([](const std::shared_ptr<Request>& req, const std::shared_ptr<Response>& res) {
455 });
456 },
457 []([[maybe_unused]] const std::shared_ptr<Request>& req) {
458 VLOG(1) << req->getSocketContext()->getSocketConnection()->getConnectionName() << ": OnRequestEnd";
459 });
460
461 client.setOnConnect([](SocketConnection* socketConnection) {
462 VLOG(1) << "OnConnect " << socketConnection->getConnectionName();
463
464 VLOG(1) << "\tLocal: " << socketConnection->getLocalAddress().toString();
465 VLOG(1) << "\tPeer: " << socketConnection->getRemoteAddress().toString();
466
467
468
469
470
471
472
473
474
475 });
476
477 client.setOnConnected([](SocketConnection* socketConnection) {
478 VLOG(1) << socketConnection->getConnectionName() << ": OnConnected";
479 X509* server_cert = SSL_get_peer_certificate(socketConnection->getSSL());
480 if (server_cert != nullptr) {
481 long verifyErr = SSL_get_verify_result(socketConnection->getSSL());
482
483 VLOG(1) << "\tPeer certificate verifyErr = " + std::to_string(verifyErr) + ": " +
484 std::string(X509_verify_cert_error_string(verifyErr));
485
486 char* str = X509_NAME_oneline(X509_get_subject_name(server_cert), nullptr, 0);
487 VLOG(1) << "\t Subject: " + std::string(str);
488 OPENSSL_free(str);
489
490 str = X509_NAME_oneline(X509_get_issuer_name(server_cert), nullptr, 0);
491 VLOG(1) << "\t Issuer: " + std::string(str);
492 OPENSSL_free(str);
493
494
495
496 GENERAL_NAMES* subjectAltNames =
497 static_cast<GENERAL_NAMES*>(X509_get_ext_d2i(server_cert, NID_subject_alt_name, nullptr, nullptr));
498#ifdef __GNUC__
499#pragma GCC diagnostic push
500#ifdef __has_warning
501#if __has_warning("-Wused-but-marked-unused")
502#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
503#endif
504#endif
505#endif
506 int32_t altNameCount = sk_GENERAL_NAME_num(subjectAltNames);
507#ifdef __GNUC_
508#pragma GCC diagnostic pop
509#endif
510 VLOG(1) << "\t Subject alternative name count: " << altNameCount;
511 for (int32_t i = 0; i < altNameCount; ++i) {
512#ifdef __GNUC__
513#pragma GCC diagnostic push
514#ifdef __has_warning
515#if __has_warning("-Wused-but-marked-unused")
516#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
517#endif
518#endif
519#endif
520 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(subjectAltNames, i);
521#ifdef __GNUC_
522#pragma GCC diagnostic pop
523#endif
524 if (generalName->type == GEN_URI) {
525 std::string subjectAltName =
526 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.uniformResourceIdentifier)),
527 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.uniformResourceIdentifier)));
528 VLOG(1) << "\t SAN (URI): '" + subjectAltName;
529 } else if (generalName->type == GEN_DNS) {
530 std::string subjectAltName =
531 std::string(reinterpret_cast<const char*>(ASN1_STRING_get0_data(generalName->d.dNSName)),
532 static_cast<std::size_t>(ASN1_STRING_length(generalName->d.dNSName)));
533 VLOG(1) << "\t SAN (DNS): '" + subjectAltName;
534 } else {
535 VLOG(1) << "\t SAN (Type): '" + std::to_string(generalName->type);
536 }
537 }
538#ifdef __GNUC__
539#pragma GCC diagnostic push
540#ifdef __has_warning
541#if __has_warning("-Wused-but-marked-unused")
542#pragma GCC diagnostic ignored "-Wused-but-marked-unused"
543#endif
544#endif
545#endif
546 sk_GENERAL_NAME_pop_free(subjectAltNames, GENERAL_NAME_free);
547#ifdef __GNUC_
548#pragma GCC diagnostic pop
549#endif
550 X509_free(server_cert);
551 } else {
552 VLOG(1) << "\tPeer certificate: no certificate";
553 }
554 });
555
556 client.setOnDisconnect([](SocketConnection* socketConnection) {
557 VLOG(1) << socketConnection->getConnectionName() << ": OnDisconnect";
558
559 VLOG(1) << "\tLocal: " << socketConnection->getLocalAddress().toString();
560 VLOG(1) << "\tPeer: " << socketConnection->getRemoteAddress().toString();
561 });
562
563 return client;
564 }
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