Example #1
0
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());
    }
  }
}
Example #2
0
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;
  }
}
Example #3
0
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;
}
Example #4
0
FilesMatch::FilesMatch(const IniSetting::Map& ini, Hdf vh) {
  m_pattern = format_pattern(Config::Get(ini, vh["pattern"], ""), true);
  Config::Get(ini, vh["headers"], m_headers);
}
Example #5
0
void VirtualHost::init(const IniSetting::Map& ini, Hdf vh) {
  m_name = vh.getName();

  const char *prefix = Config::Get(ini, vh, "Prefix", "", false);
  const char *pattern = Config::Get(ini, vh, "Pattern", "", false);
  const char *pathTranslation = Config::Get(ini, vh, "PathTranslation", "",
                                            false);

  if (prefix) m_prefix = prefix;
  if (pattern) {
    m_pattern = format_pattern(pattern, false);
    if (!m_pattern.empty()) {
      m_pattern += "i"; // case-insensitive
    }
  }
  if (pathTranslation) {
    m_pathTranslation = pathTranslation;
    if (!m_pathTranslation.empty() &&
        m_pathTranslation[m_pathTranslation.length() - 1] != '/') {
      m_pathTranslation += '/';
    }
  }

  initRuntimeOption(ini, vh); // overwrites

  m_disabled = Config::GetBool(ini, vh, "Disabled", false, false);

  m_checkExistenceBeforeRewrite =
    Config::GetBool(ini, vh, "CheckExistenceBeforeRewrite", true, false);

  for (Hdf hdf = vh["RewriteRules"].firstChild(); hdf.exists();
       hdf = hdf.next()) {
    RewriteRule dummy;
    m_rewriteRules.push_back(dummy);
    RewriteRule &rule = m_rewriteRules.back();
    rule.pattern = format_pattern(Config::GetString(ini, hdf, "pattern", "",
                                                    false),
                                  true);
    rule.to = Config::GetString(ini, hdf, "to", "", false);
    rule.qsa = Config::GetBool(ini, hdf, "qsa", false, false);
    rule.redirect = Config::GetInt16(ini, hdf, "redirect", 0, false);
    rule.encode_backrefs = Config::GetBool(ini, hdf, "encode_backrefs", false,
                                           false);

    if (rule.pattern.empty() || rule.to.empty()) {
      throw std::runtime_error("Invalid rewrite rule: (empty pattern or to)");
    }

    for (Hdf chdf = hdf["conditions"].firstChild(); chdf.exists();
         chdf = chdf.next()) {
      RewriteCond dummy;
      rule.rewriteConds.push_back(dummy);
      RewriteCond &cond = rule.rewriteConds.back();
      cond.pattern = format_pattern(Config::GetString(ini, chdf, "pattern", "",
                                                      false),
                                    true);
      if (cond.pattern.empty()) {
        throw std::runtime_error("Invalid rewrite rule: (empty cond pattern)");
      }
      const char *type = Config::Get(ini, chdf, "type", "", false);
      if (type) {
        if (strcasecmp(type, "host") == 0) {
          cond.type = RewriteCond::Type::Host;
        } else if (strcasecmp(type, "request") == 0) {
          cond.type = RewriteCond::Type::Request;
        } else {
          throw std::runtime_error("Invalid rewrite rule: (invalid "
            "cond type)");
        }
      } else {
        cond.type = RewriteCond::Type::Request;
      }
      cond.negate = Config::GetBool(ini, chdf, "negate", false, false);
    }

  }

  if (vh["IpBlockMap"].firstChild().exists()) {
    m_ipBlocks = std::make_shared<IpBlockMap>(ini, vh["IpBlockMap"]);
  }

  for (Hdf hdf = vh["LogFilters"].firstChild(); hdf.exists();
       hdf = hdf.next()) {
    QueryStringFilter filter;
    filter.urlPattern = format_pattern(Config::GetString(ini, hdf, "url", "",
                                                         false),
                                       true);
    filter.replaceWith = Config::GetString(ini, hdf, "value", "", false);
    filter.replaceWith = "\\1=" + filter.replaceWith;

    std::string pattern = Config::GetString(ini, hdf, "pattern", "", false);
    std::vector<std::string> names;
    names = Config::GetVector(ini, hdf, "params", names, false);

    if (pattern.empty()) {
      for (unsigned int i = 0; i < names.size(); i++) {
        if (pattern.empty()) {
          pattern = "(?<=[&\?])(";
        } else {
          pattern += "|";
        }
        pattern += names[i];
      }
      if (!pattern.empty()) {
        pattern += ")=.*?(?=(&|$))";
        pattern = format_pattern(pattern, false);
      }
    } else if (!names.empty()) {
      throw std::runtime_error("Invalid log filter: (cannot specify "
        "both params and pattern)");
    }

    filter.namePattern = pattern;
    m_queryStringFilters.push_back(filter);
  }

  m_serverVars = Config::GetMap(ini, vh, "ServerVariables", m_serverVars,
                                false);
  m_serverName = Config::GetString(ini, vh, "ServerName", m_serverName, false);
}
Example #6
0
FilesMatch::FilesMatch(Hdf vh) {
  m_pattern = format_pattern(vh["pattern"].get(""));
  vh["headers"].get(m_headers);
}
Example #7
0
void RuntimeOption::Load(Hdf &config) {
  PidFile = config["PidFile"].getString("www.pid");

  // Machine metrics
  string hostname, tier, cpu;
  {
    Hdf machine = config["Machine"];

    hostname = machine["name"].getString();
    if (hostname.empty()) {
      hostname = Process::GetHostName();
    }

    tier = machine["tier"].getString();

    cpu = machine["cpu"].getString();
    if (cpu.empty()) {
      cpu = Process::GetCPUModel();
    }
  }

  // Tier overwrites
  {
    Hdf tiers = config["Tiers"];
    for (Hdf hdf = tiers.firstChild(); hdf.exists(); hdf = hdf.next()) {
      if (matchHdfPattern(hostname, hdf["machine"]) &&
          matchHdfPattern(tier, hdf["tier"]) &&
          matchHdfPattern(cpu, hdf["cpu"])) {
        Tier = hdf.getName();
        config.copy(hdf["overwrite"]);
        // no break here, so we can continue to match more overwrites
      } else {
        hdf["overwrite"].setVisited(); // avoid lint complaining
      }
    }
  }

  {
    Hdf logger = config["Log"];
    if (logger["Level"] == "None") {
      Logger::LogLevel = Logger::LogNone;
    } else if (logger["Level"] == "Error") {
      Logger::LogLevel = Logger::LogError;
    } else if (logger["Level"] == "Warning") {
      Logger::LogLevel = Logger::LogWarning;
    } else if (logger["Level"] == "Info") {
      Logger::LogLevel = Logger::LogInfo;
    } else if (logger["Level"] == "Verbose") {
      Logger::LogLevel = Logger::LogVerbose;
    }
    Logger::LogHeader = logger["Header"].getBool();
    bool logInjectedStackTrace = logger["InjectedStackTrace"].getBool();
    if (logInjectedStackTrace) {
      Logger::SetTheLogger(new ExtendedLogger());
      ExtendedLogger::EnabledByDefault = true;
    }
    Logger::LogNativeStackTrace = logger["NativeStackTrace"].getBool(true);
    Logger::MaxMessagesPerRequest =
      logger["MaxMessagesPerRequest"].getInt32(-1);

    Logger::UseLogFile = logger["UseLogFile"].getBool(true);
    Logger::UseCronolog = logger["UseCronolog"].getBool(false);
    if (Logger::UseLogFile) {
      LogFile = logger["File"].getString();
      LogFileSymLink = logger["SymLink"].getString();
    }
    Logger::DropCacheChunkSize =
      logger["DropCacheChunkSize"].getInt32(1 << 20);

    Hdf aggregator = logger["Aggregator"];
    Logger::UseLogAggregator = aggregator.getBool();
    LogAggregatorFile = aggregator["File"].getString();
    LogAggregatorDatabase = aggregator["Database"].getString();
    LogAggregatorSleepSeconds = aggregator["SleepSeconds"].getInt16(10);

    AlwaysLogUnhandledExceptions =
      logger["AlwaysLogUnhandledExceptions"].getBool(true);
    NoSilencer = logger["NoSilencer"].getBool();
    EnableApplicationLog = logger["ApplicationLog"].getBool(true);
    RuntimeErrorReportingLevel =
      logger["RuntimeErrorReportingLevel"].getInt32(ErrorConstants::HPHP_ALL);

    AccessLogDefaultFormat = logger["AccessLogDefaultFormat"].
      getString("%h %l %u %t \"%r\" %>s %b");
    {
      Hdf access = logger["Access"];
      for (Hdf hdf = access.firstChild(); hdf.exists();
           hdf = hdf.next()) {
        string fname = hdf["File"].getString();
        if (fname.empty()) {
          continue;
        }
        string symLink = hdf["SymLink"].getString();
        AccessLogs.
          push_back(AccessLogFileData(fname, symLink, hdf["Format"].
                                      getString(AccessLogDefaultFormat)));
      }
    }

    AdminLogFormat = logger["AdminLog.Format"].getString("%h %t %s %U");
    AdminLogFile = logger["AdminLog.File"].getString();
    AdminLogSymLink = logger["AdminLog.SymLink"].getString();
  }
  {
    Hdf error = config["ErrorHandling"];
    CallUserHandlerOnFatals = error["CallUserHandlerOnFatals"].getBool(true);
    NoInfiniteLoopDetection = error["NoInfiniteLoopDetection"].getBool();
    NoInfiniteRecursionDetection =
      error["NoInfiniteRecursionDetection"].getBool();
    ThrowBadTypeExceptions = error["ThrowBadTypeExceptions"].getBool();
    ThrowTooManyArguments = error["ThrowTooManyArguments"].getBool();
    WarnTooManyArguments = error["WarnTooManyArguments"].getBool();
    ThrowMissingArguments = error["ThrowMissingArguments"].getBool();
    ThrowInvalidArguments = error["ThrowInvalidArguments"].getBool();
    EnableHipHopErrors = error["EnableHipHopErrors"].getBool(true);
    AssertActive = error["AssertActive"].getBool();
    AssertWarning = error["AssertWarning"].getBool();
    NoticeFrequency = error["NoticeFrequency"].getInt32(1);
    WarningFrequency = error["WarningFrequency"].getInt32(1);
  }
  {
    Hdf rlimit = config["ResourceLimit"];
    setResourceLimit(RLIMIT_CORE,   rlimit, "CoreFileSize");
    setResourceLimit(RLIMIT_NOFILE, rlimit, "MaxSocket");
    setResourceLimit(RLIMIT_DATA,   rlimit, "RSS");
    MaxRSS = rlimit["MaxRSS"].getInt64(0);
    SocketDefaultTimeout = rlimit["SocketDefaultTimeout"].getInt16(5);
    MaxRSSPollingCycle = rlimit["MaxRSSPollingCycle"].getInt64(0);
    DropCacheCycle = rlimit["DropCacheCycle"].getInt64(0);
    MaxSQLRowCount = rlimit["MaxSQLRowCount"].getInt64(0);
    MaxMemcacheKeyCount = rlimit["MaxMemcacheKeyCount"].getInt64(0);
    SerializationSizeLimit = rlimit["SerializationSizeLimit"].getInt64(0);
    StringOffsetLimit = rlimit["StringOffsetLimit"].getInt64(10 * 1024 * 1024);
  }
  {
    Hdf server = config["Server"];
    Host = server["Host"].getString();
    DefaultServerNameSuffix = server["DefaultServerNameSuffix"].getString();
    ServerIP = server["IP"].getString("0.0.0.0");
    ServerPrimaryIP = Util::GetPrimaryIP();
    ServerPort = server["Port"].getInt16(80);
    ServerBacklog = server["Backlog"].getInt16(128);
    ServerConnectionLimit = server["ConnectionLimit"].getInt16(0);
    ServerThreadCount = server["ThreadCount"].getInt32(50);
    ServerThreadRoundRobin = server["ThreadRoundRobin"].getBool();
    ServerThreadDropCacheTimeoutSeconds =
      server["ThreadDropCacheTimeoutSeconds"].getInt32(0);
    ServerThreadJobLIFO = server["ThreadJobLIFO"].getBool();
    RequestTimeoutSeconds = server["RequestTimeoutSeconds"].getInt32(0);
    RequestMemoryMaxBytes = server["RequestMemoryMaxBytes"].getInt64(-1);
    ResponseQueueCount = server["ResponseQueueCount"].getInt32(0);
    if (ResponseQueueCount <= 0) {
      ResponseQueueCount = ServerThreadCount / 10;
      if (ResponseQueueCount <= 0) ResponseQueueCount = 1;
    }
    ServerGracefulShutdownWait = server["GracefulShutdownWait"].getInt16(0);
    ServerHarshShutdown = server["HarshShutdown"].getBool(true);
    ServerEvilShutdown = server["EvilShutdown"].getBool(true);
    ServerDanglingWait = server["DanglingWait"].getInt16(0);
    if (ServerGracefulShutdownWait < ServerDanglingWait) {
      ServerGracefulShutdownWait = ServerDanglingWait;
    }
    GzipCompressionLevel = server["GzipCompressionLevel"].getInt16(3);

    ForceCompressionURL    = server["ForceCompression"]["URL"].getString();
    ForceCompressionCookie = server["ForceCompression"]["Cookie"].getString();
    ForceCompressionParam  = server["ForceCompression"]["Param"].getString();

    EnableMagicQuotesGpc = server["EnableMagicQuotesGpc"].getBool();
    EnableKeepAlive = server["EnableKeepAlive"].getBool(true);
    ConnectionTimeoutSeconds = server["ConnectionTimeoutSeconds"].getInt16(-1);
    EnableOutputBuffering = server["EnableOutputBuffering"].getBool();
    OutputHandler = server["OutputHandler"].getString();
    ImplicitFlush = server["ImplicitFlush"].getBool();
    EnableEarlyFlush = server["EnableEarlyFlush"].getBool(true);
    ForceChunkedEncoding = server["ForceChunkedEncoding"].getBool();
    MaxPostSize = (server["MaxPostSize"].getInt32(100)) * (1 << 20);
    AlwaysPopulateRawPostData = server["AlwaysPopulateRawPostData"].getBool();
    LibEventSyncSend = server["LibEventSyncSend"].getBool(true);
    TakeoverFilename = server["TakeoverFilename"].getString();
    ExpiresActive = server["ExpiresActive"].getBool(true);
    ExpiresDefault = server["ExpiresDefault"].getInt32(2592000);
    if (ExpiresDefault < 0) ExpiresDefault = 2592000;
    DefaultCharsetName = server["DefaultCharsetName"].getString("UTF-8");

    RequestBodyReadLimit = server["RequestBodyReadLimit"].getInt32(-1);

    EnableSSL = server["EnableSSL"].getBool();
    SSLPort = server["SSLPort"].getInt16(443);
    SSLCertificateFile = server["SSLCertificateFile"].getString();
    SSLCertificateKeyFile = server["SSLCertificateKeyFile"].getString();

    SourceRoot = server["SourceRoot"].getString();
    if (!SourceRoot.empty() && SourceRoot[SourceRoot.length() - 1] != '/') {
      SourceRoot += '/';
    }
    if (!SourceRoot.empty()) {
      // Guaranteed empty on empty load so avoid setting FileCache::SourceRoot
      // since it may not be initialized
      FileCache::SourceRoot = SourceRoot;
    }
    server["IncludeSearchPaths"].get(IncludeSearchPaths);
    for (unsigned int i = 0; i < IncludeSearchPaths.size(); i++) {
      string &path = IncludeSearchPaths[i];
      if (!path.empty() && path[path.length() - 1] != '/') {
        path += '/';
      }
    }
    IncludeSearchPaths.insert(IncludeSearchPaths.begin(), "./");

    FileCache = server["FileCache"].getString();
    DefaultDocument = server["DefaultDocument"].getString();
    ErrorDocument404 = server["ErrorDocument404"].getString();
    normalizePath(ErrorDocument404);
    ErrorDocument500 = server["ErrorDocument500"].getString();
    normalizePath(ErrorDocument500);
    FatalErrorMessage = server["FatalErrorMessage"].getString();
    FontPath = server["FontPath"].getString();
    if (!FontPath.empty() && FontPath[FontPath.length() - 1] != '/') {
      FontPath += "/";
    }
    EnableStaticContentCache =
      server["EnableStaticContentCache"].getBool(true);
    EnableStaticContentFromDisk =
      server["EnableStaticContentFromDisk"].getBool(true);
    EnableOnDemandUncompress =
      server["EnableOnDemandUncompress"].getBool(true);
    EnableStaticContentMMap =
      server["EnableStaticContentMMap"].getBool(true);
    if (EnableStaticContentMMap) {
      EnableOnDemandUncompress = true;
    }
    RTTIDirectory = server["RTTIDirectory"].getString("/tmp/");
    if (!RTTIDirectory.empty() &&
        RTTIDirectory[RTTIDirectory.length() - 1] != '/') {
      RTTIDirectory += "/";
    }
    EnableCliRTTI = server["EnableCliRTTI"].getBool();

    StartupDocument = server["StartupDocument"].getString();
    normalizePath(StartupDocument);
    WarmupDocument = server["WarmupDocument"].getString();
    RequestInitFunction = server["RequestInitFunction"].getString();
    RequestInitDocument = server["RequestInitDocument"].getString();
    server["ThreadDocuments"].get(ThreadDocuments);
    for (unsigned int i = 0; i < ThreadDocuments.size(); i++) {
      normalizePath(ThreadDocuments[i]);
    }

    SafeFileAccess = server["SafeFileAccess"].getBool();
    server["AllowedDirectories"].get(AllowedDirectories);
    for (unsigned int i = 0; i < AllowedDirectories.size(); i++) {
      string &directory = AllowedDirectories[i];
      char resolved_path[PATH_MAX];
      if (realpath(directory.c_str(), resolved_path) &&
          directory != resolved_path) {
        RuntimeOption::AllowedDirectories.push_back(resolved_path);
      }
    }
    server["AllowedFiles"].get(AllowedFiles);

    server["ForbiddenFileExtensions"].get(ForbiddenFileExtensions);

    EnableMemoryManager = server["EnableMemoryManager"].getBool(true);
    CheckMemory = server["CheckMemory"].getBool();
    UseHphpArray = server["UseHphpArray"].getBool(false);
    UseSmallArray = server["UseSmallArray"].getBool(false);
    UseDirectCopy = server["UseDirectCopy"].getBool(false);
    AlwaysUseRelativePath = server["AlwaysUseRelativePath"].getBool(false);

    Hdf apc = server["APC"];
    EnableApc = apc["EnableApc"].getBool(true);
    EnableConstLoad = apc["EnableConstLoad"].getBool(false);
    ApcUseSharedMemory = apc["UseSharedMemory"].getBool();
    ApcUseGnuMap = apc["ApcUseGnuMap"].getBool();
    ApcSharedMemorySize = apc["SharedMemorySize"].getInt32(1024 /* 1GB */);
    ApcPrimeLibrary = apc["PrimeLibrary"].getString();
    ApcLoadThread = apc["LoadThread"].getInt16(2);
    apc["CompletionKeys"].get(ApcCompletionKeys);

    string apcTableType = apc["TableType"].getString("hash");
    if (strcasecmp(apcTableType.c_str(), "hash") == 0) {
      ApcTableType = ApcHashTable;
    } else if (strcasecmp(apcTableType.c_str(), "concurrent") == 0) {
      ApcTableType = ApcConcurrentTable;
    } else {
      throw InvalidArgumentException("apc table type",
                                     "Invalid table type");
    }
    string apcLockType = apc["LockType"].getString("readwritelock");
    if (strcasecmp(apcLockType.c_str(), "readwritelock") == 0) {
      ApcTableLockType = ApcReadWriteLock;
    } else if (strcasecmp(apcLockType.c_str(), "mutex") == 0) {
      ApcTableLockType = ApcMutex;
    } else {
      throw InvalidArgumentException("apc lock type",
                                     "Invalid lock type");
    }

    ApcExpireOnSets = apc["ExpireOnSets"].getBool();
    ApcPurgeFrequency = apc["PurgeFrequency"].getInt32(4096);

    ApcKeyMaturityThreshold = apc["KeyMaturityThreshold"].getInt32(20);
    ApcMaximumCapacity = apc["MaximumCapacity"].getInt64(0);
    ApcKeyFrequencyUpdatePeriod = apc["KeyFrequencyUpdatePeriod"].
      getInt32(1000);


    Hdf dns = server["DnsCache"];
    EnableDnsCache = dns["Enable"].getBool();
    DnsCacheTTL = dns["TTL"].getInt32(600); // 10 minutes
    DnsCacheKeyMaturityThreshold = dns["KeyMaturityThreshold"].getInt32(20);
    DnsCacheMaximumCapacity = dns["MaximumCapacity"].getInt64(0);
    DnsCacheKeyFrequencyUpdatePeriod = dns["KeyFrequencyUpdatePeriod"].
      getInt32(1000);

    Hdf upload = server["Upload"];
    UploadMaxFileSize =
      (upload["UploadMaxFileSize"].getInt32(100)) * (1 << 20);
    UploadTmpDir = upload["UploadTmpDir"].getString("/tmp");
    RuntimeOption::AllowedDirectories.push_back(UploadTmpDir);
    EnableFileUploads = upload["EnableFileUploads"].getBool(true);
    EnableUploadProgress = upload["EnableUploadProgress"].getBool();
    Rfc1867Freq = upload["Rfc1867Freq"].getInt32(256 * 1024);
    if (Rfc1867Freq < 0) Rfc1867Freq = 256 * 1024;
    Rfc1867Prefix = upload["Rfc1867Prefix"].getString("vupload_");
    Rfc1867Name = upload["Rfc1867Name"].getString("video_ptoken");

    ImageMemoryMaxBytes = server["ImageMemoryMaxBytes"].getInt64(0);
    if (ImageMemoryMaxBytes == 0) {
      ImageMemoryMaxBytes = UploadMaxFileSize * 2;
    }
    SharedStores::Create();

    LightProcessFilePrefix =
      server["LightProcessFilePrefix"].getString("./lightprocess");
    LightProcessCount = server["LightProcessCount"].getInt32(0);

    InjectedStackTrace = server["InjectedStackTrace"].getBool(true);

    ForceServerNameToHeader = server["ForceServerNameToHeader"].getBool();
  }
  {
    Hdf hosts = config["VirtualHost"];
    if (hosts.exists()) {
      for (Hdf hdf = hosts.firstChild(); hdf.exists(); hdf = hdf.next()) {
        if (hdf.getName() == "default") {
          VirtualHost::GetDefault().init(hdf);
        } else {
          VirtualHostPtr host(new VirtualHost(hdf));
          VirtualHosts.push_back(host);
        }
      }
      for (unsigned int i = 0; i < VirtualHosts.size(); i++) {
        if (!VirtualHosts[i]->valid()) {
          throw InvalidArgumentException("virtual host",
                                         "missing prefix or pattern");
        }
      }
    }
  }
  {
    Hdf ipblocks = config["IpBlockMap"];
    IpBlocks = IpBlockMapPtr(new IpBlockMap(ipblocks));
  }
  {
    Hdf satellites = config["Satellites"];
    if (satellites.exists()) {
      for (Hdf hdf = satellites.firstChild(); hdf.exists(); hdf = hdf.next()) {
        SatelliteServerInfoPtr satellite(new SatelliteServerInfo(hdf));
        SatelliteServerInfos.push_back(satellite);
        if (satellite->getType() == SatelliteServer::KindOfRPCServer) {
          XboxPassword = satellite->getPassword();
        }
      }
    }
  }
  {
    Hdf xbox = config["Xbox"];
    XboxServerThreadCount = xbox["ServerInfo.ThreadCount"].getInt32(0);
    XboxServerPort = xbox["ServerInfo.Port"].getInt32(0);
    XboxDefaultLocalTimeoutMilliSeconds =
      xbox["DefaultLocalTimeoutMilliSeconds"].getInt32(500);
    XboxDefaultRemoteTimeoutSeconds =
      xbox["DefaultRemoteTimeoutSeconds"].getInt32(5);
    XboxServerInfoMaxRequest = xbox["ServerInfo.MaxRequest"].getInt32(500);
    XboxServerInfoDuration = xbox["ServerInfo.MaxDuration"].getInt32(120);
    XboxServerInfoWarmupDoc = xbox["ServerInfo.WarmupDocument"].get("");
    XboxServerInfoReqInitFunc = xbox["ServerInfo.RequestInitFunction"].get("");
    XboxServerInfoReqInitDoc = xbox["ServerInfo.RequestInitDocument"].get("");
    XboxProcessMessageFunc =
      xbox["ProcessMessageFunc"].get("xbox_process_message");
  }
  {
    PageletServerThreadCount = config["PageletServer.ThreadCount"].getInt32(0);
    FiberCount = config["Fiber.ThreadCount"].getInt32(0);
    if (FiberCount > 0) {
      FiberAsyncFunc::Restart();
    }
  }
  {
    Hdf content = config["StaticFile"];
    content["Extensions"].get(StaticFileExtensions);
    content["Generators"].get(StaticFileGenerators);

    Hdf matches = content["FilesMatch"];
    if (matches.exists()) {
      for (Hdf hdf = matches.firstChild(); hdf.exists(); hdf = hdf.next()) {
        FilesMatches.push_back(FilesMatchPtr(new FilesMatch(hdf)));
      }
    }
  }
  {
    Hdf admin = config["AdminServer"];
    AdminServerPort = admin["Port"].getInt16(8088);
    AdminThreadCount = admin["ThreadCount"].getInt32(1);
    AdminPassword = admin["Password"].getString();
  }
  {
    Hdf proxy = config["Proxy"];
    ProxyOrigin = proxy["Origin"].getString();
    ProxyRetry = proxy["Retry"].getInt16(3);
    UseServeURLs = proxy["ServeURLs"].getBool();
    proxy["ServeURLs"].get(ServeURLs);
    UseProxyURLs = proxy["ProxyURLs"].getBool();
    ProxyPercentage = proxy["Percentage"].getByte(0);
    proxy["ProxyURLs"].get(ProxyURLs);
    proxy["ProxyPatterns"].get(ProxyPatterns);
  }
  {
    Hdf mysql = config["MySQL"];
    MySQLReadOnly = mysql["ReadOnly"].getBool();
    MySQLLocalize = mysql["Localize"].getBool();
    MySQLConnectTimeout = mysql["ConnectTimeout"].getInt32(1000);
    MySQLReadTimeout = mysql["ReadTimeout"].getInt32(1000);
    MySQLWaitTimeout = mysql["WaitTimeout"].getInt32(-1);
    MySQLSlowQueryThreshold = mysql["SlowQueryThreshold"].getInt32(1000);
    MySQLKillOnTimeout = mysql["KillOnTimeout"].getBool();
  }
  {
    Hdf http = config["Http"];
    HttpDefaultTimeout = http["DefaultTimeout"].getInt32(30);
    HttpSlowQueryThreshold = http["SlowQueryThreshold"].getInt32(5000);
  }
  {
    Hdf debug = config["Debug"];
    NativeStackTrace = debug["NativeStackTrace"].getBool();
    StackTrace::Enabled = NativeStackTrace;
    TranslateLeakStackTrace = debug["TranslateLeakStackTrace"].getBool();
    FullBacktrace = debug["FullBacktrace"].getBool();
    ServerStackTrace = debug["ServerStackTrace"].getBool();
    ServerErrorMessage = debug["ServerErrorMessage"].getBool();
    TranslateSource = debug["TranslateSource"].getBool();
    RecordInput = debug["RecordInput"].getBool();
    ClearInputOnSuccess = debug["ClearInputOnSuccess"].getBool(true);
    ProfilerOutputDir = debug["ProfilerOutputDir"].getString("/tmp");
    CoreDumpEmail = debug["CoreDumpEmail"].getString();
    if (!CoreDumpEmail.empty()) {
      StackTrace::ReportEmail = CoreDumpEmail;
    }
    CoreDumpReport = debug["CoreDumpReport"].getBool(true);
    if (CoreDumpReport) {
      StackTrace::InstallReportOnErrors();
    }
    LocalMemcache = debug["LocalMemcache"].getBool();
    MemcacheReadOnly = debug["MemcacheReadOnly"].getBool();

    {
      Hdf simpleCounter = debug["SimpleCounter"];
      SimpleCounter::SampleStackCount =
        simpleCounter["SampleStackCount"].getInt32(0);
      SimpleCounter::SampleStackDepth =
        simpleCounter["SampleStackDepth"].getInt32(5);
    }
  }
  {
    Hdf stats = config["Stats"];
    EnableStats = stats.getBool(); // main switch

    EnableWebStats = stats["Web"].getBool();
    EnableMemoryStats = stats["Memory"].getBool();
    EnableMallocStats = stats["Malloc"].getBool();
    EnableAPCStats = stats["APC"].getBool();
    EnableAPCKeyStats = stats["APCKey"].getBool();
    EnableMemcacheStats = stats["Memcache"].getBool();
    EnableMemcacheKeyStats = stats["MemcacheKey"].getBool();
    EnableSQLStats = stats["SQL"].getBool();
    EnableSQLTableStats = stats["SQLTable"].getBool();

    if (EnableStats && EnableMallocStats) {
      LeakDetectable::EnableMallocStats(true);
    }

    StatsXSL = stats["XSL"].getString();
    StatsXSLProxy = stats["XSLProxy"].getString();

    StatsSlotDuration = stats["SlotDuration"].getInt32(10 * 60); // 10 minutes
    StatsMaxSlot = stats["MaxSlot"].getInt32(12 * 6); // 12 hours

    {
      Hdf apcSize = stats["APCSize"];
      EnableAPCSizeStats = apcSize["Enable"].getBool();
      EnableAPCSizeGroup = apcSize["Group"].getBool();
      apcSize["SpecialPrefix"].get(APCSizeSpecialPrefix);
      for (unsigned int i = 0; i < APCSizeSpecialPrefix.size(); i++) {
        string &prefix = APCSizeSpecialPrefix[i];
        string prefixReplace = prefix + "{A}";
        APCSizePrefixReplace.push_back(prefixReplace);
      }
      apcSize["SpecialMiddle"].get(APCSizeSpecialMiddle);
      for (unsigned int i = 0; i < APCSizeSpecialMiddle.size(); i++) {
        string &middle = APCSizeSpecialMiddle[i];
        string middleReplace = "{A}" + middle + "{A}";
        APCSizeMiddleReplace.push_back(middleReplace);
      }
      EnableAPCSizeDetail = apcSize["Individual"].getBool();
      EnableAPCFetchStats = apcSize["FetchStats"].getBool();
      APCSizeCountPrime = apcSize["CountPrime"].getBool();
    }

    ProfilerTraceBuffer = stats["ProfilerTraceBuffer"].getInt32(2000000);
    ProfilerTraceExpansion = stats["ProfilerTraceExpansion"].getDouble(1.2);
  }
  {
    config["ServerVariables"].get(ServerVariables);
    config["EnvVariables"].get(EnvVariables);
  }
  {
    Hdf eval = config["Eval"];
    EnableShortTags= eval["EnableShortTags"].getBool(true);
    if (EnableShortTags) ScannerType |= Scanner::AllowShortTags;
    else ScannerType &= ~Scanner::AllowShortTags;

    EnableAspTags = eval["EnableAspTags"].getBool();
    if (EnableAspTags) ScannerType |= Scanner::AllowAspTags;
    else ScannerType &= ~Scanner::AllowAspTags;

    EnableXHP = eval["EnableXHP"].getBool(true);
    if (EnableXHP) ScannerType |= Scanner::PreprocessXHP;
    else ScannerType &= ~Scanner::PreprocessXHP;

    EnableStrict = eval["EnableStrict"].getBool();
    StrictLevel = eval["StrictLevel"].getInt32(1); // StrictBasic
    StrictFatal = eval["StrictFatal"].getBool();
    RecordCodeCoverage = eval["RecordCodeCoverage"].getBool();
    CodeCoverageOutputFile = eval["CodeCoverageOutputFile"].getString();
    {
      Hdf debugger = eval["Debugger"];
      EnableDebugger = debugger["EnableDebugger"].getBool();
      EnableDebuggerServer = debugger["EnableDebuggerServer"].getBool();
      DebuggerServerPort = debugger["Port"].getInt16(8089);
      DebuggerStartupDocument = debugger["StartupDocument"].getString();
      DebuggerDefaultSandboxPath = debugger["DefaultSandboxPath"].getString();

      DebuggerDefaultRpcPort = debugger["RPC.DefaultPort"].getInt16(8083);
      DebuggerDefaultRpcAuth = debugger["RPC.DefaultAuth"].getString();
      DebuggerRpcHostDomain = debugger["RPC.HostDomain"].getString();
      DebuggerDefaultRpcTimeout = debugger["RPC.DefaultTimeout"].getInt32(30);
    }
  }
  {
    Hdf sandbox = config["Sandbox"];
    SandboxMode = sandbox["SandboxMode"].getBool();
    SandboxPattern = format_pattern(sandbox["Pattern"].getString(), true);
    SandboxHome = sandbox["Home"].getString();
    SandboxFallback = sandbox["Fallback"].getString();
    SandboxConfFile = sandbox["ConfFile"].getString();
    SandboxFromCommonRoot = sandbox["FromCommonRoot"].getBool();
    SandboxDirectoriesRoot = sandbox["DirectoriesRoot"].getString();
    SandboxLogsRoot = sandbox["LogsRoot"].getString();
    sandbox["ServerVariables"].get(SandboxServerVariables);
  }
  {
    Hdf mail = config["Mail"];
    SendmailPath = mail["SendmailPath"].getString("sendmail -t -i");
    MailForceExtraParameters = mail["ForceExtraParameters"].getString();
  }
  {
    Hdf preg = config["Preg"];
    PregBacktraceLimit = preg["BacktraceLimit"].getInt32(100000);
    PregRecursionLimit = preg["RecursionLimit"].getInt32(100000);
  }

  Extension::LoadModules(config);
}
Example #8
0
void RuntimeOption::Load(Hdf &config) {
  PidFile = config["PidFile"].getString("www.pid");

  // Tier overwrites
  {
    Hdf tiers = config["Tiers"];
    string hostname = Process::GetHostName();
    for (Hdf hdf = tiers.firstChild(); hdf.exists(); hdf = hdf.next()) {
      string pattern = hdf["machine"].getString();
      if (!pattern.empty()) {
        Variant ret = preg_match(String(pattern.c_str(), pattern.size(),
                                        AttachLiteral),
                                 String(hostname.c_str(), hostname.size(),
                                        AttachLiteral));
        if (ret.toInt64() > 0) {
          Tier = hdf.getName();
          config.copy(hdf["overwrite"]);
          // no break here, so we can continue to match more overwrites
        }
      }
    }
  }

  {
    Hdf logger = config["Log"];
    if (logger["Level"] == "None") {
      Logger::LogLevel = Logger::LogNone;
    } else if (logger["Level"] == "Error") {
      Logger::LogLevel = Logger::LogError;
    } else if (logger["Level"] == "Warning") {
      Logger::LogLevel = Logger::LogWarning;
    } else if (logger["Level"] == "Info") {
      Logger::LogLevel = Logger::LogInfo;
    } else if (logger["Level"] == "Verbose") {
      Logger::LogLevel = Logger::LogVerbose;
    }
    Logger::LogHeader = logger["Header"].getBool();
    Logger::MaxMessagesPerRequest =
      logger["MaxMessagesPerRequest"].getInt32(-1);

    Logger::UseLogFile = logger["UseLogFile"].getBool(true);
    if (Logger::UseLogFile) {
      LogFile = logger["File"].getString();
    }

    Hdf aggregator = logger["Aggregator"];
    Logger::UseLogAggregator = aggregator.getBool();
    LogAggregatorFile = aggregator["File"].getString();
    LogAggregatorDatabase = aggregator["Database"].getString();
    LogAggregatorSleepSeconds = aggregator["SleepSeconds"].getInt16(10);

    AlwaysLogUnhandledExceptions =
      logger["AlwaysLogUnhandledExceptions"].getBool(true);
    NoSilencer = logger["NoSilencer"].getBool();
    EnableApplicationLog = logger["ApplicationLog"].getBool(true);

    AccessLogDefaultFormat = logger["AccessLogDefaultFormat"].
      getString("%h %l %u %t \"%r\" %>s %b");
    {
      Hdf access = logger["Access"];
      for (Hdf hdf = access.firstChild(); hdf.exists();
           hdf = hdf.next()) {
        string fname = hdf["File"].getString();
        if (fname.empty()) {
          continue;
        }
        AccessLogs.
          push_back(pair<string, string>(fname, hdf["Format"].
                                         getString(AccessLogDefaultFormat)));
      }
    }

    AdminLogFormat = logger["AdminLogFormat"].getString("%h %t %s %U");
    AdminLogFile = logger["AdminLogFile"].getString();
  }
  {
    Hdf error = config["ErrorHandling"];
    NoInfiniteLoopDetection = error["NoInfiniteLoopDetection"].getBool();
    NoInfiniteRecursionDetection =
      error["NoInfiniteRecursionDetection"].getBool();
    ThrowBadTypeExceptions = error["ThrowBadTypeExceptions"].getBool();
    ThrowNotices = error["ThrowNotices"].getBool();
    AssertActive = error["AssertActive"].getBool();
    AssertWarning = error["AssertWarning"].getBool();
  }
  {
    Hdf rlimit = config["ResourceLimit"];
    setResourceLimit(RLIMIT_CORE,   rlimit, "CoreFileSize");
    setResourceLimit(RLIMIT_NOFILE, rlimit, "MaxSocket");
    setResourceLimit(RLIMIT_DATA,   rlimit, "RSS");
    MaxRSS = rlimit["RSS"].getInt64(0);
  }
  {
    Hdf server = config["Server"];
    Host = server["Host"].getString();
    DefaultServerNameSuffix = server["DefaultServerNameSuffix"].getString();
    ServerIP = server["IP"].getString("0.0.0.0");
    ServerPrimaryIP = Util::GetPrimaryIP();
    ServerPort = server["Port"].getInt16(80);
    ServerThreadCount = server["ThreadCount"].getInt32(50);
    PageletServerThreadCount = server["PageletServerThreadCount"].getInt32(0);
    RequestTimeoutSeconds = server["RequestTimeoutSeconds"].getInt32(-1);
    RequestMemoryMaxBytes = server["RequestMemoryMaxBytes"].getInt64(-1);
    ResponseQueueCount = server["ResponseQueueCount"].getInt32(0);
    if (ResponseQueueCount <= 0) {
      ResponseQueueCount = ServerThreadCount / 10;
      if (ResponseQueueCount <= 0) ResponseQueueCount = 1;
    }
    ServerGracefulShutdownWait = server["GracefulShutdownWait"].getInt16(0);
    ServerHarshShutdown = server["HarshShutdown"].getBool(true);
    ServerEvilShutdown = server["EvilShutdown"].getBool(true);
    ServerDanglingWait = server["DanglingWait"].getInt16(0);
    if (ServerGracefulShutdownWait < ServerDanglingWait) {
      ServerGracefulShutdownWait = ServerDanglingWait;
    }
    GzipCompressionLevel = server["GzipCompressionLevel"].getInt16(3);
    EnableKeepAlive = server["EnableKeepAlive"].getBool(true);
    EnableEarlyFlush = server["EnableEarlyFlush"].getBool(true);
    ForceChunkedEncoding = server["ForceChunkedEncoding"].getBool();
    MaxPostSize = (server["MaxPostSize"].getInt32(8)) * (1 << 20);
    UploadMaxFileSize = (server["MaxPostSize"].getInt32(10)) * (1 << 20);
    EnableFileUploads = server["EnableFileUploads"].getBool(true);
    LibEventSyncSend = server["LibEventSyncSend"].getBool(true);
    TakeoverFilename = server["TakeoverFilename"].getString();
    ExpiresActive = server["ExpiresActive"].getBool(true);
    ExpiresDefault = server["ExpiresDefault"].getInt32(2592000);
    if (ExpiresDefault < 0) ExpiresDefault = 2592000;
    DefaultCharsetName = server["DefaultCharsetName"].getString("UTF-8");

    SourceRoot = server["SourceRoot"].getString();
    if (!SourceRoot.empty() && SourceRoot[SourceRoot.length() - 1] != '/') {
      SourceRoot += '/';
    }
    if (!SourceRoot.empty()) {
      // Guaranteed empty on empty load so avoid setting FileCache::SourceRoot
      // since it may not be initialized
      FileCache::SourceRoot = SourceRoot;
    }
    server["IncludeSearchPaths"].get(IncludeSearchPaths);
    for (unsigned int i = 0; i < IncludeSearchPaths.size(); i++) {
      string &path = IncludeSearchPaths[i];
      if (!path.empty() && path[path.length() - 1] != '/') {
        path += '/';
      }
    }
    IncludeSearchPaths.insert(IncludeSearchPaths.begin(), "./");

    FileCache = server["FileCache"].getString();
    DefaultDocument = server["DefaultDocument"].getString();
    ErrorDocument404 = server["ErrorDocument404"].getString();
    normalizePath(ErrorDocument404);
    FatalErrorMessage = server["FatalErrorMessage"].getString();
    FontPath = server["FontPath"].getString();
    if (!FontPath.empty() && FontPath[FontPath.length() - 1] != '/') {
      FontPath += "/";
    }
    EnableStaticContentCache =
      server["EnableStaticContentCache"].getBool(true);
    EnableStaticContentFromDisk =
      server["EnableStaticContentFromDisk"].getBool(true);

    RTTIDirectory = server["RTTIDirectory"].getString("/tmp/");
    if (!RTTIDirectory.empty() &&
        RTTIDirectory[RTTIDirectory.length() - 1] != '/') {
      RTTIDirectory += "/";
    }
    EnableCliRTTI = server["EnableCliRTTI"].getBool();

    StartupDocument = server["StartupDocument"].getString();
    normalizePath(StartupDocument);
    WarmupDocument = server["WarmupDocument"].getString();
    RequestInitFunction = server["RequestInitFunction"].getString();
    server["ThreadDocuments"].get(ThreadDocuments);
    for (unsigned int i = 0; i < ThreadDocuments.size(); i++) {
      normalizePath(ThreadDocuments[i]);
    }

    SafeFileAccess = server["SafeFileAccess"].getBool();
    server["AllowedDirectories"].get(AllowedDirectories);
    for (unsigned int i = 0; i < AllowedDirectories.size(); i++) {
      string &directory = AllowedDirectories[i];
      char resolved_path[PATH_MAX];
      if (realpath(directory.c_str(), resolved_path) &&
          directory != resolved_path) {
        RuntimeOption::AllowedDirectories.push_back(resolved_path);
      }
    }
    server["AllowedFiles"].get(AllowedFiles);

    EnableMemoryManager = server["EnableMemoryManager"].getBool();
    CheckMemory = server["CheckMemory"].getBool();
    UseZendArray = server["UseZendArray"].getBool(true);

    Hdf apc = server["APC"];
    EnableApc = apc["EnableApc"].getBool(true);
    ApcUseSharedMemory = apc["UseSharedMemory"].getBool();
    ApcSharedMemorySize = apc["SharedMemorySize"].getInt32(1024 /* 1GB */);
    ApcPrimeLibrary = apc["PrimeLibrary"].getString();
    ApcLoadThread = apc["LoadThread"].getInt16(2);
    apc["CompletionKeys"].get(ApcCompletionKeys);

    string apcTableType = apc["TableType"].getString("hash");
    if (strcasecmp(apcTableType.c_str(), "hash") == 0) {
      ApcTableType = ApcHashTable;
    } else if (strcasecmp(apcTableType.c_str(), "lfu") == 0) {
      ApcTableType = ApcLfuTable;
    } else if (strcasecmp(apcTableType.c_str(), "concurrent") == 0) {
      ApcTableType = ApcConcurrentTable;
    } else {
      throw InvalidArgumentException("apc table type",
                                     "Invalid table type");
    }
    string apcLockType = apc["LockType"].getString("readwritelock");
    if (strcasecmp(apcLockType.c_str(), "readwritelock") == 0) {
      ApcTableLockType = ApcReadWriteLock;
    } else if (strcasecmp(apcLockType.c_str(), "mutex") == 0) {
      ApcTableLockType = ApcMutex;
    } else {
      throw InvalidArgumentException("apc lock type",
                                     "Invalid lock type");
    }

    ApcUseLockedRefs = apc["UseLockedRefs"].getBool();
    ApcExpireOnSets = apc["ExpireOnSets"].getBool();
    ApcPurgeFrequency = apc["PurgeFrequency"].getInt32(4096);

    ApcKeyMaturityThreshold = apc["KeyMaturityThreshold"].getInt32(20);
    ApcMaximumCapacity = apc["MaximumCapacity"].getInt64(0);
    ApcKeyFrequencyUpdatePeriod = apc["KeyFrequencyUpdatePeriod"].
      getInt32(1000);


    Hdf dns = server["DnsCache"];
    EnableDnsCache = dns["Enable"].getBool();
    DnsCacheTTL = dns["TTL"].getInt32(600); // 10 minutes
    DnsCacheKeyMaturityThreshold = dns["KeyMaturityThreshold"].getInt32(20);
    DnsCacheMaximumCapacity = dns["MaximumCapacity"].getInt64(0);
    DnsCacheKeyFrequencyUpdatePeriod = dns["KeyFrequencyUpdatePeriod"].
      getInt32(1000);

    SharedStores::Create();

    LightProcessFilePrefix =
      server["LightProcessFilePrefix"].getString("./lightprocess");
    LightProcessCount = server["LightProcessCount"].getInt32(0);

    InjectedStacktrace = server["InjectedStacktrace"].getBool();

    ForceServerNameToHeader = server["ForceServerNameToHeader"].getBool();
  }
  {
    Hdf hosts = config["VirtualHost"];
    if (hosts.exists()) {
      for (Hdf hdf = hosts.firstChild(); hdf.exists(); hdf = hdf.next()) {
        if (hdf.getName() == "default") {
          VirtualHost::GetDefault().init(hdf);
        } else {
          VirtualHostPtr host(new VirtualHost(hdf));
          VirtualHosts.push_back(host);
        }
      }
      for (unsigned int i = 0; i < VirtualHosts.size(); i++) {
        if (!VirtualHosts[i]->valid()) {
          throw InvalidArgumentException("virtual host",
                                         "missing prefix or pattern");
        }
      }
    }
  }
  {
    Hdf ipblocks = config["IpBlockMap"];
    IpBlocks = IpBlockMapPtr(new IpBlockMap(ipblocks));
  }
  {
    Hdf satellites = config["Satellites"];
    if (satellites.exists()) {
      for (Hdf hdf = satellites.firstChild(); hdf.exists(); hdf = hdf.next()) {
        SatelliteServerInfoPtr satellite(new SatelliteServerInfo(hdf));
        SatelliteServerInfos.push_back(satellite);
        if (satellite->getType() == SatelliteServer::KindOfRPCServer) {
          XboxPassword = satellite->getPassword();
        }
      }
    }
  }
  {
    Hdf xbox = config["Xbox"];
    XboxServerThreadCount = xbox["ServerThreadCount"].getInt32(0);
    XboxServerPort = xbox["ServerPort"].getInt32(0);
    XboxDefaultLocalTimeoutMilliSeconds =
      xbox["DefaultLocalTimeoutMilliSeconds"].getInt32(500);
    XboxDefaultRemoteTimeoutSeconds =
      xbox["DefaultRemoteTimeoutSeconds"].getInt32(5);
    XboxServerInfoMaxRequest = xbox["ServerInfoMaxRequest"].getInt32(500);
    XboxServerInfoDuration = xbox["ServerInfoDuration"].getInt32(120);
    XboxServerInfoWarmupDoc = xbox["ServerInfoWarmupDoc"].get("");
    XboxServerInfoReqInitFunc = xbox["ServerInfoReqInitFunc"].get("");
    XboxProcessMessageFunc =
      xbox["ProcessMessageFunc"].get("xbox_process_message");
  }
  {
    Hdf content = config["StaticFile"];
    content["Extensions"].get(StaticFileExtensions);
    content["Generators"].get(StaticFileGenerators);
  }
  {
    Hdf admin = config["AdminServer"];
    AdminServerPort = admin["Port"].getInt16(8088);
    AdminThreadCount = admin["ThreadCount"].getInt32(1);
    AdminPassword = admin["Password"].getString();
  }
  {
    Hdf proxy = config["Proxy"];
    ProxyOrigin = proxy["Origin"].getString();
    ProxyRetry = proxy["Retry"].getInt16(3);
    UseServeURLs = proxy["ServeURLs"].getBool();
    proxy["ServeURLs"].get(ServeURLs);
    UseProxyURLs = proxy["ProxyURLs"].getBool();
    ProxyPercentage = proxy["Percentage"].getByte(0);
    proxy["ProxyURLs"].get(ProxyURLs);
  }
  {
    Hdf mysql = config["MySQL"];
    MySQLReadOnly = mysql["ReadOnly"].getBool();
    MySQLLocalize = mysql["Localize"].getBool();
    MySQLConnectTimeout = mysql["ConnectTimeout"].getInt32(1000);
    MySQLReadTimeout = mysql["ReadTimeout"].getInt32(1000);
    MySQLSlowQueryThreshold = mysql["SlowQueryThreshold"].getInt32(1000);
    MySQLKillOnTimeout = mysql["KillOnTimeout"].getBool();
  }
  {
    Hdf http = config["Http"];
    HttpDefaultTimeout = http["DefaultTimeout"].getInt32(30);
    HttpSlowQueryThreshold = http["SlowQueryThreshold"].getInt32(5000);
  }
  {
    Hdf sandbox = config["Sandbox"];
    SocketDefaultTimeout = sandbox["SocketDefaultTimeout"].getInt16(5);
    LocalMemcache = sandbox["LocalMemcache"].getBool();
    MemcacheReadOnly = sandbox["MemcacheReadOnly"].getBool();
  }
  {
    Hdf debug = config["Debug"];
    FullBacktrace = debug["FullBacktrace"].getBool();
    ServerStackTrace = debug["ServerStackTrace"].getBool();
    ServerErrorMessage = debug["ServerErrorMessage"].getBool();
    TranslateSource = debug["TranslateSource"].getBool();
    RecordInput = debug["RecordInput"].getBool();
    ClearInputOnSuccess = debug["ClearInputOnSuccess"].getBool(true);
    ProfilerOutputDir = debug["ProfilerOutputDir"].getString("/tmp");
    CoreDumpEmail = debug["CoreDumpEmail"].getString();
    if (!CoreDumpEmail.empty()) {
      StackTrace::ReportEmail = CoreDumpEmail;
    }
    CoreDumpReport = debug["CoreDumpReport"].getBool(true);
    if (CoreDumpReport) {
      StackTrace::InstallReportOnErrors();
    }
  }
  {
    Hdf stats = config["Stats"];
    EnableStats = stats.getBool(); // main switch

    EnableWebStats = stats["Web"].getBool();
    EnableMemoryStats = stats["Memory"].getBool();
    EnableMallocStats = stats["Malloc"].getBool();
    EnableAPCStats = stats["APC"].getBool();
    EnableAPCKeyStats = stats["APCKey"].getBool();
    EnableMemcacheStats = stats["Memcache"].getBool();
    EnableSQLStats = stats["SQL"].getBool();

    if (EnableStats && EnableMallocStats) {
      LeakDetectable::EnableMallocStats(true);
    }

    StatsXSL = stats["XSL"].getString();
    StatsXSLProxy = stats["XSLProxy"].getString();

    StatsSlotDuration = stats["SlotDuration"].getInt32(10 * 60); // 10 minutes
    StatsMaxSlot = stats["MaxSlot"].getInt32(12 * 6); // 12 hours
  }
  {
    config["ServerVariables"].get(ServerVariables);
    config["EnvVariables"].get(EnvVariables);
  }
  {
    Hdf eval = config["Eval"];
    EnableXHP = eval["EnableXHP"].getBool(true);
    EnableStrict = eval["EnableStrict"].getBool(0);
    StrictLevel = eval["StrictLevel"].getInt32(1); // StrictBasic
    StrictFatal = eval["StrictFatal"].getBool();
    EvalBytecodeInterpreter = eval["BytecodeInterpreter"].getBool(false);
    DumpBytecode = eval["DumpBytecode"].getBool(false);
  }
  {
    Hdf sandbox = config["Sandbox"];
    SandboxMode = sandbox["SandboxMode"].getBool();
    SandboxPattern = format_pattern(sandbox["Pattern"].getString());
    SandboxHome = sandbox["Home"].getString();
    SandboxConfFile = sandbox["ConfFile"].getString();
    sandbox["ServerVariables"].get(SandboxServerVariables);
  }
  {
    Hdf mail = config["Mail"];
    SendmailPath = mail["SendmailPath"].getString("sendmail -t -i");
    MailForceExtraParameters = mail["ForceExtraParameters"].getString();
  }
}