void Option::LoadRootHdf(const IniSetting::Map& ini, const Hdf &roots, vector<string> &vec) { if (roots.exists()) { for (Hdf hdf = roots.firstChild(); hdf.exists(); hdf = hdf.next()) { vec.push_back(Config::GetString(ini, hdf,"")); } } }
bool TestCppBase::TestCollectionHdf() { IniSetting::Map ini = IniSetting::Map::object; Hdf hdf; hdf.fromString( " Server {\n" " AllowedDirectories.* = /var/www\n" " AllowedDirectories.* = /usr/bin\n" " HighPriorityEndPoints.* = /end\n" " HighPriorityEndPoints.* = /point\n" " HighPriorityEndPoints.* = /power\n" " }\n" ); RuntimeOption::AllowedDirectories.clear(); Config::Bind(RuntimeOption::AllowedDirectories, ini, hdf, "Server.AllowedDirectories"); VERIFY(RuntimeOption::AllowedDirectories.size() == 2); std::vector<std::string> ad = Config::GetVector(ini, hdf, "Server.AllowedDirectories", RuntimeOption::AllowedDirectories); VERIFY(RuntimeOption::AllowedDirectories.size() == 2); VERIFY(ad.size() == 2); Config::Bind(RuntimeOption::ServerHighPriorityEndPoints, ini, hdf, "Server.HighPriorityEndPoints"); VERIFY(RuntimeOption::ServerHighPriorityEndPoints.size() == 3); return Count(true); }
void ReplayTransport::recordInput(Transport* transport, const char *filename) { ASSERT(transport); Hdf hdf; hdf["thread"] = (int64)pthread_self(); hdf["get"] = (transport->getMethod() == GET); hdf["url"] = transport->getUrl(); hdf["remote_host"] = transport->getRemoteHost(); transport->getHeaders(m_requestHeaders); int index = 0; for (HeaderMap::const_iterator iter = m_requestHeaders.begin(); iter != m_requestHeaders.end(); ++iter) { for (unsigned int i = 0; i < iter->second.size(); i++) { Hdf header = hdf["headers"][index++]; header["name"] = iter->first; header["value"] = iter->second[i]; } } int size; const void *data = transport->getPostData(size); if (size) { int len; char *encoded = string_uuencode((const char *)data, size, len); hdf["post"] = encoded; free(encoded); } else { hdf["post"] = ""; } hdf.write(filename); }
void Option::LoadRootHdf(const Hdf &roots, map<string, string> &map) { if (roots.exists()) { for (Hdf hdf = roots.firstChild(); hdf.exists(); hdf = hdf.next()) { map[hdf["root"].get()] = hdf["path"].get(); } } }
bool Hdf::lintImpl(std::vector<std::string> &names, const std::vector<std::string> &excludes, bool visited) { unsigned int size = names.size(); bool childVisited = false; for (Hdf hdf = firstChild(false); hdf.exists(); hdf = hdf.next(false)) { if (hdf.lintImpl(names, excludes, visited)) { childVisited = true; } } bool meVisited = childVisited || hdf_is_visited(getRaw()); std::string fullname = getFullPath(); if (!fullname.empty()) { if (meVisited == visited) { bool excluded = false; for (unsigned int i = 0; i < excludes.size(); i++) { if (match(fullname, excludes[i])) { excluded = true; break; } } if (!excluded) { if (!visited) { names.resize(size); // so reports about my children are gone } names.push_back(fullname); } } } return meVisited; }
void Hdf::configGet(std::map<std::string, std::string, stdltistr> &values) const { values.clear(); for (Hdf hdf = firstChild(); hdf.exists(); hdf = hdf.next()) { values[hdf.getName()] = hdf.configGetString(""); } }
void Option::LoadRootHdf(const IniSetting::Map& ini, const Hdf &roots, map<string, string> &map) { if (roots.exists()) { for (Hdf hdf = roots.firstChild(); hdf.exists(); hdf = hdf.next()) { map[Config::Get(ini, hdf["root"])] = Config::Get(ini, hdf["path"]); } } }
void ReplayTransport::replayInputImpl() { String postData = StringUtil::UUDecode(m_hdf["post"].get("")); m_postData = string(postData.data(), postData.size()); m_requestHeaders.clear(); for (Hdf hdf = m_hdf["headers"].firstChild(); hdf.exists(); hdf = hdf.next()) { m_requestHeaders[hdf["name"].get("")].push_back(hdf["value"].get("")); } }
void IpBlockMap::LoadIpList(hphp_string_map<bool> &ips, Hdf hdf, bool allow) { for (Hdf child = hdf.firstChild(); child.exists(); child = child.next()) { string ip = child.getString(); size_t pos = ip.find('/'); if (pos != string::npos) { ip = ip.substr(0, pos); } ips[ip] = allow; } }
bool TestCppBase::TestSatelliteServer() { IniSetting::Map ini = IniSetting::Map::object; Hdf hdf; hdf.fromString( "Satellites {\n" " rpc {\n" " Type = RPCServer\n" " Port = 9999\n" " RequestInitDocument = my/rpc/rpc.php\n" " RequestInitFunction = init_me\n" " Password = abcd0987\n" " Passwords {\n" " * = abcd0987\n" " }\n" " }\n" " ips {\n" " Type = InternalPageServer\n" " BlockMainServer = false\n" " }\n" "}\n" ); std::vector<std::shared_ptr<SatelliteServerInfo>> infos; RuntimeOption::ReadSatelliteInfo(ini, hdf, infos, RuntimeOption::XboxPassword, RuntimeOption::XboxPasswords); for (auto& info_ptr : infos) { auto info = info_ptr.get(); auto name = info->getName(); if (name == "rpc") { VERIFY(info->getType() == SatelliteServer::Type::KindOfRPCServer); VERIFY(info->getPort() == 9999); VERIFY(info->getThreadCount() == 5); VERIFY(info->getTimeoutSeconds() == std::chrono::seconds(RuntimeOption::RequestTimeoutSeconds)); VERIFY(info->getURLs().size() == 0); VERIFY(info->getMaxRequest() == 500); VERIFY(info->getMaxDuration() == 120); VERIFY(info->getReqInitFunc() == "init_me"); VERIFY(info->getReqInitDoc() == "my/rpc/rpc.php"); VERIFY(info->getPassword() == "abcd0987"); VERIFY(info->getPasswords().size() == 1); VERIFY(info->getPasswords().find("abcd0987") != info->getPasswords().end()); VERIFY(info->alwaysReset() == false); VERIFY(RuntimeOption::XboxPassword == "abcd0987"); } else if (name == "ips") { VERIFY(info->getType() == SatelliteServer::Type::KindOfInternalPageServer); VERIFY(info->getURLs().size() == 0); } } return Count(true); }
void Option::LoadRootHdf(const IniSetting::Map& ini, const Hdf &roots, const std::string& name, std::map<std::string, std::string> &map) { if (roots.exists()) { for (Hdf hdf = roots[name].firstChild(); hdf.exists(); hdf = hdf.next()) { map[Config::Get(ini, hdf, "root", "", false)] = Config::Get(ini, hdf, "path", "", false); } } }
SatelliteServerInfo::SatelliteServerInfo(Hdf hdf) { m_name = hdf.getName(); m_port = hdf["Port"].getUInt16(0); m_threadCount = hdf["ThreadCount"].getInt32(5); m_maxRequest = hdf["MaxRequest"].getInt32(500); m_maxDuration = hdf["MaxDuration"].getInt32(120); m_timeoutSeconds = std::chrono::seconds (hdf["TimeoutSeconds"].getInt32(RuntimeOption::RequestTimeoutSeconds)); m_reqInitFunc = hdf["RequestInitFunction"].getString(""); m_reqInitDoc = hdf["RequestInitDocument"].getString(""); m_password = hdf["Password"].getString(""); hdf["Passwords"].get(m_passwords); m_alwaysReset = hdf["AlwaysReset"].getBool(false); std::string type = hdf["Type"].getString(); if (type == "InternalPageServer") { m_type = SatelliteServer::Type::KindOfInternalPageServer; std::vector<std::string> urls; hdf["URLs"].get(urls); for (unsigned int i = 0; i < urls.size(); i++) { m_urls.insert(format_pattern(urls[i], true)); } if (hdf["BlockMainServer"].getBool(true)) { InternalURLs.insert(m_urls.begin(), m_urls.end()); } } else if (type == "DanglingPageServer") { m_type = SatelliteServer::Type::KindOfDanglingPageServer; DanglingServerPort = m_port; } else if (type == "RPCServer") { m_type = SatelliteServer::Type::KindOfRPCServer; } else { m_type = SatelliteServer::Type::Unknown; } }
void Hdf::lint(std::vector<std::string> &names, const char *excludePatternNode /* = "LintExcludePatterns" */, bool visited /* = false */) { std::vector<std::string> patterns; if (excludePatternNode && *excludePatternNode) { for (Hdf hdf = operator[](excludePatternNode).firstChild(); hdf.exists(); hdf = hdf.next()) { std::string value = hdf.configGetString(); if (!value.empty()) { patterns.push_back(value); } } } lintImpl(names, patterns, visited); }
void Extension::LoadModules(Hdf hdf) { // Load up any dynamic extensions std::string path = hdf["DynamicExtensionPath"].getString("."); for (Hdf ext = hdf["DynamicExtensions"].firstChild(); ext.exists(); ext = ext.next()) { std::string extLoc = ext.getString(); if (extLoc.empty()) { continue; } if (extLoc[0] != '/') { extLoc = path + "/" + extLoc; } // Extensions are self-registering, // so we bring in the SO then // throw away its handle. void *ptr = dlopen(extLoc.c_str()); if (!ptr) { throw Exception("Could not open extension %s: %s", extLoc.c_str(), dlerror()); } auto getModule = (Extension *(*)())dlsym(ptr, "getModule"); if (!getModule) { throw Exception("Could not load extension %s: %s (%s)", extLoc.c_str(), "getModule() symbol not defined.", dlerror()); } Extension *mod = getModule(); if (mod->m_hhvmAPIVersion != HHVM_API_VERSION) { throw Exception("Could not use extension %s: " "Compiled with HHVM API Version %" PRId64 ", " "this version of HHVM expects %ld", extLoc.c_str(), mod->m_hhvmAPIVersion, HHVM_API_VERSION); } mod->setDSOName(extLoc); } // Invoke Extension::moduleLoad() callbacks assert(s_registered_extensions); for (ExtensionMap::const_iterator iter = s_registered_extensions->begin(); iter != s_registered_extensions->end(); ++iter) { iter->second->moduleLoad(hdf); } }
// Hdf takes precedence, as usual. No `ini` binding yet. void Config::Iterate(const IniSettingMap &ini, const Hdf &hdf, std::function<void (const IniSettingMap&, const Hdf&)> cb) { if (hdf.exists()) { for (Hdf c = hdf.firstChild(); c.exists(); c = c.next()) { cb(ini, c); } } else { auto ini_name = IniName(hdf); auto* ini_value = ini.get_ptr(ini_name); if (ini_value && ini_value->isObject()) { for (auto& val : ini_value->values()) { cb(val, hdf); } } } }
// No `ini` binding yet. Hdf still takes precedence but will be removed // once we have made all options ini-aware. All new settings should // use the ini path of this method (i.e., pass a bogus Hdf or keep it null) void Config::Iterate(std::function<void (const IniSettingMap&, const Hdf&, const std::string&)> cb, const IniSettingMap &ini, const Hdf& config, const std::string &name, const bool prepend_hhvm /* = true */) { // We shouldn't be passing a leaf here. That's why name is not // optional. assert(!name.empty()); Hdf hdf = config[name]; if (hdf.exists() && !hdf.isEmpty()) { for (Hdf c = hdf.firstChild(); c.exists(); c = c.next()) { cb(IniSetting::Map::object, c, ""); } } else { Hdf empty; auto ini_name = IniName(name, prepend_hhvm); auto* ini_value = ini_iterate(ini, ini_name); if (ini_value && ini_value->isObject()) { for (auto& pair : ini_value->items()) { cb(pair.second, empty, pair.first.data()); } } } }
void ReplayTransport::recordInput(Transport* transport, const char *filename) { assert(transport); Hdf hdf; char buf[32]; snprintf(buf, sizeof(buf), "%u", Process::GetProcessId()); hdf["pid"] = std::string(buf); #ifdef _MSC_VER snprintf(buf, sizeof(buf), "%" PRIx64, (int64_t)pthread_getw32threadid_np(Process::GetThreadId())); #else snprintf(buf, sizeof(buf), "%" PRIx64, (int64_t)Process::GetThreadId()); #endif hdf["tid"] = std::string(buf); snprintf(buf, sizeof(buf), "%u", Process::GetThreadPid()); hdf["tpid"] = std::string(buf); hdf["cmd"] = static_cast<int>(transport->getMethod()); hdf["url"] = transport->getUrl(); hdf["remote_host"] = transport->getRemoteHost(); hdf["remote_port"] = transport->getRemotePort(); transport->getHeaders(m_requestHeaders); int index = 0; for (HeaderMap::const_iterator iter = m_requestHeaders.begin(); iter != m_requestHeaders.end(); ++iter) { for (unsigned int i = 0; i < iter->second.size(); i++) { Hdf header = hdf["headers"][index++]; header["name"] = iter->first; header["value"] = iter->second[i]; } } int size; const void *data = transport->getPostData(size); if (size) { String encoded = string_uuencode((const char *)data, size); hdf["post"] = encoded.get()->data(); } else { hdf["post"] = ""; } hdf.write(filename); }
bool TestUtil::TestHDF() { // This was causing a crash { Hdf doc, node; node = doc["Node"]; } { Hdf doc; doc.fromString( "node.* {\n" " name = value\n" "}"); VS(doc["node"][0]["name"].getString(), "value"); } return Count(true); }
bool TestUtil::TestHDF() { // This was causing a crash { Hdf doc, node; node = doc["Node"]; } { IniSetting::Map ini = IniSetting::Map::object; Hdf doc; doc.fromString( "node.* {\n" " name = value\n" "}"); VS(Config::GetString(ini, doc, "node.0.name"), "value"); } return Count(true); }
const char* Config::Get(const IniSetting::Map &ini, const Hdf& config, const std::string& name /* = "" */, const char *defValue /* = nullptr */, const bool prepend_hhvm /* = true */) { auto ini_name = IniName(name, prepend_hhvm); Hdf hdf = name != "" ? config[name] : config; auto* value = ini_iterate(ini, ini_name); if (value && value->isString()) { // See generic Get##METHOD below for why we are doing this const char* ini_ret = value->data(); const char* hdf_ret = hdf.configGet(value->data()); if (hdf_ret != ini_ret) { ini_ret = hdf_ret; IniSetting::Set(ini_name, ini_ret); } return ini_ret; } return hdf.configGet(defValue); }
IpBlockMap::IpBlockMap(Hdf config) { for (Hdf hdf = config.firstChild(); hdf.exists(); hdf = hdf.next()) { AclPtr acl(new Acl()); bool allow = hdf["AllowFirst"].getBool(false); if (allow) { LoadIpList(acl->ips, hdf["Ip.Deny"], false); LoadIpList(acl->ips, hdf["Ip.Allow"], true); } else { LoadIpList(acl->ips, hdf["Ip.Allow"], true); LoadIpList(acl->ips, hdf["Ip.Deny"], false); } string location = hdf["Location"].getString(); if (!location.empty() && location[0] == '/') { location = location.substr(1); } m_acls[location] = acl; } }
void ReplayTransport::recordInput(Transport* transport, const char *filename) { ASSERT(transport); Hdf hdf; char buf[32]; snprintf(buf, sizeof(buf), "%u", Process::GetProcessId()); hdf["pid"] = string(buf); snprintf(buf, sizeof(buf), "%llx", (int64)Process::GetThreadId()); hdf["tid"] = string(buf); snprintf(buf, sizeof(buf), "%u", Process::GetThreadPid()); hdf["tpid"] = string(buf); hdf["cmd"] = transport->getMethod(); hdf["url"] = transport->getUrl(); hdf["remote_host"] = transport->getRemoteHost(); hdf["remote_port"] = transport->getRemotePort(); transport->getHeaders(m_requestHeaders); int index = 0; for (HeaderMap::const_iterator iter = m_requestHeaders.begin(); iter != m_requestHeaders.end(); ++iter) { for (unsigned int i = 0; i < iter->second.size(); i++) { Hdf header = hdf["headers"][index++]; header["name"] = iter->first; header["value"] = iter->second[i]; } } int size; const void *data = transport->getPostData(size); if (size) { int len; char *encoded = string_uuencode((const char *)data, size, len); hdf["post"] = encoded; free(encoded); } else { hdf["post"] = ""; } hdf.write(filename); }
// This method must return a char* which is owned by the IniSettingMap // to avoid issues with the lifetime of the char* const char* Config::Get(const IniSettingMap &ini, const Hdf& config, const std::string& name /* = "" */, const char *defValue /* = nullptr */, const bool prepend_hhvm /* = true */) { auto ini_name = IniName(name, prepend_hhvm); Hdf hdf = name != "" ? config[name] : config; auto value = ini_iterate(ini, ini_name); if (value.isString()) { // See generic Get##METHOD below for why we are doing this // Note that value is a string, so value.toString() is not // a temporary. const char* ini_ret = value.toString().data(); const char* hdf_ret = hdf.configGet(ini_ret); if (hdf_ret != ini_ret) { ini_ret = hdf_ret; IniSetting::SetSystem(ini_name, ini_ret); } return ini_ret; } return hdf.configGet(defValue); }
void IpBlockMap::LoadIpList(AclPtr acl, Hdf hdf, bool allow) { for (Hdf child = hdf.firstChild(); child.exists(); child = child.next()) { string ip = child.getString(); unsigned int start, end; if (ReadIPv4Address(ip.c_str(), start, end)) { ASSERT(end >= start); if (end - start < 1024) { for (unsigned int i = start; i <= end; i++) { acl->ips[i] = allow; } } else { acl->ranges.resize(acl->ranges.size() + 1); IpRange &range = acl->ranges.back(); range.start = start; range.end = end; range.allow = allow; } } } }
void Option::LoadRootHdf(const Hdf &roots, vector<string> &vec) { if (roots.exists()) { for (Hdf hdf = roots.firstChild(); hdf.exists(); hdf = hdf.next()) { vec.push_back(hdf.getString("")); } } }
void Config::Parse(const std::string &config, IniSetting::Map &ini, Hdf &hdf) { if (boost::ends_with(config, "ini")) { std::ifstream ifs(config); const std::string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); auto parsed_ini = IniSetting::FromStringAsMap(str, config); for (auto &pair : parsed_ini.items()) { ini[pair.first] = pair.second; } } else { hdf.append(config); } }
static bool matchHdfPattern(const std::string &value, Hdf hdfPattern) { string pattern = hdfPattern.getString(); if (!pattern.empty()) { Variant ret = preg_match(String(pattern.c_str(), pattern.size(), AttachLiteral), String(value.c_str(), value.size(), AttachLiteral)); if (ret.toInt64() <= 0) { return false; } } return true; }
FilesMatch::FilesMatch(const IniSetting::Map& ini, const Hdf& vh) { if (vh.exists()) { m_pattern = format_pattern(vh["pattern"].configGetString(), true); vh["headers"].configGet(m_headers); } else { m_pattern = format_pattern( ini[String("pattern")].toString().toCppString(), true ); for (ArrayIter iter(ini[String("headers")].toArray()); iter; ++iter) { m_headers.push_back(iter.second().toString().toCppString()); } } }
SatelliteServerInfo::SatelliteServerInfo(const IniSetting::Map& ini, Hdf hdf) { // Since this could be activated when calling fb_gen_user_func() or similar. // Those type of calls spawn async, and after extensions have // been loaded. // So, pretend extensions haven't been loaded for this PHP_INI_SYSTEM // setting and then stop pretending after these binds. // Something similar is being done in virtual-host.cpp as well. IniSetting::s_pretendExtensionsHaveNotBeenLoaded = true; m_name = hdf.getName(); Config::Bind(m_port, ini, hdf["Port"], 0); Config::Bind(m_threadCount, ini, hdf["ThreadCount"], 5); Config::Bind(m_maxRequest, ini, hdf["MaxRequest"], 500); Config::Bind(m_maxDuration, ini, hdf["MaxDuration"], 120); m_timeoutSeconds = std::chrono::seconds( Config::GetInt32(ini, hdf["TimeoutSeconds"], RuntimeOption::RequestTimeoutSeconds)); Config::Bind(m_reqInitFunc, ini, hdf["RequestInitFunction"], ""); Config::Bind(m_reqInitDoc, ini, hdf["RequestInitDocument"], ""); Config::Bind(m_password, ini, hdf["Password"], ""); Config::Get(ini, hdf["Passwords"], m_passwords); Config::Bind(m_alwaysReset, ini, hdf["AlwaysReset"], false); std::string type = Config::GetString(ini, hdf["Type"]); if (type == "InternalPageServer") { m_type = SatelliteServer::Type::KindOfInternalPageServer; std::vector<std::string> urls; Config::Get(ini, hdf["URLs"], urls); for (unsigned int i = 0; i < urls.size(); i++) { m_urls.insert(format_pattern(urls[i], true)); } if (Config::GetBool(ini, hdf["BlockMainServer"], true)) { InternalURLs.insert(m_urls.begin(), m_urls.end()); } } else if (type == "DanglingPageServer") { m_type = SatelliteServer::Type::KindOfDanglingPageServer; DanglingServerPort = m_port; } else if (type == "RPCServer") { m_type = SatelliteServer::Type::KindOfRPCServer; } else { m_type = SatelliteServer::Type::Unknown; } IniSetting::s_pretendExtensionsHaveNotBeenLoaded = false; }
void Config::Bind(std::vector<std::string>& loc, const IniSettingMap& ini, const Hdf& config) { std::vector<std::string> ret; auto ini_name = IniName(config); auto* value = ini.get_ptr(ini_name); if (value && value->isObject()) { ini_on_update(*value, ret); loc = ret; } // If there is an HDF setting for the config, then it still wins for // the RuntimeOption value until we obliterate HDFs ret.clear(); config.configGet(ret); if (ret.size() > 0) { loc = ret; } IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM, ini_name, &loc); }