in extensions/civetweb/processors/ListenHTTP.cpp [41:171]
void ListenHTTP::onSchedule(core::ProcessContext *context, core::ProcessSessionFactory* /*sessionFactory*/) {
std::string basePath;
if (!context->getProperty(BasePath, basePath)) {
static_assert(BasePath.default_value);
logger_->log_info("%s attribute is missing, so default value of %s will be used", std::string(BasePath.name), std::string(*BasePath.default_value));
basePath = *BasePath.default_value;
}
basePath.insert(0, "/");
if (!context->getProperty(Port, listeningPort)) {
logger_->log_error("%s attribute is missing or invalid", std::string(Port.name));
return;
}
bool randomPort = listeningPort == "0";
std::string authDNPattern;
if (context->getProperty(AuthorizedDNPattern, authDNPattern) && !authDNPattern.empty()) {
logger_->log_debug("ListenHTTP using %s: %s", std::string(AuthorizedDNPattern.name), authDNPattern);
} else {
authDNPattern = ".*";
logger_->log_debug("Authorized DN Pattern not set or invalid, using default '%s' pattern", authDNPattern);
}
std::string sslCertFile;
if (context->getProperty(SSLCertificate, sslCertFile) && !sslCertFile.empty()) {
logger_->log_debug("ListenHTTP using %s: %s", std::string(SSLCertificate.name), sslCertFile);
}
// Read further TLS/SSL options only if TLS/SSL usage is implied by virtue of certificate value being set
std::string sslCertAuthorityFile;
std::string sslVerifyPeer;
std::string sslMinVer;
if (!sslCertFile.empty()) {
if (context->getProperty(SSLCertificateAuthority, sslCertAuthorityFile) && !sslCertAuthorityFile.empty()) {
logger_->log_debug("ListenHTTP using %s: %s", std::string(SSLCertificateAuthority.name), sslCertAuthorityFile);
}
if (context->getProperty(SSLVerifyPeer, sslVerifyPeer)) {
if (sslVerifyPeer.empty() || sslVerifyPeer == "no") {
logger_->log_debug("ListenHTTP will not verify peers");
} else {
logger_->log_debug("ListenHTTP will verify peers");
}
} else {
logger_->log_debug("ListenHTTP will not verify peers");
}
if (context->getProperty(SSLMinimumVersion, sslMinVer)) {
logger_->log_debug("ListenHTTP using %s: %s", std::string(SSLMinimumVersion.name), sslMinVer);
}
}
std::string headersAsAttributesPattern;
if (context->getProperty(HeadersAsAttributesRegex, headersAsAttributesPattern) && !headersAsAttributesPattern.empty()) {
logger_->log_debug("ListenHTTP using %s: %s", std::string(HeadersAsAttributesRegex.name), headersAsAttributesPattern);
}
auto numThreads = getMaxConcurrentTasks();
logger_->log_info("ListenHTTP starting HTTP server on port %s and path %s with %d threads", randomPort ? "random" : listeningPort, basePath, numThreads);
// Initialize web server
std::vector<std::string> options;
options.emplace_back("enable_keep_alive");
options.emplace_back("yes");
options.emplace_back("keep_alive_timeout_ms");
options.emplace_back("15000");
options.emplace_back("num_threads");
options.emplace_back(std::to_string(numThreads));
if (sslCertFile.empty()) {
options.emplace_back("listening_ports");
options.emplace_back(listeningPort);
} else {
listeningPort += "s";
options.emplace_back("listening_ports");
options.emplace_back(listeningPort);
options.emplace_back("ssl_certificate");
options.emplace_back(sslCertFile);
if (!sslCertAuthorityFile.empty()) {
options.emplace_back("ssl_ca_file");
options.emplace_back(sslCertAuthorityFile);
}
if (sslVerifyPeer.empty() || sslVerifyPeer == "no") {
options.emplace_back("ssl_verify_peer");
options.emplace_back("no");
} else {
options.emplace_back("ssl_verify_peer");
options.emplace_back("yes");
}
if (sslMinVer == "TLS1.2") {
options.emplace_back("ssl_protocol_version");
options.emplace_back(std::to_string(4));
} else {
throw minifi::Exception(ExceptionType::PROCESSOR_EXCEPTION, "Invalid SSL Minimum Version specified!");
}
}
server_ = std::make_unique<CivetServer>(options, &callbacks_, &logger_);
context->getProperty(BatchSize, batch_size_);
logger_->log_debug("ListenHTTP using %s: %zu", std::string(BatchSize.name), batch_size_);
handler_ = std::make_unique<Handler>(basePath, context, std::move(authDNPattern),
headersAsAttributesPattern.empty() ? std::nullopt : std::make_optional<utils::Regex>(headersAsAttributesPattern));
server_->addHandler(basePath, handler_.get());
if (randomPort) {
const auto& vec = server_->getListeningPorts();
if (vec.size() != 1) {
logger_->log_error("Random port is set, but there is no listening port! Server most probably failed to start!");
} else {
bool is_secure = isSecure();
listeningPort = std::to_string(vec[0]);
if (is_secure) {
listeningPort += "s";
}
logger_->log_info("Listening on port %s", listeningPort);
}
}
}