Loading src/api/JsonApiServer.cpp +418 −175 File changed.Preview size limit exceeded, changes collapsed. Show changes src/api/JsonApiServer.h +6 −2 Changes for src/api/JsonApiServer.h: 6 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include "../config/BootstrapConfig.h" #include "../lb/LoadBalancer.h" #include "../store/ConfigStore.h" #include "../tls/CertificateManager.h" namespace proxyplus::api { Loading @@ -28,7 +29,8 @@ public: store::ConfigStore &configStore, auth::IAuthService &authService, lb::LoadBalancer &loadBalancer, cluster::ClusterManager *clusterManager); // nullptr in single-node mode cluster::ClusterManager *clusterManager, // nullptr in single-node mode tls::CertificateManager &certManager); void RequestEvent(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args) override; Loading Loading @@ -63,6 +65,7 @@ private: auth::IAuthService &_authService; lb::LoadBalancer &_loadBalancer; cluster::ClusterManager *_clusterManager; tls::CertificateManager &_certManager; }; // Binds at construction time, same rationale as HttpProxyServer/SmtpProxyServer. Loading @@ -71,7 +74,7 @@ public: JsonApiServer(config::AppConfig cfg, std::string staticDir, std::string certPath, std::string keyPath, store::ConfigStore &configStore, auth::IAuthService &authService, lb::LoadBalancer &loadBalancer, cluster::ClusterManager *clusterManager); cluster::ClusterManager *clusterManager, tls::CertificateManager &certManager); void run(); bool reloadCertificates(const std::string &certPath, const std::string &keyPath) { Loading @@ -86,6 +89,7 @@ private: auth::IAuthService &_authService; lb::LoadBalancer &_loadBalancer; cluster::ClusterManager *_clusterManager; tls::CertificateManager &_certManager; }; } // namespace proxyplus::api src/main.cpp +1 −1 Changes for src/main.cpp: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -259,7 +259,7 @@ int main(int argc, char **argv) { auto jsonApi = std::make_unique<proxyplus::api::JsonApiServer>( cfg, staticDir, certPathFor(cfg, cfg.adminTlsProfile), keyPathFor(cfg, cfg.adminTlsProfile), configStore, authService, loadBalancer, clusterManager.get()); configStore, authService, loadBalancer, clusterManager.get(), certManager); if (!cfg.adminTlsProfile.empty()) { auto *server = jsonApi.get(); std::string profile = cfg.adminTlsProfile; Loading src/tls/CertificateManager.cpp +22 −0 Changes for src/tls/CertificateManager.cpp: 22 added lines, 0 removed lines. Original line number Diff line number Diff line #include "CertificateManager.h" #include <algorithm> #include <chrono> #include <cstdio> #include <ctime> Loading Loading @@ -225,6 +226,27 @@ void CertificateManager::provisionSelfSigned() { } } void CertificateManager::reconcile(const std::string &profile) { auto profiles = _configStore.listTlsProfiles(); auto it = std::find_if(profiles.begin(), profiles.end(), [&](const auto &p) { return p.profile == profile; }); if (it == profiles.end()) return; if (it->acmeEnabled) { renew(*it); } else if (it->selfSigned) { generateSelfSigned(*it); } else { materializeManualCert(*it); } } void CertificateManager::removeCert(const std::string &profile) { std::string dir = _cfg.dataPath + "/tls"; ::remove((dir + "/" + profile + ".crt").c_str()); ::remove((dir + "/" + profile + ".key").c_str()); } void CertificateManager::checkLoop() { while (_running.load()) { for (const auto &rec : _configStore.listTlsProfiles()) { Loading src/tls/CertificateManager.h +16 −0 Changes for src/tls/CertificateManager.h: 16 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,22 @@ public: // profile's cert must already exist on disk by the time binding starts. void provisionSelfSigned(); // Immediately reconciles one profile against its current ConfigStore record -- called by // JsonApiServer right after a POST /api/v1/tls/profiles write, instead of leaving it to // checkLoop()'s next tick (up to kCheckIntervalSeconds away). Unlike checkLoop(), this // always acts rather than gating on needsRenewal(): an edited domains list or ACME // setting needs to take effect now, not just once the old cert happens to be expiring. // No-op if the profile doesn't exist (e.g. raced with a delete). void reconcile(const std::string &profile); // Removes a deleted profile's on-disk cert/key -- best-effort hygiene so an unmanaged // private key doesn't linger once its record is gone. Called by JsonApiServer's // DELETE /api/v1/tls/profiles handler. Any listener that still has the cert loaded in // memory from its own static tls_profile in YAML is unaffected either way -- listeners // bind once at startup (see docs/ARCHITECTURE.md), so this was never going to hot-unplug // a running listener's TLS without a restart. void removeCert(const std::string &profile); void start(); void stop(); Loading Loading
src/api/JsonApiServer.cpp +418 −175 File changed.Preview size limit exceeded, changes collapsed. Show changes
src/api/JsonApiServer.h +6 −2 Changes for src/api/JsonApiServer.h: 6 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include "../config/BootstrapConfig.h" #include "../lb/LoadBalancer.h" #include "../store/ConfigStore.h" #include "../tls/CertificateManager.h" namespace proxyplus::api { Loading @@ -28,7 +29,8 @@ public: store::ConfigStore &configStore, auth::IAuthService &authService, lb::LoadBalancer &loadBalancer, cluster::ClusterManager *clusterManager); // nullptr in single-node mode cluster::ClusterManager *clusterManager, // nullptr in single-node mode tls::CertificateManager &certManager); void RequestEvent(libhttppp::HttpRequest &curreq, const int tid, ULONG_PTR args) override; Loading Loading @@ -63,6 +65,7 @@ private: auth::IAuthService &_authService; lb::LoadBalancer &_loadBalancer; cluster::ClusterManager *_clusterManager; tls::CertificateManager &_certManager; }; // Binds at construction time, same rationale as HttpProxyServer/SmtpProxyServer. Loading @@ -71,7 +74,7 @@ public: JsonApiServer(config::AppConfig cfg, std::string staticDir, std::string certPath, std::string keyPath, store::ConfigStore &configStore, auth::IAuthService &authService, lb::LoadBalancer &loadBalancer, cluster::ClusterManager *clusterManager); cluster::ClusterManager *clusterManager, tls::CertificateManager &certManager); void run(); bool reloadCertificates(const std::string &certPath, const std::string &keyPath) { Loading @@ -86,6 +89,7 @@ private: auth::IAuthService &_authService; lb::LoadBalancer &_loadBalancer; cluster::ClusterManager *_clusterManager; tls::CertificateManager &_certManager; }; } // namespace proxyplus::api
src/main.cpp +1 −1 Changes for src/main.cpp: 1 added line, 1 removed line. Original line number Diff line number Diff line Loading @@ -259,7 +259,7 @@ int main(int argc, char **argv) { auto jsonApi = std::make_unique<proxyplus::api::JsonApiServer>( cfg, staticDir, certPathFor(cfg, cfg.adminTlsProfile), keyPathFor(cfg, cfg.adminTlsProfile), configStore, authService, loadBalancer, clusterManager.get()); configStore, authService, loadBalancer, clusterManager.get(), certManager); if (!cfg.adminTlsProfile.empty()) { auto *server = jsonApi.get(); std::string profile = cfg.adminTlsProfile; Loading
src/tls/CertificateManager.cpp +22 −0 Changes for src/tls/CertificateManager.cpp: 22 added lines, 0 removed lines. Original line number Diff line number Diff line #include "CertificateManager.h" #include <algorithm> #include <chrono> #include <cstdio> #include <ctime> Loading Loading @@ -225,6 +226,27 @@ void CertificateManager::provisionSelfSigned() { } } void CertificateManager::reconcile(const std::string &profile) { auto profiles = _configStore.listTlsProfiles(); auto it = std::find_if(profiles.begin(), profiles.end(), [&](const auto &p) { return p.profile == profile; }); if (it == profiles.end()) return; if (it->acmeEnabled) { renew(*it); } else if (it->selfSigned) { generateSelfSigned(*it); } else { materializeManualCert(*it); } } void CertificateManager::removeCert(const std::string &profile) { std::string dir = _cfg.dataPath + "/tls"; ::remove((dir + "/" + profile + ".crt").c_str()); ::remove((dir + "/" + profile + ".key").c_str()); } void CertificateManager::checkLoop() { while (_running.load()) { for (const auto &rec : _configStore.listTlsProfiles()) { Loading
src/tls/CertificateManager.h +16 −0 Changes for src/tls/CertificateManager.h: 16 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -40,6 +40,22 @@ public: // profile's cert must already exist on disk by the time binding starts. void provisionSelfSigned(); // Immediately reconciles one profile against its current ConfigStore record -- called by // JsonApiServer right after a POST /api/v1/tls/profiles write, instead of leaving it to // checkLoop()'s next tick (up to kCheckIntervalSeconds away). Unlike checkLoop(), this // always acts rather than gating on needsRenewal(): an edited domains list or ACME // setting needs to take effect now, not just once the old cert happens to be expiring. // No-op if the profile doesn't exist (e.g. raced with a delete). void reconcile(const std::string &profile); // Removes a deleted profile's on-disk cert/key -- best-effort hygiene so an unmanaged // private key doesn't linger once its record is gone. Called by JsonApiServer's // DELETE /api/v1/tls/profiles handler. Any listener that still has the cert loaded in // memory from its own static tls_profile in YAML is unaffected either way -- listeners // bind once at startup (see docs/ARCHITECTURE.md), so this was never going to hot-unplug // a running listener's TLS without a restart. void removeCert(const std::string &profile); void start(); void stop(); Loading