Simplify region selector/pgo options, fix pgo for legacy/tracelet selectors
[hiphop-php.git] / hphp / runtime / base / runtime-option.cpp
blob975bb923bce59de7a2bb761b53bcaa88f29501f6
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/runtime/base/runtime-option.h"
19 #include <cstdint>
20 #include <limits>
22 #include <sys/time.h>
23 #include <sys/resource.h>
25 #include "folly/String.h"
27 #include "hphp/util/hdf.h"
28 #include "hphp/util/util.h"
29 #include "hphp/util/network.h"
30 #include "hphp/util/logger.h"
31 #include "hphp/util/stack-trace.h"
32 #include "hphp/util/process.h"
33 #include "hphp/util/file-cache.h"
34 #include "hphp/util/log-file-flusher.h"
36 #include "hphp/parser/scanner.h"
38 #include "hphp/runtime/server/satellite-server.h"
39 #include "hphp/runtime/server/virtual-host.h"
40 #include "hphp/runtime/server/files-match.h"
41 #include "hphp/runtime/server/access-log.h"
43 #include "hphp/runtime/base/type-conversions.h"
44 #include "hphp/runtime/base/builtin-functions.h"
45 #include "hphp/runtime/base/shared-store-base.h"
46 #include "hphp/runtime/base/extended-logger.h"
47 #include "hphp/runtime/base/simple-counter.h"
48 #include "hphp/runtime/base/memory-manager.h"
49 #include "hphp/runtime/base/hardware-counter.h"
50 #include "hphp/runtime/base/preg.h"
51 #include "hphp/runtime/base/crash-reporter.h"
52 #include "hphp/runtime/base/static-string-table.h"
54 namespace HPHP {
55 ///////////////////////////////////////////////////////////////////////////////
57 bool RuntimeOption::Loaded = false;
59 const char *RuntimeOption::ExecutionMode = "";
60 std::string RuntimeOption::BuildId;
61 std::string RuntimeOption::InstanceId;
62 std::string RuntimeOption::PidFile = "www.pid";
64 std::string RuntimeOption::LogFile;
65 std::string RuntimeOption::LogFileSymLink;
66 int RuntimeOption::LogHeaderMangle;
67 bool RuntimeOption::AlwaysEscapeLog = false;
68 bool RuntimeOption::AlwaysLogUnhandledExceptions = true;
69 bool RuntimeOption::InjectedStackTrace = true;
70 int RuntimeOption::InjectedStackTraceLimit = -1;
71 bool RuntimeOption::NoSilencer = false;
72 bool RuntimeOption::EnableApplicationLog = true;
73 bool RuntimeOption::CallUserHandlerOnFatals = true;
74 bool RuntimeOption::ThrowExceptionOnBadMethodCall = true;
75 int RuntimeOption::RuntimeErrorReportingLevel =
76 static_cast<int>(ErrorConstants::ErrorModes::HPHP_ALL);
78 std::string RuntimeOption::ServerUser;
80 int RuntimeOption::MaxLoopCount = 0;
81 int RuntimeOption::MaxSerializedStringSize = 64 * 1024 * 1024; // 64MB
82 bool RuntimeOption::NoInfiniteRecursionDetection = false;
83 bool RuntimeOption::ThrowBadTypeExceptions = false;
84 bool RuntimeOption::ThrowTooManyArguments = false;
85 bool RuntimeOption::WarnTooManyArguments = false;
86 bool RuntimeOption::ThrowMissingArguments = false;
87 bool RuntimeOption::ThrowInvalidArguments = false;
88 bool RuntimeOption::EnableHipHopErrors = true;
89 bool RuntimeOption::AssertActive = false;
90 bool RuntimeOption::AssertWarning = false;
91 int64_t RuntimeOption::NoticeFrequency = 1;
92 int64_t RuntimeOption::WarningFrequency = 1;
93 int RuntimeOption::RaiseDebuggingFrequency = 1;
94 int64_t RuntimeOption::SerializationSizeLimit = StringData::MaxSize;
95 int64_t RuntimeOption::StringOffsetLimit = 10 * 1024 * 1024; // 10MB
97 std::string RuntimeOption::AccessLogDefaultFormat;
98 std::vector<AccessLogFileData> RuntimeOption::AccessLogs;
100 std::string RuntimeOption::AdminLogFormat;
101 std::string RuntimeOption::AdminLogFile;
102 std::string RuntimeOption::AdminLogSymLink;
105 std::string RuntimeOption::Tier;
106 std::string RuntimeOption::Host;
107 std::string RuntimeOption::DefaultServerNameSuffix;
108 std::string RuntimeOption::ServerType = "libevent";
109 std::string RuntimeOption::ServerIP;
110 std::string RuntimeOption::ServerFileSocket;
111 std::string RuntimeOption::ServerPrimaryIP;
112 int RuntimeOption::ServerPort;
113 int RuntimeOption::ServerPortFd = -1;
114 int RuntimeOption::ServerBacklog = 128;
115 int RuntimeOption::ServerConnectionLimit = 0;
116 int RuntimeOption::ServerThreadCount = 50;
117 bool RuntimeOption::ServerThreadRoundRobin = false;
118 constexpr int kDefaultWarmupThrottleRequestCount = 0;
119 int RuntimeOption::ServerWarmupThrottleRequestCount =
120 kDefaultWarmupThrottleRequestCount;
121 int RuntimeOption::ServerThreadDropCacheTimeoutSeconds = 0;
122 int RuntimeOption::ServerThreadJobLIFOSwitchThreshold = INT_MAX;
123 int RuntimeOption::ServerThreadJobMaxQueuingMilliSeconds = -1;
124 bool RuntimeOption::ServerThreadDropStack = false;
125 bool RuntimeOption::ServerHttpSafeMode = false;
126 bool RuntimeOption::ServerStatCache = false;
127 std::vector<std::string> RuntimeOption::ServerWarmupRequests;
128 boost::container::flat_set<std::string>
129 RuntimeOption::ServerHighPriorityEndPoints;
130 int RuntimeOption::PageletServerThreadCount = 0;
131 bool RuntimeOption::PageletServerThreadRoundRobin = false;
132 int RuntimeOption::PageletServerThreadDropCacheTimeoutSeconds = 0;
133 int RuntimeOption::PageletServerQueueLimit = 0;
134 bool RuntimeOption::PageletServerThreadDropStack = false;
135 int RuntimeOption::FiberCount = 1;
136 int RuntimeOption::RequestTimeoutSeconds = 0;
137 int RuntimeOption::PspTimeoutSeconds = 0;
138 size_t RuntimeOption::ServerMemoryHeadRoom = 0;
139 int64_t RuntimeOption::RequestMemoryMaxBytes =
140 std::numeric_limits<int64_t>::max();
141 int64_t RuntimeOption::ImageMemoryMaxBytes = 0;
142 int RuntimeOption::ResponseQueueCount;
143 int RuntimeOption::ServerGracefulShutdownWait;
144 bool RuntimeOption::ServerHarshShutdown = true;
145 bool RuntimeOption::ServerEvilShutdown = true;
146 int RuntimeOption::ServerDanglingWait;
147 int RuntimeOption::ServerShutdownListenWait = 0;
148 int RuntimeOption::ServerShutdownListenNoWork = -1;
149 int RuntimeOption::GzipCompressionLevel = 3;
150 std::string RuntimeOption::ForceCompressionURL;
151 std::string RuntimeOption::ForceCompressionCookie;
152 std::string RuntimeOption::ForceCompressionParam;
153 bool RuntimeOption::EnableMagicQuotesGpc = false;
154 bool RuntimeOption::EnableKeepAlive = true;
155 bool RuntimeOption::ExposeHPHP = true;
156 bool RuntimeOption::ExposeXFBServer = false;
157 bool RuntimeOption::ExposeXFBDebug = false;
158 std::string RuntimeOption::XFBDebugSSLKey;
159 int RuntimeOption::ConnectionTimeoutSeconds = -1;
160 bool RuntimeOption::EnableOutputBuffering = false;
161 std::string RuntimeOption::OutputHandler;
162 bool RuntimeOption::ImplicitFlush = false;
163 bool RuntimeOption::EnableEarlyFlush = true;
164 bool RuntimeOption::ForceChunkedEncoding = false;
165 int64_t RuntimeOption::MaxPostSize;
166 bool RuntimeOption::AlwaysPopulateRawPostData = true;
167 int64_t RuntimeOption::UploadMaxFileSize;
168 std::string RuntimeOption::UploadTmpDir;
169 bool RuntimeOption::EnableFileUploads;
170 bool RuntimeOption::EnableUploadProgress;
171 int RuntimeOption::Rfc1867Freq;
172 std::string RuntimeOption::Rfc1867Prefix;
173 std::string RuntimeOption::Rfc1867Name;
174 bool RuntimeOption::LibEventSyncSend = true;
175 bool RuntimeOption::ExpiresActive = true;
176 int RuntimeOption::ExpiresDefault = 2592000;
177 std::string RuntimeOption::DefaultCharsetName = "utf-8";
178 bool RuntimeOption::ForceServerNameToHeader = false;
179 bool RuntimeOption::EnableCufAsync = false;
180 bool RuntimeOption::PathDebug = false;
182 int RuntimeOption::RequestBodyReadLimit = -1;
184 bool RuntimeOption::EnableSSL = false;
185 int RuntimeOption::SSLPort = 443;
186 int RuntimeOption::SSLPortFd = -1;
187 std::string RuntimeOption::SSLCertificateFile;
188 std::string RuntimeOption::SSLCertificateKeyFile;
189 std::string RuntimeOption::SSLCertificateDir;
190 bool RuntimeOption::TLSDisableTLS1_2;
191 std::string RuntimeOption::TLSClientCipherSpec;
193 std::vector<std::shared_ptr<VirtualHost>> RuntimeOption::VirtualHosts;
194 std::shared_ptr<IpBlockMap> RuntimeOption::IpBlocks;
195 std::vector<std::shared_ptr<SatelliteServerInfo>>
196 RuntimeOption::SatelliteServerInfos;
198 int RuntimeOption::XboxServerThreadCount = 10;
199 int RuntimeOption::XboxServerMaxQueueLength = INT_MAX;
200 int RuntimeOption::XboxServerPort = 0;
201 int RuntimeOption::XboxDefaultLocalTimeoutMilliSeconds = 500;
202 int RuntimeOption::XboxDefaultRemoteTimeoutSeconds = 5;
203 int RuntimeOption::XboxServerInfoMaxRequest = 500;
204 int RuntimeOption::XboxServerInfoDuration = 120;
205 std::string RuntimeOption::XboxServerInfoWarmupDoc;
206 std::string RuntimeOption::XboxServerInfoReqInitFunc;
207 std::string RuntimeOption::XboxServerInfoReqInitDoc;
208 bool RuntimeOption::XboxServerInfoAlwaysReset = false;
209 bool RuntimeOption::XboxServerLogInfo = false;
210 std::string RuntimeOption::XboxProcessMessageFunc = "xbox_process_message";
211 std::string RuntimeOption::XboxPassword;
212 std::set<std::string> RuntimeOption::XboxPasswords;
214 std::string RuntimeOption::SourceRoot = Process::GetCurrentDirectory() + '/';
215 std::vector<std::string> RuntimeOption::IncludeSearchPaths;
216 std::string RuntimeOption::FileCache;
217 std::string RuntimeOption::DefaultDocument;
218 std::string RuntimeOption::ErrorDocument404;
219 bool RuntimeOption::ForbiddenAs404 = false;
220 std::string RuntimeOption::ErrorDocument500;
221 std::string RuntimeOption::FatalErrorMessage;
222 std::string RuntimeOption::FontPath;
223 bool RuntimeOption::EnableStaticContentFromDisk = true;
224 bool RuntimeOption::EnableOnDemandUncompress = true;
225 bool RuntimeOption::EnableStaticContentMMap = true;
227 bool RuntimeOption::Utf8izeReplace = true;
229 std::string RuntimeOption::StartupDocument;
230 std::string RuntimeOption::WarmupDocument;
231 std::string RuntimeOption::RequestInitFunction;
232 std::string RuntimeOption::RequestInitDocument;
233 std::vector<std::string> RuntimeOption::ThreadDocuments;
234 std::vector<std::string> RuntimeOption::ThreadLoopDocuments;
236 bool RuntimeOption::SafeFileAccess = false;
237 std::vector<std::string> RuntimeOption::AllowedDirectories;
238 std::set<std::string> RuntimeOption::AllowedFiles;
239 hphp_string_imap<std::string> RuntimeOption::StaticFileExtensions;
240 hphp_string_imap<std::string> RuntimeOption::PhpFileExtensions;
241 std::set<std::string> RuntimeOption::ForbiddenFileExtensions;
242 std::set<std::string> RuntimeOption::StaticFileGenerators;
243 std::vector<std::shared_ptr<FilesMatch>> RuntimeOption::FilesMatches;
245 bool RuntimeOption::WhitelistExec = false;
246 bool RuntimeOption::WhitelistExecWarningOnly = false;
247 std::vector<std::string> RuntimeOption::AllowedExecCmds;
249 bool RuntimeOption::UnserializationWhitelistCheck = false;
250 bool RuntimeOption::UnserializationWhitelistCheckWarningOnly = true;
252 std::string RuntimeOption::TakeoverFilename;
253 int RuntimeOption::AdminServerPort;
254 int RuntimeOption::AdminThreadCount = 1;
255 std::string RuntimeOption::AdminPassword;
256 std::set<std::string> RuntimeOption::AdminPasswords;
258 std::string RuntimeOption::ProxyOrigin;
259 int RuntimeOption::ProxyRetry = 3;
260 bool RuntimeOption::UseServeURLs;
261 std::set<std::string> RuntimeOption::ServeURLs;
262 bool RuntimeOption::UseProxyURLs;
263 int RuntimeOption::ProxyPercentage = 0;
264 std::set<std::string> RuntimeOption::ProxyURLs;
265 std::vector<std::string> RuntimeOption::ProxyPatterns;
266 bool RuntimeOption::AlwaysUseRelativePath = false;
267 std::string RuntimeOption::IniFile = "/etc/hhvm/php.ini";
269 int RuntimeOption::HttpDefaultTimeout = 30;
270 int RuntimeOption::HttpSlowQueryThreshold = 5000; // ms
272 bool RuntimeOption::TranslateLeakStackTrace = false;
273 bool RuntimeOption::NativeStackTrace = false;
274 bool RuntimeOption::FullBacktrace = false;
275 bool RuntimeOption::ServerStackTrace = false;
276 bool RuntimeOption::ServerErrorMessage = false;
277 bool RuntimeOption::TranslateSource = false;
278 bool RuntimeOption::RecordInput = false;
279 bool RuntimeOption::ClearInputOnSuccess = true;
280 std::string RuntimeOption::ProfilerOutputDir;
281 std::string RuntimeOption::CoreDumpEmail;
282 bool RuntimeOption::CoreDumpReport = true;
283 std::string RuntimeOption::CoreDumpReportDirectory
284 #if defined(HPHP_OSS)
285 ("/tmp");
286 #else
287 ("/var/tmp/cores");
288 #endif
289 bool RuntimeOption::LocalMemcache = false;
290 bool RuntimeOption::MemcacheReadOnly = false;
292 bool RuntimeOption::EnableStats = false;
293 bool RuntimeOption::EnableWebStats = false;
294 bool RuntimeOption::EnableMemoryStats = false;
295 bool RuntimeOption::EnableMemcacheStats = false;
296 bool RuntimeOption::EnableMemcacheKeyStats = false;
297 bool RuntimeOption::EnableSQLStats = false;
298 bool RuntimeOption::EnableSQLTableStats = false;
299 bool RuntimeOption::EnableNetworkIOStatus = false;
300 std::string RuntimeOption::StatsXSL;
301 std::string RuntimeOption::StatsXSLProxy;
302 int RuntimeOption::StatsSlotDuration = 10 * 60; // 10 minutes
303 int RuntimeOption::StatsMaxSlot = 12 * 6; // 12 hours
305 int64_t RuntimeOption::MaxRSS = 0;
306 int64_t RuntimeOption::MaxRSSPollingCycle = 0;
307 int64_t RuntimeOption::DropCacheCycle = 0;
308 int64_t RuntimeOption::MaxSQLRowCount = 10000;
309 int64_t RuntimeOption::MaxMemcacheKeyCount = 0;
310 int64_t RuntimeOption::SocketDefaultTimeout = 5;
311 bool RuntimeOption::LockCodeMemory = false;
312 int RuntimeOption::MaxArrayChain = INT_MAX;
313 bool RuntimeOption::WarnOnCollectionToArray = false;
314 bool RuntimeOption::UseDirectCopy = false;
316 bool RuntimeOption::EnableDnsCache = false;
317 int RuntimeOption::DnsCacheTTL = 10 * 60; // 10 minutes
318 time_t RuntimeOption::DnsCacheKeyMaturityThreshold = 20;
319 size_t RuntimeOption::DnsCacheMaximumCapacity = 0;
320 int RuntimeOption::DnsCacheKeyFrequencyUpdatePeriod = 1000;
322 std::map<std::string, std::string> RuntimeOption::ServerVariables;
323 std::map<std::string, std::string> RuntimeOption::EnvVariables;
325 std::string RuntimeOption::LightProcessFilePrefix;
326 int RuntimeOption::LightProcessCount;
328 bool RuntimeOption::EnableHipHopSyntax = false;
329 bool RuntimeOption::EnableHipHopExperimentalSyntax = false;
330 bool RuntimeOption::EnableShortTags = true;
331 bool RuntimeOption::EnableAspTags = false;
332 bool RuntimeOption::EnableXHP = false;
333 bool RuntimeOption::EnableObjDestructCall = false;
334 bool RuntimeOption::EnableEmitSwitch = true;
335 bool RuntimeOption::EnableEmitterStats = true;
336 bool RuntimeOption::EnableInstructionCounts = false;
337 bool RuntimeOption::CheckSymLink = true;
338 int RuntimeOption::MaxUserFunctionId = (2 * 65536);
339 bool RuntimeOption::EnableArgsInBacktraces = true;
340 bool RuntimeOption::EnableZendCompat = false;
341 bool RuntimeOption::TimeoutsUseWallTime = true;
343 int RuntimeOption::GetScannerType() {
344 int type = 0;
345 if (EnableShortTags) type |= Scanner::AllowShortTags;
346 if (EnableAspTags) type |= Scanner::AllowAspTags;
347 if (EnableXHP) type |= Scanner::AllowXHPSyntax;
348 if (EnableHipHopSyntax) type |= Scanner::AllowHipHopSyntax;
349 return type;
352 // Initializers for Eval flags.
353 static inline bool evalJitDefault() {
354 // --mode server or --mode daemon
355 // run long enough to justify JIT
356 if (RuntimeOption::ServerExecutionMode()) {
357 return true;
360 // JIT explicitly turned on via .hhvm-jit file
361 static const char* path = "/.hhvm-jit";
362 struct stat dummy;
363 return stat(path, &dummy) == 0;
366 static inline std::string regionSelectorDefault() {
367 #ifdef HHVM_REGION_SELECTOR_TRACELET
368 return "tracelet";
369 #else
370 #ifdef HHVM_REGION_SELECTOR_LEGACY
371 return "legacy";
372 #else
373 return "";
374 #endif
375 #endif
378 static inline bool pgoDefault() {
379 // TODO(3496304)
380 return !RuntimeOption::EvalSimulateARM;
383 static inline bool hhirRelaxGuardsDefault() {
384 return RuntimeOption::EvalJitRegionSelector == "tracelet";
387 static inline bool hhbcRelaxGuardsDefault() {
388 return !RuntimeOption::EvalHHIRRelaxGuards;
391 static inline bool simulateARMDefault() {
392 #ifdef HHVM_SIMULATE_ARM_BY_DEFAULT
393 return true;
394 #else
395 return false;
396 #endif
399 static inline bool hugePagesSoundNice() {
400 return RuntimeOption::ServerExecutionMode();
403 const uint64_t kEvalVMStackElmsDefault =
404 #ifdef VALGRIND
405 0x800
406 #else
407 0x4000
408 #endif
410 const uint32_t kEvalVMInitialGlobalTableSizeDefault = 512;
411 static const int kDefaultWarmupRequests = debug ? 1 : 11;
412 static const int kDefaultJitPGOThreshold = debug ? 2 : 4;
413 static const uint32_t kDefaultProfileRequests = debug ? 1 << 31 : 500;
414 static const size_t kJitGlobalDataDef = RuntimeOption::EvalJitASize >> 2;
415 inline size_t maxUsageDef() {
416 return RuntimeOption::EvalJitASize;
418 using std::string;
419 #define F(type, name, def) \
420 type RuntimeOption::Eval ## name = type(def);
421 EVALFLAGS();
422 #undef F
423 std::set<string, stdltistr> RuntimeOption::DynamicInvokeFunctions;
424 bool RuntimeOption::RecordCodeCoverage = false;
425 std::string RuntimeOption::CodeCoverageOutputFile;
427 std::string RuntimeOption::RepoLocalMode;
428 std::string RuntimeOption::RepoLocalPath;
429 std::string RuntimeOption::RepoCentralPath;
430 std::string RuntimeOption::RepoEvalMode;
431 std::string RuntimeOption::RepoJournal;
432 bool RuntimeOption::RepoCommit = true;
433 bool RuntimeOption::RepoDebugInfo = true;
434 // Missing: RuntimeOption::RepoAuthoritative's physical location is
435 // perf-sensitive.
437 bool RuntimeOption::SandboxMode = false;
438 std::string RuntimeOption::SandboxPattern;
439 std::string RuntimeOption::SandboxHome;
440 std::string RuntimeOption::SandboxFallback;
441 std::string RuntimeOption::SandboxConfFile;
442 std::map<std::string, std::string> RuntimeOption::SandboxServerVariables;
443 bool RuntimeOption::SandboxFromCommonRoot;
444 std::string RuntimeOption::SandboxDirectoriesRoot;
445 std::string RuntimeOption::SandboxLogsRoot;
447 bool RuntimeOption::EnableDebugger = false;
448 bool RuntimeOption::EnableDebuggerColor = true;
449 bool RuntimeOption::EnableDebuggerPrompt = true;
450 bool RuntimeOption::EnableDebuggerServer = false;
451 bool RuntimeOption::EnableDebuggerUsageLog = false;
452 bool RuntimeOption::DebuggerDisableIPv6 = false;
453 int RuntimeOption::DebuggerServerPort = 8089;
454 int RuntimeOption::DebuggerDefaultRpcPort = 8083;
455 std::string RuntimeOption::DebuggerDefaultRpcAuth;
456 std::string RuntimeOption::DebuggerRpcHostDomain;
457 int RuntimeOption::DebuggerDefaultRpcTimeout = 30;
458 std::string RuntimeOption::DebuggerDefaultSandboxPath;
459 std::string RuntimeOption::DebuggerStartupDocument;
460 int RuntimeOption::DebuggerSignalTimeout = 1;
462 std::string RuntimeOption::SendmailPath;
463 std::string RuntimeOption::MailForceExtraParameters;
465 long RuntimeOption::PregBacktraceLimit = 1000000;
466 long RuntimeOption::PregRecursionLimit = 100000;
467 bool RuntimeOption::EnablePregErrorLog = true;
469 bool RuntimeOption::HHProfServerEnabled = false;
470 int RuntimeOption::HHProfServerPort = 4327;
471 int RuntimeOption::HHProfServerThreads = 2;
472 int RuntimeOption::HHProfServerTimeoutSeconds = 30;
473 bool RuntimeOption::HHProfServerProfileClientMode = true;
474 bool RuntimeOption::HHProfServerAllocationProfile = false;
475 int RuntimeOption::HHProfServerFilterMinAllocPerReq = 2;
476 int RuntimeOption::HHProfServerFilterMinBytesPerReq = 128;
478 // TODO (t3610856): Change the default to false once dependent code is fixed
479 bool RuntimeOption::SimpleXMLEmptyNamespaceMatchesAll = true;
481 bool RuntimeOption::EnableHotProfiler = true;
482 int RuntimeOption::ProfilerTraceBuffer = 2000000;
483 double RuntimeOption::ProfilerTraceExpansion = 1.2;
484 int RuntimeOption::ProfilerMaxTraceBuffer = 0;
486 #ifdef FACEBOOK
487 bool RuntimeOption::EnableFb303Server = true;
488 int RuntimeOption::Fb303ServerPort;
489 int RuntimeOption::Fb303ServerThreadStackSizeMb = 8;
490 int RuntimeOption::Fb303ServerWorkerThreads = 1;
491 int RuntimeOption::Fb303ServerPoolThreads = 1;
492 #endif
494 int RuntimeOption::EnableAlternative = 0;
496 ///////////////////////////////////////////////////////////////////////////////
498 static void setResourceLimit(int resource, Hdf rlimit, const char *nodeName) {
499 if (!rlimit[nodeName].getString().empty()) {
500 struct rlimit rl;
501 getrlimit(resource, &rl);
502 rl.rlim_cur = rlimit[nodeName].getInt64();
503 if (rl.rlim_max < rl.rlim_cur) {
504 rl.rlim_max = rl.rlim_cur;
506 int ret = setrlimit(resource, &rl);
507 if (ret) {
508 Logger::Error("Unable to set %s to %" PRId64 ": %s (%d)",
509 nodeName, (int64_t)rl.rlim_cur,
510 folly::errnoStr(errno).c_str(), errno);
515 static void normalizePath(std::string &path) {
516 if (!path.empty()) {
517 if (path[path.length() - 1] == '/') {
518 path = path.substr(0, path.length() - 1);
520 if (path[0] != '/') {
521 path = std::string("/") + path;
526 static bool matchHdfPattern(const std::string &value, Hdf hdfPattern) {
527 string pattern = hdfPattern.getString();
528 if (!pattern.empty()) {
529 Variant ret = preg_match(String(pattern.c_str(), pattern.size(),
530 CopyString),
531 String(value.c_str(), value.size(),
532 CopyString));
533 if (ret.toInt64() <= 0) {
534 return false;
537 return true;
540 void RuntimeOption::Load(Hdf &config,
541 std::vector<std::string> *overwrites /* = NULL */,
542 bool empty /* = false */) {
543 // Machine metrics
544 string hostname, tier, cpu;
546 Hdf machine = config["Machine"];
548 hostname = machine["name"].getString();
549 if (hostname.empty()) {
550 hostname = Process::GetHostName();
553 tier = machine["tier"].getString();
555 cpu = machine["cpu"].getString();
556 if (cpu.empty()) {
557 cpu = Process::GetCPUModel();
561 if (overwrites) {
562 // Do these first, mainly so we can override Tier.*.machine,
563 // Tier.*.tier and Tier.*.cpu on the command line. But it can
564 // also make sense to override fields within a Tier (
565 // eg if you are using the same command line across a lot
566 // of different machines)
567 for (unsigned int i = 0; i < overwrites->size(); i++) {
568 config.fromString(overwrites->at(i).c_str());
572 // Tier overwrites
574 Hdf tiers = config["Tiers"];
575 for (Hdf hdf = tiers.firstChild(); hdf.exists(); hdf = hdf.next()) {
576 if (matchHdfPattern(hostname, hdf["machine"]) &&
577 matchHdfPattern(tier, hdf["tier"]) &&
578 matchHdfPattern(cpu, hdf["cpu"])) {
579 Tier = hdf.getName();
580 config.copy(hdf["overwrite"]);
581 // no break here, so we can continue to match more overwrites
583 hdf["overwrite"].setVisited(); // avoid lint complaining
587 if (overwrites) {
588 // Do the command line overrides again, so we override
589 // any tier overwrites
590 for (unsigned int i = 0; i < overwrites->size(); i++) {
591 config.fromString(overwrites->at(i).c_str());
595 PidFile = config["PidFile"].getString("www.pid");
597 config["DynamicInvokeFunctions"].get(DynamicInvokeFunctions);
600 Hdf logger = config["Log"];
601 if (logger["Level"] == "None") {
602 Logger::LogLevel = Logger::LogNone;
603 } else if (logger["Level"] == "Error") {
604 Logger::LogLevel = Logger::LogError;
605 } else if (logger["Level"] == "Warning") {
606 Logger::LogLevel = Logger::LogWarning;
607 } else if (logger["Level"] == "Info") {
608 Logger::LogLevel = Logger::LogInfo;
609 } else if (logger["Level"] == "Verbose") {
610 Logger::LogLevel = Logger::LogVerbose;
612 Logger::LogHeader = logger["Header"].getBool();
613 bool logInjectedStackTrace = logger["InjectedStackTrace"].getBool();
614 if (logInjectedStackTrace) {
615 Logger::SetTheLogger(new ExtendedLogger());
616 ExtendedLogger::EnabledByDefault = true;
618 Logger::LogNativeStackTrace = logger["NativeStackTrace"].getBool(true);
619 Logger::MaxMessagesPerRequest =
620 logger["MaxMessagesPerRequest"].getInt32(-1);
622 Logger::UseSyslog = logger["UseSyslog"].getBool(false);
623 Logger::UseLogFile = logger["UseLogFile"].getBool(true);
624 Logger::UseCronolog = logger["UseCronolog"].getBool(false);
625 if (Logger::UseLogFile) {
626 LogFile = logger["File"].getString();
627 if (!RuntimeOption::ServerExecutionMode()) {
628 LogFile.clear();
630 if (LogFile[0] == '|') Logger::IsPipeOutput = true;
631 LogFileSymLink = logger["SymLink"].getString();
633 LogFileFlusher::DropCacheChunkSize =
634 logger["DropCacheChunkSize"].getInt32(1 << 20);
635 AlwaysEscapeLog = logger["AlwaysEscapeLog"].getBool(false);
636 RuntimeOption::LogHeaderMangle = logger["HeaderMangle"].getInt32(0);
638 AlwaysLogUnhandledExceptions =
639 logger["AlwaysLogUnhandledExceptions"].getBool(true);
640 NoSilencer = logger["NoSilencer"].getBool();
641 EnableApplicationLog = logger["ApplicationLog"].getBool(true);
642 RuntimeErrorReportingLevel =
643 logger["RuntimeErrorReportingLevel"]
644 .getInt32(static_cast<int>(ErrorConstants::ErrorModes::HPHP_ALL));
646 AccessLogDefaultFormat = logger["AccessLogDefaultFormat"].
647 getString("%h %l %u %t \"%r\" %>s %b");
649 Hdf access = logger["Access"];
650 for (Hdf hdf = access.firstChild(); hdf.exists();
651 hdf = hdf.next()) {
652 string fname = hdf["File"].getString();
653 if (fname.empty()) {
654 continue;
656 string symLink = hdf["SymLink"].getString();
657 AccessLogs.
658 push_back(AccessLogFileData(fname, symLink, hdf["Format"].
659 getString(AccessLogDefaultFormat)));
663 AdminLogFormat = logger["AdminLog.Format"].getString("%h %t %s %U");
664 AdminLogFile = logger["AdminLog.File"].getString();
665 AdminLogSymLink = logger["AdminLog.SymLink"].getString();
668 Hdf error = config["ErrorHandling"];
670 /* Remove this, once its removed from production configs */
671 (void)error["NoInfiniteLoopDetection"].getBool();
673 MaxSerializedStringSize =
674 error["MaxSerializedStringSize"].getInt32(64 * 1024 * 1024);
675 CallUserHandlerOnFatals = error["CallUserHandlerOnFatals"].getBool(true);
676 ThrowExceptionOnBadMethodCall =
677 error["ThrowExceptionOnBadMethodCall"].getBool(true);
678 MaxLoopCount = error["MaxLoopCount"].getInt32(0);
679 NoInfiniteRecursionDetection =
680 error["NoInfiniteRecursionDetection"].getBool();
681 ThrowBadTypeExceptions = error["ThrowBadTypeExceptions"].getBool();
682 ThrowTooManyArguments = error["ThrowTooManyArguments"].getBool();
683 WarnTooManyArguments = error["WarnTooManyArguments"].getBool();
684 ThrowMissingArguments = error["ThrowMissingArguments"].getBool();
685 ThrowInvalidArguments = error["ThrowInvalidArguments"].getBool();
686 EnableHipHopErrors = error["EnableHipHopErrors"].getBool(true);
687 AssertActive = error["AssertActive"].getBool();
688 AssertWarning = error["AssertWarning"].getBool();
689 NoticeFrequency = error["NoticeFrequency"].getInt64(1);
690 WarningFrequency = error["WarningFrequency"].getInt64(1);
693 Hdf rlimit = config["ResourceLimit"];
694 if (rlimit["CoreFileSizeOverride"].getInt64()) {
695 setResourceLimit(RLIMIT_CORE, rlimit, "CoreFileSizeOverride");
696 } else {
697 setResourceLimit(RLIMIT_CORE, rlimit, "CoreFileSize");
699 setResourceLimit(RLIMIT_NOFILE, rlimit, "MaxSocket");
700 setResourceLimit(RLIMIT_DATA, rlimit, "RSS");
701 MaxRSS = rlimit["MaxRSS"].getInt64(0);
702 SocketDefaultTimeout = rlimit["SocketDefaultTimeout"].getInt64(5);
703 MaxRSSPollingCycle = rlimit["MaxRSSPollingCycle"].getInt64(0);
704 DropCacheCycle = rlimit["DropCacheCycle"].getInt64(0);
705 MaxSQLRowCount = rlimit["MaxSQLRowCount"].getInt64(0);
706 MaxMemcacheKeyCount = rlimit["MaxMemcacheKeyCount"].getInt64(0);
707 SerializationSizeLimit =
708 rlimit["SerializationSizeLimit"].getInt64(StringData::MaxSize);
709 StringOffsetLimit = rlimit["StringOffsetLimit"].getInt64(10 * 1024 * 1024);
712 Hdf server = config["Server"];
713 Host = server["Host"].getString();
714 DefaultServerNameSuffix = server["DefaultServerNameSuffix"].getString();
715 ServerType = server["Type"].getString(ServerType);
716 ServerIP = server["IP"].getString();
717 ServerFileSocket = server["FileSocket"].getString();
718 ServerPrimaryIP = Util::GetPrimaryIP();
719 ServerPort = server["Port"].getUInt16(80);
720 ServerBacklog = server["Backlog"].getInt16(128);
721 ServerConnectionLimit = server["ConnectionLimit"].getInt16(0);
722 ServerThreadCount = server["ThreadCount"].getInt32(50);
723 ServerThreadRoundRobin = server["ThreadRoundRobin"].getBool();
724 ServerWarmupThrottleRequestCount =
725 server["WarmupThrottleRequestCount"].getInt32(
726 kDefaultWarmupThrottleRequestCount
728 ServerThreadDropCacheTimeoutSeconds =
729 server["ThreadDropCacheTimeoutSeconds"].getInt32(0);
730 if (server["ThreadJobLIFO"].getBool()) {
731 ServerThreadJobLIFOSwitchThreshold = 0;
733 ServerThreadJobLIFOSwitchThreshold =
734 server["ThreadJobLIFOSwitchThreshold"].getInt32(
735 ServerThreadJobLIFOSwitchThreshold);
736 ServerThreadJobMaxQueuingMilliSeconds =
737 server["ThreadJobMaxQueuingMilliSeconds"].getInt16(-1);
738 ServerThreadDropStack = server["ThreadDropStack"].getBool();
739 ServerHttpSafeMode = server["HttpSafeMode"].getBool();
740 ServerStatCache = server["StatCache"].getBool(false);
741 server["WarmupRequests"].get(ServerWarmupRequests);
742 server["HighPriorityEndPoints"].get(ServerHighPriorityEndPoints);
744 RequestTimeoutSeconds = server["RequestTimeoutSeconds"].getInt32(0);
745 PspTimeoutSeconds = server["PspTimeoutSeconds"].getInt32(0);
746 ServerMemoryHeadRoom = server["MemoryHeadRoom"].getInt64(0);
747 RequestMemoryMaxBytes = server["RequestMemoryMaxBytes"].
748 getInt64(std::numeric_limits<int64_t>::max());
749 ResponseQueueCount = server["ResponseQueueCount"].getInt32(0);
750 if (ResponseQueueCount <= 0) {
751 ResponseQueueCount = ServerThreadCount / 10;
752 if (ResponseQueueCount <= 0) ResponseQueueCount = 1;
754 ServerGracefulShutdownWait = server["GracefulShutdownWait"].getInt16(0);
755 ServerHarshShutdown = server["HarshShutdown"].getBool(true);
756 ServerEvilShutdown = server["EvilShutdown"].getBool(true);
757 ServerDanglingWait = server["DanglingWait"].getInt16(0);
758 ServerShutdownListenWait = server["ShutdownListenWait"].getInt16(0);
759 ServerShutdownListenNoWork = server["ShutdownListenNoWork"].getInt16(-1);
760 if (ServerGracefulShutdownWait < ServerDanglingWait) {
761 ServerGracefulShutdownWait = ServerDanglingWait;
763 GzipCompressionLevel = server["GzipCompressionLevel"].getInt16(3);
765 ForceCompressionURL = server["ForceCompression"]["URL"].getString();
766 ForceCompressionCookie = server["ForceCompression"]["Cookie"].getString();
767 ForceCompressionParam = server["ForceCompression"]["Param"].getString();
769 EnableMagicQuotesGpc = server["EnableMagicQuotesGpc"].getBool();
770 EnableKeepAlive = server["EnableKeepAlive"].getBool(true);
771 ExposeHPHP = server["ExposeHPHP"].getBool(true);
772 ExposeXFBServer = server["ExposeXFBServer"].getBool(false);
773 ExposeXFBDebug = server["ExposeXFBDebug"].getBool(false);
774 XFBDebugSSLKey = server["XFBDebugSSLKey"].getString("");
775 ConnectionTimeoutSeconds = server["ConnectionTimeoutSeconds"].getInt16(-1);
776 EnableOutputBuffering = server["EnableOutputBuffering"].getBool();
777 OutputHandler = server["OutputHandler"].getString();
778 ImplicitFlush = server["ImplicitFlush"].getBool();
779 EnableEarlyFlush = server["EnableEarlyFlush"].getBool(true);
780 ForceChunkedEncoding = server["ForceChunkedEncoding"].getBool();
781 MaxPostSize = (server["MaxPostSize"].getInt32(100)) * (1LL << 20);
782 AlwaysPopulateRawPostData =
783 server["AlwaysPopulateRawPostData"].getBool(true);
784 LibEventSyncSend = server["LibEventSyncSend"].getBool(true);
785 TakeoverFilename = server["TakeoverFilename"].getString();
786 ExpiresActive = server["ExpiresActive"].getBool(true);
787 ExpiresDefault = server["ExpiresDefault"].getInt32(2592000);
788 if (ExpiresDefault < 0) ExpiresDefault = 2592000;
789 DefaultCharsetName = server["DefaultCharsetName"].getString("utf-8");
791 RequestBodyReadLimit = server["RequestBodyReadLimit"].getInt32(-1);
793 EnableSSL = server["EnableSSL"].getBool();
794 SSLPort = server["SSLPort"].getUInt16(443);
795 SSLCertificateFile = server["SSLCertificateFile"].getString();
796 SSLCertificateKeyFile = server["SSLCertificateKeyFile"].getString();
797 SSLCertificateDir = server["SSLCertificateDir"].getString();
798 TLSDisableTLS1_2 = server["TLSDisableTLS1_2"].getBool(false);
799 TLSClientCipherSpec = server["TLSClientCipherSpec"].getString();
801 string srcRoot = Util::normalizeDir(server["SourceRoot"].getString());
802 if (!srcRoot.empty()) SourceRoot = srcRoot;
803 FileCache::SourceRoot = SourceRoot;
805 server["IncludeSearchPaths"].get(IncludeSearchPaths);
806 for (unsigned int i = 0; i < IncludeSearchPaths.size(); i++) {
807 IncludeSearchPaths[i] = Util::normalizeDir(IncludeSearchPaths[i]);
809 IncludeSearchPaths.insert(IncludeSearchPaths.begin(), ".");
811 FileCache = server["FileCache"].getString();
812 DefaultDocument = server["DefaultDocument"].getString();
813 ErrorDocument404 = server["ErrorDocument404"].getString();
814 normalizePath(ErrorDocument404);
815 ForbiddenAs404 = server["ForbiddenAs404"].getBool();
816 ErrorDocument500 = server["ErrorDocument500"].getString();
817 normalizePath(ErrorDocument500);
818 FatalErrorMessage = server["FatalErrorMessage"].getString();
819 FontPath = Util::normalizeDir(server["FontPath"].getString());
820 EnableStaticContentFromDisk =
821 server["EnableStaticContentFromDisk"].getBool(true);
822 EnableOnDemandUncompress =
823 server["EnableOnDemandUncompress"].getBool(true);
824 EnableStaticContentMMap =
825 server["EnableStaticContentMMap"].getBool(true);
826 if (EnableStaticContentMMap) {
827 EnableOnDemandUncompress = true;
829 Utf8izeReplace = server["Utf8izeReplace"].getBool(true);
831 StartupDocument = server["StartupDocument"].getString();
832 normalizePath(StartupDocument);
833 WarmupDocument = server["WarmupDocument"].getString();
834 RequestInitFunction = server["RequestInitFunction"].getString();
835 RequestInitDocument = server["RequestInitDocument"].getString();
836 server["ThreadDocuments"].get(ThreadDocuments);
837 for (unsigned int i = 0; i < ThreadDocuments.size(); i++) {
838 normalizePath(ThreadDocuments[i]);
840 server["ThreadLoopDocuments"].get(ThreadLoopDocuments);
841 for (unsigned int i = 0; i < ThreadLoopDocuments.size(); i++) {
842 normalizePath(ThreadLoopDocuments[i]);
845 SafeFileAccess = server["SafeFileAccess"].getBool();
846 server["AllowedDirectories"].get(AllowedDirectories);
848 WhitelistExec = server["WhitelistExec"].getBool();
849 WhitelistExecWarningOnly = server["WhitelistExecWarningOnly"].getBool();
850 server["AllowedExecCmds"].get(AllowedExecCmds);
852 UnserializationWhitelistCheck =
853 server["UnserializationWhitelistCheck"].getBool(false);
854 UnserializationWhitelistCheckWarningOnly =
855 server["UnserializationWhitelistCheckWarningOnly"].getBool(true);
857 server["AllowedFiles"].get(AllowedFiles);
859 server["ForbiddenFileExtensions"].get(ForbiddenFileExtensions);
861 LockCodeMemory = server["LockCodeMemory"].getBool(false);
862 MaxArrayChain = server["MaxArrayChain"].getInt32(INT_MAX);
863 if (MaxArrayChain != INT_MAX) {
864 // HphpArray needs a higher threshold to avoid false-positives.
865 // (and we always use HphpArray)
866 MaxArrayChain *= 2;
869 WarnOnCollectionToArray = server["WarnOnCollectionToArray"].getBool(false);
870 UseDirectCopy = server["UseDirectCopy"].getBool(false);
871 AlwaysUseRelativePath = server["AlwaysUseRelativePath"].getBool(false);
873 IniFile = server["IniFile"].getString(IniFile);
874 if (access(IniFile.c_str(), R_OK) == -1) {
875 if (IniFile != "/etc/hhvm/php.ini") {
876 Logger::Error("INI file doesn't exist: %s", IniFile.c_str());
878 IniFile.clear();
881 Hdf dns = server["DnsCache"];
882 EnableDnsCache = dns["Enable"].getBool();
883 DnsCacheTTL = dns["TTL"].getInt32(600); // 10 minutes
884 DnsCacheKeyMaturityThreshold = dns["KeyMaturityThreshold"].getInt32(20);
885 DnsCacheMaximumCapacity = dns["MaximumCapacity"].getInt64(0);
886 DnsCacheKeyFrequencyUpdatePeriod = dns["KeyFrequencyUpdatePeriod"].
887 getInt32(1000);
889 Hdf upload = server["Upload"];
890 UploadMaxFileSize =
891 (upload["UploadMaxFileSize"].getInt32(100)) * (1LL << 20);
892 UploadTmpDir = upload["UploadTmpDir"].getString("/tmp");
893 RuntimeOption::AllowedDirectories.push_back(UploadTmpDir);
894 EnableFileUploads = upload["EnableFileUploads"].getBool(true);
895 EnableUploadProgress = upload["EnableUploadProgress"].getBool();
896 Rfc1867Freq = upload["Rfc1867Freq"].getInt32(256 * 1024);
897 if (Rfc1867Freq < 0) Rfc1867Freq = 256 * 1024;
898 Rfc1867Prefix = upload["Rfc1867Prefix"].getString("vupload_");
899 Rfc1867Name = upload["Rfc1867Name"].getString("video_ptoken");
901 ImageMemoryMaxBytes = server["ImageMemoryMaxBytes"].getInt64(0);
902 if (ImageMemoryMaxBytes == 0) {
903 ImageMemoryMaxBytes = UploadMaxFileSize * 2;
905 SharedStores::Create();
907 LightProcessFilePrefix =
908 server["LightProcessFilePrefix"].getString("./lightprocess");
909 LightProcessCount = server["LightProcessCount"].getInt32(0);
911 InjectedStackTrace = server["InjectedStackTrace"].getBool(true);
912 InjectedStackTraceLimit = server["InjectedStackTraceLimit"].getInt32(-1);
914 ForceServerNameToHeader = server["ForceServerNameToHeader"].getBool();
916 EnableCufAsync = server["EnableCufAsync"].getBool(false);
917 PathDebug = server["PathDebug"].getBool(false);
919 ServerUser = server["User"].getString("");
922 VirtualHost::SortAllowedDirectories(AllowedDirectories);
924 Hdf hosts = config["VirtualHost"];
925 if (hosts.exists()) {
926 for (Hdf hdf = hosts.firstChild(); hdf.exists(); hdf = hdf.next()) {
927 if (hdf.getName() == "default") {
928 VirtualHost::GetDefault().init(hdf);
929 VirtualHost::GetDefault().addAllowedDirectories(AllowedDirectories);
930 } else {
931 auto host = std::make_shared<VirtualHost>(hdf);
932 host->addAllowedDirectories(AllowedDirectories);
933 VirtualHosts.push_back(host);
936 for (unsigned int i = 0; i < VirtualHosts.size(); i++) {
937 if (!VirtualHosts[i]->valid()) {
938 throw InvalidArgumentException("virtual host",
939 "missing prefix or pattern");
945 Hdf ipblocks = config["IpBlockMap"];
946 IpBlocks = std::make_shared<IpBlockMap>(ipblocks);
949 Hdf satellites = config["Satellites"];
950 if (satellites.exists()) {
951 for (Hdf hdf = satellites.firstChild(); hdf.exists(); hdf = hdf.next()) {
952 auto satellite = std::make_shared<SatelliteServerInfo>(hdf);
953 SatelliteServerInfos.push_back(satellite);
954 if (satellite->getType() == SatelliteServer::Type::KindOfRPCServer) {
955 XboxPassword = satellite->getPassword();
956 XboxPasswords = satellite->getPasswords();
962 Hdf xbox = config["Xbox"];
963 XboxServerThreadCount = xbox["ServerInfo.ThreadCount"].getInt32(10);
964 XboxServerMaxQueueLength =
965 xbox["ServerInfo.MaxQueueLength"].getInt32(INT_MAX);
966 if (XboxServerMaxQueueLength < 0) XboxServerMaxQueueLength = INT_MAX;
967 XboxServerPort = xbox["ServerInfo.Port"].getInt32(0);
968 XboxDefaultLocalTimeoutMilliSeconds =
969 xbox["DefaultLocalTimeoutMilliSeconds"].getInt32(500);
970 XboxDefaultRemoteTimeoutSeconds =
971 xbox["DefaultRemoteTimeoutSeconds"].getInt32(5);
972 XboxServerInfoMaxRequest = xbox["ServerInfo.MaxRequest"].getInt32(500);
973 XboxServerInfoDuration = xbox["ServerInfo.MaxDuration"].getInt32(120);
974 XboxServerInfoWarmupDoc = xbox["ServerInfo.WarmupDocument"].get("");
975 XboxServerInfoReqInitFunc = xbox["ServerInfo.RequestInitFunction"].get("");
976 XboxServerInfoReqInitDoc = xbox["ServerInfo.RequestInitDocument"].get("");
977 XboxServerInfoAlwaysReset = xbox["ServerInfo.AlwaysReset"].getBool(false);
978 XboxServerLogInfo = xbox["ServerInfo.LogInfo"].getBool(false);
979 XboxProcessMessageFunc =
980 xbox["ProcessMessageFunc"].get("xbox_process_message");
983 Hdf pagelet = config["PageletServer"];
984 PageletServerThreadCount = pagelet["ThreadCount"].getInt32(0);
985 PageletServerThreadRoundRobin = pagelet["ThreadRoundRobin"].getBool();
986 PageletServerThreadDropStack = pagelet["ThreadDropStack"].getBool();
987 PageletServerThreadDropCacheTimeoutSeconds =
988 pagelet["ThreadDropCacheTimeoutSeconds"].getInt32(0);
989 PageletServerQueueLimit = pagelet["QueueLimit"].getInt32(0);
992 FiberCount = config["Fiber.ThreadCount"].getInt32(Process::GetCPUCount());
995 Hdf content = config["StaticFile"];
996 content["Extensions"].get(StaticFileExtensions);
997 content["Generators"].get(StaticFileGenerators);
999 Hdf matches = content["FilesMatch"];
1000 if (matches.exists()) {
1001 for (Hdf hdf = matches.firstChild(); hdf.exists(); hdf = hdf.next()) {
1002 FilesMatches.push_back(std::make_shared<FilesMatch>(hdf));
1007 Hdf phpfile = config["PhpFile"];
1008 phpfile["Extensions"].get(PhpFileExtensions);
1011 Hdf admin = config["AdminServer"];
1012 AdminServerPort = admin["Port"].getInt16(0);
1013 AdminThreadCount = admin["ThreadCount"].getInt32(1);
1014 AdminPassword = admin["Password"].getString();
1015 admin["Passwords"].get(AdminPasswords);
1018 Hdf proxy = config["Proxy"];
1019 ProxyOrigin = proxy["Origin"].getString();
1020 ProxyRetry = proxy["Retry"].getInt16(3);
1021 UseServeURLs = proxy["ServeURLs"].getBool();
1022 proxy["ServeURLs"].get(ServeURLs);
1023 UseProxyURLs = proxy["ProxyURLs"].getBool();
1024 ProxyPercentage = proxy["Percentage"].getByte(0);
1025 proxy["ProxyURLs"].get(ProxyURLs);
1026 proxy["ProxyPatterns"].get(ProxyPatterns);
1029 Hdf http = config["Http"];
1030 HttpDefaultTimeout = http["DefaultTimeout"].getInt32(30);
1031 HttpSlowQueryThreshold = http["SlowQueryThreshold"].getInt32(5000);
1034 Hdf debug = config["Debug"];
1035 NativeStackTrace = debug["NativeStackTrace"].getBool();
1036 StackTrace::Enabled = NativeStackTrace;
1037 TranslateLeakStackTrace = debug["TranslateLeakStackTrace"].getBool();
1038 FullBacktrace = debug["FullBacktrace"].getBool();
1039 ServerStackTrace = debug["ServerStackTrace"].getBool();
1040 ServerErrorMessage = debug["ServerErrorMessage"].getBool();
1041 TranslateSource = debug["TranslateSource"].getBool();
1042 RecordInput = debug["RecordInput"].getBool();
1043 ClearInputOnSuccess = debug["ClearInputOnSuccess"].getBool(true);
1044 ProfilerOutputDir = debug["ProfilerOutputDir"].getString("/tmp");
1045 CoreDumpEmail = debug["CoreDumpEmail"].getString();
1046 CoreDumpReport = debug["CoreDumpReport"].getBool(true);
1047 if (CoreDumpReport) {
1048 install_crash_reporter();
1050 CoreDumpReportDirectory =
1051 debug["CoreDumpReportDirectory"].getString(CoreDumpReportDirectory);
1052 LocalMemcache = debug["LocalMemcache"].getBool();
1053 MemcacheReadOnly = debug["MemcacheReadOnly"].getBool();
1056 Hdf simpleCounter = debug["SimpleCounter"];
1057 SimpleCounter::SampleStackCount =
1058 simpleCounter["SampleStackCount"].getInt32(0);
1059 SimpleCounter::SampleStackDepth =
1060 simpleCounter["SampleStackDepth"].getInt32(5);
1064 Hdf stats = config["Stats"];
1065 EnableStats = stats.getBool(); // main switch
1067 EnableWebStats = stats["Web"].getBool();
1068 EnableMemoryStats = stats["Memory"].getBool();
1069 EnableMemcacheStats = stats["Memcache"].getBool();
1070 EnableMemcacheKeyStats = stats["MemcacheKey"].getBool();
1071 EnableSQLStats = stats["SQL"].getBool();
1072 EnableSQLTableStats = stats["SQLTable"].getBool();
1073 EnableNetworkIOStatus = stats["NetworkIO"].getBool();
1075 StatsXSL = stats["XSL"].getString();
1076 StatsXSLProxy = stats["XSLProxy"].getString();
1078 StatsSlotDuration = stats["SlotDuration"].getInt32(10 * 60); // 10 minutes
1079 StatsMaxSlot = stats["MaxSlot"].getInt32(12 * 6); // 12 hours
1081 EnableHotProfiler = stats["EnableHotProfiler"].getBool(true);
1082 ProfilerTraceBuffer = stats["ProfilerTraceBuffer"].getInt32(2000000);
1083 ProfilerTraceExpansion = stats["ProfilerTraceExpansion"].getDouble(1.2);
1084 ProfilerMaxTraceBuffer = stats["ProfilerMaxTraceBuffer"].getInt32(0);
1087 config["ServerVariables"].get(ServerVariables);
1088 config["EnvVariables"].get(EnvVariables);
1091 Hdf eval = config["Eval"];
1092 EnableHipHopSyntax = eval["EnableHipHopSyntax"].getBool();
1093 EnableHipHopExperimentalSyntax =
1094 eval["EnableHipHopExperimentalSyntax"].getBool();
1095 EnableShortTags= eval["EnableShortTags"].getBool(true);
1096 EnableAspTags = eval["EnableAspTags"].getBool();
1097 EnableXHP = eval["EnableXHP"].getBool(false);
1098 EnableZendCompat = eval["EnableZendCompat"].getBool(false);
1099 TimeoutsUseWallTime = eval["TimeoutsUseWallTime"].getBool(true);
1101 if (EnableHipHopSyntax) {
1102 // If EnableHipHopSyntax is true, it forces EnableXHP to true
1103 // regardless of how it was set in the config
1104 EnableXHP = true;
1107 EnableObjDestructCall = eval["EnableObjDestructCall"].getBool(false);
1108 MaxUserFunctionId = eval["MaxUserFunctionId"].getInt32(2 * 65536);
1109 CheckSymLink = eval["CheckSymLink"].getBool(true);
1111 EnableAlternative = eval["EnableAlternative"].getInt32(0);
1113 #define get_double getDouble
1114 #define get_bool getBool
1115 #define get_string getString
1116 #define get_int16 getInt16
1117 #define get_int32 getInt32
1118 #define get_int32_t getInt32
1119 #define get_int64 getInt64
1120 #define get_uint16 getUInt16
1121 #define get_uint32 getUInt32
1122 #define get_uint32_t getUInt32
1123 #define get_uint64 getUInt64
1124 #define get_uint64_t getUInt64
1125 #define F(type, name, defaultVal) \
1126 Eval ## name = eval[#name].get_ ##type(defaultVal);
1127 EVALFLAGS()
1128 #undef F
1129 #undef get_double
1130 #undef get_bool
1131 #undef get_string
1132 #undef get_int16
1133 #undef get_int32
1134 #undef get_int64
1135 #undef get_uint16
1136 #undef get_uint32
1137 #undef get_uint32_t
1138 #undef get_uint64
1139 Util::low_malloc_huge_pages(EvalMaxLowMemHugePages);
1140 EvalJitEnableRenameFunction = EvalJitEnableRenameFunction || !EvalJit;
1142 EnableEmitSwitch = eval["EnableEmitSwitch"].getBool(true);
1143 EnableEmitterStats = eval["EnableEmitterStats"].getBool(EnableEmitterStats);
1144 EnableInstructionCounts = eval["EnableInstructionCounts"].getBool(false);
1145 RecordCodeCoverage = eval["RecordCodeCoverage"].getBool();
1146 if (EvalJit && RecordCodeCoverage) {
1147 throw InvalidArgumentException(
1148 "code coverage", "Code coverage is not supported for Eval.Jit=true");
1150 if (RecordCodeCoverage) CheckSymLink = true;
1151 CodeCoverageOutputFile = eval["CodeCoverageOutputFile"].getString();
1153 Hdf debugger = eval["Debugger"];
1154 EnableDebugger = debugger["EnableDebugger"].getBool();
1155 EnableDebuggerColor = debugger["EnableDebuggerColor"].getBool(true);
1156 EnableDebuggerPrompt = debugger["EnableDebuggerPrompt"].getBool(true);
1157 EnableDebuggerServer = debugger["EnableDebuggerServer"].getBool();
1158 EnableDebuggerUsageLog = debugger["EnableDebuggerUsageLog"].getBool();
1159 DebuggerServerPort = debugger["Port"].getUInt16(8089);
1160 DebuggerDisableIPv6 = debugger["DisableIPv6"].getBool(false);
1161 DebuggerDefaultSandboxPath = debugger["DefaultSandboxPath"].getString();
1162 DebuggerStartupDocument = debugger["StartupDocument"].getString();
1163 DebuggerSignalTimeout = debugger["SignalTimeout"].getInt32(1);
1165 DebuggerDefaultRpcPort = debugger["RPC.DefaultPort"].getUInt16(8083);
1166 DebuggerDefaultRpcAuth = debugger["RPC.DefaultAuth"].getString();
1167 DebuggerRpcHostDomain = debugger["RPC.HostDomain"].getString();
1168 DebuggerDefaultRpcTimeout = debugger["RPC.DefaultTimeout"].getInt32(30);
1171 Hdf repo = config["Repo"];
1173 Hdf repoLocal = repo["Local"];
1174 // Repo.Local.Mode.
1175 RepoLocalMode = repoLocal["Mode"].getString();
1176 if (!empty && RepoLocalMode.empty()) {
1177 const char* HHVM_REPO_LOCAL_MODE = getenv("HHVM_REPO_LOCAL_MODE");
1178 if (HHVM_REPO_LOCAL_MODE != nullptr) {
1179 RepoLocalMode = HHVM_REPO_LOCAL_MODE;
1182 if (RepoLocalMode.empty()) {
1183 RepoLocalMode = "r-";
1185 if (RepoLocalMode.compare("rw")
1186 && RepoLocalMode.compare("r-")
1187 && RepoLocalMode.compare("--")) {
1188 Logger::Error("Bad config setting: Repo.Local.Mode=%s",
1189 RepoLocalMode.c_str());
1190 RepoLocalMode = "rw";
1192 // Repo.Local.Path.
1193 RepoLocalPath = repoLocal["Path"].getString();
1194 if (!empty && RepoLocalPath.empty()) {
1195 const char* HHVM_REPO_LOCAL_PATH = getenv("HHVM_REPO_LOCAL_PATH");
1196 if (HHVM_REPO_LOCAL_PATH != nullptr) {
1197 RepoLocalPath = HHVM_REPO_LOCAL_PATH;
1202 Hdf repoCentral = repo["Central"];
1203 // Repo.Central.Path.
1204 RepoCentralPath = repoCentral["Path"].getString();
1207 Hdf repoEval = repo["Eval"];
1208 // Repo.Eval.Mode.
1209 RepoEvalMode = repoEval["Mode"].getString();
1210 if (RepoEvalMode.empty()) {
1211 RepoEvalMode = "readonly";
1212 } else if (RepoEvalMode.compare("local")
1213 && RepoEvalMode.compare("central")
1214 && RepoEvalMode.compare("readonly")) {
1215 Logger::Error("Bad config setting: Repo.Eval.Mode=%s",
1216 RepoEvalMode.c_str());
1217 RepoEvalMode = "readonly";
1220 RepoJournal = repo["Journal"].getString("delete");
1221 RepoCommit = repo["Commit"].getBool(true);
1222 RepoDebugInfo = repo["DebugInfo"].getBool(true);
1223 RepoAuthoritative = repo["Authoritative"].getBool(false);
1226 // NB: after we know the value of RepoAuthoritative.
1227 EnableArgsInBacktraces =
1228 eval["EnableArgsInBacktraces"].getBool(!RepoAuthoritative);
1231 Hdf sandbox = config["Sandbox"];
1232 SandboxMode = sandbox["SandboxMode"].getBool();
1233 SandboxPattern = Util::format_pattern
1234 (sandbox["Pattern"].getString(), true);
1235 SandboxHome = sandbox["Home"].getString();
1236 SandboxFallback = sandbox["Fallback"].getString();
1237 SandboxConfFile = sandbox["ConfFile"].getString();
1238 SandboxFromCommonRoot = sandbox["FromCommonRoot"].getBool();
1239 SandboxDirectoriesRoot = sandbox["DirectoriesRoot"].getString();
1240 SandboxLogsRoot = sandbox["LogsRoot"].getString();
1241 sandbox["ServerVariables"].get(SandboxServerVariables);
1244 Hdf mail = config["Mail"];
1245 SendmailPath = mail["SendmailPath"].getString("sendmail -t -i");
1246 MailForceExtraParameters = mail["ForceExtraParameters"].getString();
1249 Hdf preg = config["Preg"];
1250 PregBacktraceLimit = preg["BacktraceLimit"].getInt64(1000000);
1251 PregRecursionLimit = preg["RecursionLimit"].getInt64(100000);
1252 EnablePregErrorLog = preg["ErrorLog"].getBool(true);
1255 Hdf hhprofServer = config["HHProfServer"];
1256 HHProfServerEnabled = hhprofServer["Enabled"].getBool(false);
1257 HHProfServerPort = hhprofServer["Port"].getInt16(4327);
1258 HHProfServerThreads = hhprofServer["Threads"].getInt16(2);
1259 HHProfServerTimeoutSeconds =
1260 hhprofServer["TimeoutSeconds"].getInt64(30);
1261 HHProfServerProfileClientMode =
1262 hhprofServer["ProfileClientMode"].getBool(true);
1263 HHProfServerAllocationProfile =
1264 hhprofServer["AllocationProfile"].getBool(false);
1266 // HHProfServer.Filter.*
1267 Hdf hhprofFilter = hhprofServer["Filter"];
1268 HHProfServerFilterMinAllocPerReq =
1269 hhprofFilter["MinAllocPerReq"].getInt64(2);
1270 HHProfServerFilterMinBytesPerReq =
1271 hhprofFilter["MinBytesPerReq"].getInt64(128);
1274 Hdf simplexml = config["SimpleXML"];
1275 // TODO (t3610856): Change the default to false once dependent code is fixed
1276 SimpleXMLEmptyNamespaceMatchesAll =
1277 simplexml["EmptyNamespaceMatchesAll"].getBool(true);
1279 #ifdef FACEBOOK
1281 Hdf fb303Server = config["Fb303Server"];
1282 EnableFb303Server = fb303Server["Enable"].getBool(true);
1283 Fb303ServerPort = fb303Server["Port"].getInt16(0);
1284 Fb303ServerThreadStackSizeMb = fb303Server["ThreadStackSizeMb"].getInt16(8);
1285 Fb303ServerWorkerThreads = fb303Server["WorkerThreads"].getInt16(1);
1286 Fb303ServerPoolThreads = fb303Server["PoolThreads"].getInt16(1);
1288 #endif
1290 refineStaticStringTableSize();
1292 Extension::LoadModules(config);
1293 if (overwrites) Loaded = true;
1296 ///////////////////////////////////////////////////////////////////////////////