@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a configuration warning when `memory_limit` will limit file uploads

Summary: Fixes T6011. See that task for discussion. We can detect when `memory_limit` will be the limiting factor for drag-and-drop uploads and warn administrators about it.

Test Plan: Fiddled configuration values and hit, then resolved, the issue.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T6011

Differential Revision: https://secure.phabricator.com/D10413

+97 -3
+59
src/applications/config/check/PhabricatorSetupCheckStorage.php
··· 2 2 3 3 final class PhabricatorSetupCheckStorage extends PhabricatorSetupCheck { 4 4 5 + /** 6 + * @phutil-external-symbol class PhabricatorStartup 7 + */ 5 8 protected function executeChecks() { 6 9 $upload_limit = PhabricatorEnv::getEnvConfig('storage.upload-size-limit'); 7 10 if (!$upload_limit) { ··· 16 19 ->setName(pht('Upload Limit Not Yet Configured')) 17 20 ->setMessage($message) 18 21 ->addPhabricatorConfig('storage.upload-size-limit'); 22 + } else { 23 + $memory_limit = PhabricatorStartup::getOldMemoryLimit(); 24 + if ($memory_limit && ((int)$memory_limit > 0)) { 25 + $memory_limit_bytes = phutil_parse_bytes($memory_limit); 26 + $memory_usage_bytes = memory_get_usage(); 27 + $upload_limit_bytes = phutil_parse_bytes($upload_limit); 28 + 29 + $available_bytes = ($memory_limit_bytes - $memory_usage_bytes); 30 + 31 + if ($upload_limit_bytes > $available_bytes) { 32 + $summary = pht( 33 + 'Your PHP memory limit is configured in a way that may prevent '. 34 + 'you from uploading large files.'); 35 + 36 + $message = pht( 37 + 'When you upload a file via drag-and-drop or the API, the entire '. 38 + 'file is buffered into memory before being written to permanent '. 39 + 'storage. Phabricator needs memory available to store these '. 40 + 'files while they are uploaded, but PHP is currently configured '. 41 + 'to limit the available memory.'. 42 + "\n\n". 43 + 'Your Phabricator %s is currently set to a larger value (%s) than '. 44 + 'the amount of available memory (%s) that a PHP process has '. 45 + 'available to use, so uploads via drag-and-drop and the API will '. 46 + 'hit the memory limit before they hit other limits.'. 47 + "\n\n". 48 + '(Note that the application itself must also fit in available '. 49 + 'memory, so not all of the memory under the memory limit is '. 50 + 'available for buffering file uploads.)'. 51 + "\n\n". 52 + "The easiest way to resolve this issue is to set %s to %s in your ". 53 + "PHP configuration, to disable the memory limit. There is ". 54 + "usually little or no value to using this option to limit ". 55 + "Phabricator process memory.". 56 + "\n\n". 57 + "You can also increase the limit, or decrease %s, or ignore this ". 58 + "issue and accept that these upload mechanisms will be limited ". 59 + "in the size of files they can handle.", 60 + phutil_tag('tt', array(), 'storage.upload-size-limit'), 61 + phutil_format_bytes($upload_limit_bytes), 62 + phutil_format_bytes($available_bytes), 63 + phutil_tag('tt', array(), 'memory_limit'), 64 + phutil_tag('tt', array(), '-1'), 65 + phutil_tag('tt', array(), 'storage.upload-size-limit')); 66 + 67 + $this 68 + ->newIssue('php.memory_limit.upload') 69 + ->setName(pht('Memory Limit Restricts File Uploads')) 70 + ->setSummary($summary) 71 + ->setMessage($message) 72 + ->addPHPConfig('memory_limit') 73 + ->addPHPConfigOriginalValue('memory_limit', $memory_limit) 74 + ->addPhabricatorConfig('storage.upload-size-limit'); 75 + } 76 + } 19 77 } 78 + 20 79 21 80 $local_path = PhabricatorEnv::getEnvConfig('storage.local-disk.path'); 22 81 if (!$local_path) {
+23
src/applications/config/issue/PhabricatorSetupIssue.php
··· 16 16 private $phpConfig = array(); 17 17 private $commands = array(); 18 18 private $mysqlConfig = array(); 19 + private $originalPHPConfigValues = array(); 19 20 20 21 public function addCommand($command) { 21 22 $this->commands[] = $command; ··· 80 81 public function addPHPConfig($php_config) { 81 82 $this->phpConfig[] = $php_config; 82 83 return $this; 84 + } 85 + 86 + /** 87 + * Set an explicit value to display when showing the user PHP configuration 88 + * values. 89 + * 90 + * If Phabricator has changed a value by the time a config issue is raised, 91 + * you can provide the original value here so the UI makes sense. For example, 92 + * we alter `memory_limit` during startup, so if the original value is not 93 + * provided it will look like it is always set to `-1`. 94 + * 95 + * @param string PHP configuration option to provide a value for. 96 + * @param string Explicit value to show in the UI. 97 + * @return this 98 + */ 99 + public function addPHPConfigOriginalValue($php_config, $value) { 100 + $this->originalPHPConfigValues[$php_config] = $value; 101 + return $this; 102 + } 103 + 104 + public function getPHPConfigOriginalValue($php_config, $default = null) { 105 + return idx($this->originalPHPConfigValues, $php_config, $default); 83 106 } 84 107 85 108 public function getPHPConfig() {
+5 -3
src/applications/config/view/PhabricatorSetupIssueView.php
··· 26 26 27 27 $configs = $issue->getPHPConfig(); 28 28 if ($configs) { 29 - $description[] = $this->renderPHPConfig($configs); 29 + $description[] = $this->renderPHPConfig($configs, $issue); 30 30 } 31 31 32 32 $configs = $issue->getMySQLConfig(); ··· 243 243 )); 244 244 } 245 245 246 - private function renderPHPConfig(array $configs) { 246 + private function renderPHPConfig(array $configs, $issue) { 247 247 $table_info = phutil_tag( 248 248 'p', 249 249 array(), ··· 253 253 254 254 $dict = array(); 255 255 foreach ($configs as $key) { 256 - $dict[$key] = ini_get($key); 256 + $dict[$key] = $issue->getPHPConfigOriginalValue( 257 + $key, 258 + ini_get($key)); 257 259 } 258 260 259 261 $table = $this->renderValueTable($dict);
+10
support/PhabricatorStartup.php
··· 41 41 private static $globals = array(); 42 42 private static $capturingOutput; 43 43 private static $rawInput; 44 + private static $oldMemoryLimit; 44 45 45 46 // TODO: For now, disable rate limiting entirely by default. We need to 46 47 // iterate on it a bit for Conduit, some of the specific score levels, and ··· 310 311 */ 311 312 private static function setupPHP() { 312 313 error_reporting(E_ALL | E_STRICT); 314 + self::$oldMemoryLimit = ini_get('memory_limit'); 313 315 ini_set('memory_limit', -1); 314 316 315 317 // If we have libxml, disable the incredibly dangerous entity loader. 316 318 if (function_exists('libxml_disable_entity_loader')) { 317 319 libxml_disable_entity_loader(true); 318 320 } 321 + } 322 + 323 + 324 + /** 325 + * @task validation 326 + */ 327 + public static function getOldMemoryLimit() { 328 + return self::$oldMemoryLimit; 319 329 } 320 330 321 331 /**