diff --git a/include/KAccess.h b/include/KAccess.h index e84a855..b470df7 100644 --- a/include/KAccess.h +++ b/include/KAccess.h @@ -119,6 +119,7 @@ class KAccess final : public kconfig::KConfigListen friend class KTable; static std::map acl_factorys[2]; static std::map mark_factorys[2]; + static void remove_all_factorys(); static bool addAclModel(u_short type, KAcl* acl, bool replace = false); static bool addMarkModel(u_short type, KMark* acl, bool replace = false); static void build_action_attribute(KXmlAttribute& attribute, const KUrlValue& uv); diff --git a/include/KConfigTree.h b/include/KConfigTree.h index a74e1b9..fd89bf7 100644 --- a/include/KConfigTree.h +++ b/include/KConfigTree.h @@ -76,6 +76,7 @@ namespace kconfig { } virtual KConfigEventFlag config_flag() const = 0; + /* return false event will pass to parent node */ virtual bool on_config_event(KConfigTree* tree, KConfigEvent* ev) = 0; }; diff --git a/include/KVirtualHostContainer.h b/include/KVirtualHostContainer.h index d2ae281..ad7bb4d 100644 --- a/include/KVirtualHostContainer.h +++ b/include/KVirtualHostContainer.h @@ -153,6 +153,16 @@ class KVirtualHostContainer : public KAtomCountable auto lock = get_locker(); return root.find(domain); } + int get_bind_count() { + auto lock = get_locker(); + int result = count; + return result; + } + int get_total_bind_count() { + auto lock = get_locker(); + int result = total_count; + return result; + } void bind_vh(KVirtualHost* vh, bool high = false); void unbind_vh(KVirtualHost* vh); KLocker get_locker() { @@ -161,6 +171,8 @@ class KVirtualHostContainer : public KAtomCountable protected: ~KVirtualHostContainer(); private: + int count = 0; + int total_count = 0; KDomainMap root; KMutex lock; }; diff --git a/include/KVirtualHostManage.h b/include/KVirtualHostManage.h index fcaba8d..d2d2879 100644 --- a/include/KVirtualHostManage.h +++ b/include/KVirtualHostManage.h @@ -18,11 +18,10 @@ class KGTempleteVirtualHost; -class KVirtualHostManage : public kconfig::KConfigListen +class KVirtualHostManage final : public kconfig::KConfigListen { public: - KVirtualHostManage(); - virtual ~KVirtualHostManage(); + ~KVirtualHostManage(); void getMenuHtml(KWStream& s, KVirtualHost* vh, KStringBuf& url); void getHtml(KWStream& s, const KString& vh_name, int id, KUrlValue& attribute); bool vh_base_action(KUrlValue& attribute, KString& err_msg); @@ -52,7 +51,7 @@ class KVirtualHostManage : public kconfig::KConfigListen bool updateVirtualHost(kconfig::KConfigTree* ct, KVirtualHost* vh); bool updateVirtualHost(kconfig::KConfigTree* ct, KVirtualHost* vh, KVirtualHost* ov); //void updateVirtualHost(KVirtualHost* vh, std::list& hosts); - void updateVirtualHost(KVirtualHost* vh, std::list& binds); + //void updateVirtualHost(KVirtualHost* vh, std::list& binds); /* * Ôö¼ÓÐéÄâÖ÷»ú */ @@ -82,7 +81,9 @@ class KVirtualHostManage : public kconfig::KConfigListen static KFiberLocker locker() { return KFiberLocker(lock); } + static KVirtualHostManage* get_instance(); private: + KVirtualHostManage(); void getVhIndex(KWStream& s, KVirtualHost* vh, int id); bool internalAddVirtualHost(kconfig::KConfigTree* ct, KVirtualHost* vh, KVirtualHost* ov); bool internalRemoveVirtualHost(kconfig::KConfigTree* ct, KVirtualHost* vh); diff --git a/kasync b/kasync index 8ce1151..7ccbfa8 160000 --- a/kasync +++ b/kasync @@ -1 +1 @@ -Subproject commit 8ce11512f3db31d83e573282dd4736dcacab53f9 +Subproject commit 7ccbfa87e4824fef27f0327392402f02cf2a6cad diff --git a/src/KAccess.cpp b/src/KAccess.cpp index f3b071f..14bbdf1 100644 --- a/src/KAccess.cpp +++ b/src/KAccess.cpp @@ -181,6 +181,18 @@ void KAccess::clear() { bool KAccess::isGlobal() { return global_flag; } +void KAccess::remove_all_factorys() { + for (int i = 0; i < 2; ++i) { + for (auto it = acl_factorys[i].begin(); it != acl_factorys[i].end(); ++it) { + (*it).second->release(); + } + acl_factorys[i].clear(); + for (auto it = mark_factorys[i].begin(); it != mark_factorys[i].end(); ++it) { + (*it).second->release(); + } + mark_factorys[i].clear(); + } +} bool KAccess::addAclModel(u_short type, KAcl* m, bool replace) { if (type > 1) { m->add_ref(); diff --git a/src/KConfig.cpp b/src/KConfig.cpp index 949c764..8f5b1ac 100644 --- a/src/KConfig.cpp +++ b/src/KConfig.cpp @@ -136,7 +136,7 @@ KConfig::~KConfig() { } KGlobalConfig::KGlobalConfig() { gam = new KAcserverManager; - gvm = new KVirtualHostManage; + gvm = KVirtualHostManage::get_instance(); sysHost = new KVirtualHost("_SYS"); dem = NULL; select_count = 0; diff --git a/src/KDsoExtend.cpp b/src/KDsoExtend.cpp index 194ac2d..9e9d195 100644 --- a/src/KDsoExtend.cpp +++ b/src/KDsoExtend.cpp @@ -77,6 +77,7 @@ KDsoExtend::KDsoExtend(const char* name) { memset(&version, 0, sizeof(version)); } KDsoExtend::~KDsoExtend() { + dso.unload(); xfree(name); if (filename) { xfree(filename); @@ -84,6 +85,10 @@ KDsoExtend::~KDsoExtend() { if (orign_filename) { xfree(orign_filename); } + for (auto it = upstream.begin(); it != upstream.end(); ++it) { + (*it).second->release(); + } + upstream.clear(); } bool KDsoExtend::RegisterUpstream(kgl_upstream* us) { //global upstream always open after cache handle. diff --git a/src/KDynamicListen.cpp b/src/KDynamicListen.cpp index 9a70440..2a3cdca 100644 --- a/src/KDynamicListen.cpp +++ b/src/KDynamicListen.cpp @@ -524,6 +524,7 @@ static iterator_ret listen_html_iterator(void *data, void *argv) KListen *listen = (KListen *)data; KWStream *s = (KWStream*)argv; kserver *server = listen->server; + KVirtualHostContainer* vhd = (KVirtualHostContainer*)kserver_get_opaque(server); if (KBIT_TEST(listen->server->flags, KGL_SERVER_START)) { *s << ""; bool unix_socket = false; @@ -573,8 +574,12 @@ static iterator_ret listen_html_iterator(void *data, void *argv) } *s << "" << (int)listen->key->global; *s << "" << (int)listen->key->dynamic; - *s << "" << katom_get((void *)&server->refs); - *s << ""; + *s << "" << katom_get((void *)&server->refs) << ""; + *s << "" << vhd->get_bind_count() +#if 0 + << " " << vhd->get_total_bind_count() +#endif + << ""; *s << ""; } return iterator_continue; diff --git a/src/KHttpManage.cpp b/src/KHttpManage.cpp index 3827474..a148438 100644 --- a/src/KHttpManage.cpp +++ b/src/KHttpManage.cpp @@ -457,7 +457,7 @@ bool KHttpManage::config() { s << ""; s << "\n" << klang["success_listen"] << ":"; s << ""; + s << ""; conf.gvm->GetListenHtml(s); s << "
" << LANG_IP << "" << LANG_PORT; - s << "" << klang["listen_type"] << "" << klang["protocol"] << "flagsglobaldynamic" << LANG_REFS << "
" << klang["listen_type"] << "" << klang["protocol"] << "flagsglobaldynamic" << LANG_REFS << "bind
"; s << ""; diff --git a/src/KVirtualHost.cpp b/src/KVirtualHost.cpp index dbeb5f9..6776fe3 100644 --- a/src/KVirtualHost.cpp +++ b/src/KVirtualHost.cpp @@ -617,6 +617,9 @@ bool KVirtualHost::setSSLInfo(const KString& certfile, const KString& keyfile, c kgl_release_ssl_ctx(ssl_ctx); ssl_ctx = nullptr; } + if (cert_file.empty()) { + return false; + } ssl_ctx = refs_ssl_ctx(); if (ssl_ctx) { kgl_release_ssl_ctx(ssl_ctx); @@ -631,7 +634,7 @@ bool KVirtualHost::parse_xml(const khttpd::KXmlNodeBody* body, KVirtualHost* ov) envs.clear(); parseEnv(attr("envs")); setDocRoot(attr["doc_root"]); - browse = (attr["browse"] == "on" || attr["browse"]=="1"); + browse = (attr["browse"] == "on" || attr["browse"] == "1"); inherit = (attr["inherit"] == "on" || attr["inherit"] == "1"); setAccess(attr["access"]); @@ -698,19 +701,41 @@ bool KVirtualHost::parse_xml(const khttpd::KXmlNodeBody* body, KVirtualHost* ov) } //parse host auto host_xml = kconfig::find_child(body, _KS("host")); - if (!host_xml) { - return true; - } - for (uint32_t index = 0;; ++index) { - auto body = host_xml->get_body(index); - if (!body) { - break; + if (host_xml) { + for (uint32_t index = 0;; ++index) { + auto body = host_xml->get_body(index); + if (!body) { + break; + } + auto svh = parse_host(body); + if (!svh) { + continue; + } + hosts.push_back(svh); } - auto svh = parse_host(body); - if (!svh) { - continue; + } + //parse bind + auto bind_xml = kconfig::find_child(body, _KS("bind")); + if (bind_xml) { + for (uint32_t index = 0;; ++index) { + auto body = bind_xml->get_body(index); + if (!body) { + break; + } + auto bind = body->get_text(); + if (!bind) { + continue; + } + if (bind[0] == '!') { + binds.push_back(bind.substr(1)); + } else if (bind.find(':') != KString::npos) { + binds.push_back(bind); + } else { + KStringBuf s; + s << "*:" << bind; + binds.push_back(s.c_str()); + } } - hosts.push_back(svh); } return true; } @@ -748,6 +773,7 @@ bool KVirtualHost::on_config_event(kconfig::KConfigTree* tree, kconfig::KConfigE //[[fallthrough]] case kconfig::EvSubDir | kconfig::EvUpdate: { +#if 0 if (xml->is_tag(_KS("host"))) { /* notice parent xml tag event. */ return false; @@ -775,19 +801,29 @@ bool KVirtualHost::on_config_event(kconfig::KConfigTree* tree, kconfig::KConfigE } conf.gvm->updateVirtualHost(this, binds); return true; + + /* notice parent xml tag event. */ + //return false; } +#endif } break; case kconfig::EvSubDir | kconfig::EvRemove: +#if 0 if (xml->is_tag(_KS("host"))) { /* notice parent xml tag event. */ return false; } if (xml->is_tag(_KS("bind"))) { + //* std::list binds; conf.gvm->updateVirtualHost(this, binds); return true; + //*/ + /* notice parent xml tag event. */ + //return false; } +#endif break; } return false; diff --git a/src/KVirtualHostContainer.cpp b/src/KVirtualHostContainer.cpp index c11d65f..823791f 100644 --- a/src/KVirtualHostContainer.cpp +++ b/src/KVirtualHostContainer.cpp @@ -140,13 +140,18 @@ bool convert(const char* domain, bool& wide, domain_t buf, int buf_size) { void KVirtualHostContainer::bind_vh(KVirtualHost* vh, bool high) { auto lock = get_locker(); for (auto it2 = vh->hosts.begin(); it2 != vh->hosts.end(); ++it2) { - root.add((*it2)->bind_host, (*it2)->wide, high ? kgl_bind_high : kgl_bind_low, (*it2)); + if (root.add((*it2)->bind_host, (*it2)->wide, high ? kgl_bind_high : kgl_bind_low, (*it2))) { + ++count; + ++total_count; + } } } void KVirtualHostContainer::unbind_vh(KVirtualHost* vh) { auto lock = get_locker(); for (auto it2 = vh->hosts.begin(); it2 != vh->hosts.end(); ++it2) { - root.del((*it2)->bind_host, (*it2)->wide, (*it2)); + if (kgl_del_failed != root.del((*it2)->bind_host, (*it2)->wide, (*it2))) { + --count; + } } } bool KDomainMap::bind(const char* domain, void* vh, kgl_bind_level level) { diff --git a/src/KVirtualHostManage.cpp b/src/KVirtualHostManage.cpp index a61ba69..0033d04 100644 --- a/src/KVirtualHostManage.cpp +++ b/src/KVirtualHostManage.cpp @@ -43,6 +43,13 @@ void free_ssl_certifycate(void* arg) { KSslCertificate* cert = (KSslCertificate*)arg; delete cert; } +static KVirtualHostManage* vhm = nullptr; +KVirtualHostManage* KVirtualHostManage::get_instance() { + if (!vhm) { + vhm = new KVirtualHostManage(); + } + return vhm; +} bool KVirtualHostManage::on_config_event(kconfig::KConfigTree* tree, kconfig::KConfigEvent* ev) { auto xml = ev->get_xml(); switch (ev->type) { @@ -121,9 +128,7 @@ KVirtualHostManage::KVirtualHostManage() { } KVirtualHostManage::~KVirtualHostManage() { for (auto it4 = avh.begin(); it4 != avh.end(); it4++) { - if (this == conf.gvm) { - InternalUnBindVirtualHost((*it4).second); - } + InternalUnBindVirtualHost((*it4).second); (*it4).second->release(); } avh.clear(); @@ -279,7 +284,7 @@ bool KVirtualHostManage::updateVirtualHost(kconfig::KConfigTree* ct, KVirtualHos #ifdef ENABLE_VH_RUN_AS ov->need_kill_process = vh->caculateNeedKillProcess(ov); #endif - if (ov && this == conf.gvm) { + if (ov) { internalRemoveVirtualHost(ct, ov); } } @@ -287,7 +292,7 @@ bool KVirtualHostManage::updateVirtualHost(kconfig::KConfigTree* ct, KVirtualHos getAutoName(vh->name); } bool result = internalAddVirtualHost(ct, vh, ov); - if (ov && this == conf.gvm) { + if (ov) { InternalUnBindVirtualHost(ov); } return result; @@ -316,9 +321,7 @@ bool KVirtualHostManage::removeVirtualHost(kconfig::KConfigTree* ct, KVirtualHos vh->need_kill_process = 1; #endif bool result = internalRemoveVirtualHost(ct, vh); - if (this == conf.gvm) { - InternalUnBindVirtualHost(vh); - } + InternalUnBindVirtualHost(vh); return result; } bool KVirtualHostManage::internalAddVirtualHost(kconfig::KConfigTree* ct, KVirtualHost* vh, KVirtualHost* ov) { @@ -330,9 +333,7 @@ bool KVirtualHostManage::internalAddVirtualHost(kconfig::KConfigTree* ct, KVirtu klog(KLOG_ERR, "Cann't add VirtualHost [%s] name duplicate.\n", vh->name.c_str()); return false; } - if (this == conf.gvm) { - InternalBindVirtualHost(vh); - } + InternalBindVirtualHost(vh); avh.insert(pair(vh->name, vh)); vh->add_ref(); return true; @@ -353,7 +354,6 @@ bool KVirtualHostManage::internalRemoveVirtualHost(kconfig::KConfigTree* ct, KVi return false; } avh.erase(it); - kassert(this == conf.gvm); vh->release(); return true; } @@ -1084,7 +1084,7 @@ void KVirtualHostManage::updateVirtualHost(KVirtualHost* vh, std::list& binds) { auto vm_locker = locker(); InternalUnBindVirtualHost(vh); @@ -1094,6 +1094,7 @@ void KVirtualHostManage::updateVirtualHost(KVirtualHost* vh, std::list& } InternalBindVirtualHost(vh); } +*/ void KVirtualHostManage::InternalBindVirtualHost(KVirtualHost* vh) { #ifdef ENABLE_SVH_SSL if (ssl_config) { diff --git a/src/main.cpp b/src/main.cpp index af7cf14..a1f3e51 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -185,6 +185,7 @@ int clean_memory_leak_fiber(void* arg, int argc) { conf.sysHost->release(); packageManage.clean(); shutdown_http_server(); + KAccess::remove_all_factorys(); #ifndef HTTP_PROXY delete conf.gvm; delete conf.gam;