From: Tim Düsterhus Date: Tue, 31 May 2022 13:41:47 +0000 (+0200) Subject: Merge branch '5.4' into 5.5 X-Git-Tag: 5.5.0_Beta_4~2 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c266fd8f97d6d4f94f6b8f4330cacd0b68c6059b;p=GitHub%2FWoltLab%2FWCF.git Merge branch '5.4' into 5.5 --- c266fd8f97d6d4f94f6b8f4330cacd0b68c6059b diff --cc wcfsetup/install/files/lib/system/request/RequestHandler.class.php index 5dbcb3f313,2fd82b5e94..5547d31c26 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@@ -114,89 -126,20 +116,103 @@@ class RequestHandler extends SingletonF } } + private function checkSystemEnvironment() + { + if ($this->isACPRequest()) { + return; + } + + if (!(70200 <= PHP_VERSION_ID && PHP_VERSION_ID <= 80099)) { + \header('HTTP/1.1 500 Internal Server Error'); + + throw new NamedUserException(WCF::getLanguage()->get('wcf.global.incompatiblePhpVersion')); + } + } + + + /** + * Splits the given array of cache-control values at commas, while properly + * taking into account that each value might itself contain commas within a + * quoted string. + */ + private function splitCacheControl(array $values): \Iterator + { + foreach ($values as $value) { + $isQuoted = false; + $result = ''; + + for ($i = 0, $len = \strlen($value); $i < $len; $i++) { + $char = $value[$i]; + if (!$isQuoted && $char === ',') { + yield \trim($result); + + $isQuoted = false; + $result = ''; + + continue; + } + + if ($isQuoted && $char === '\\') { + $result .= $char; + $i++; + + if ($i < $len) { + $result .= $value[$i]; + + continue; + } + } + + if ($char === '"') { + $isQuoted = !$isQuoted; + } + + $result .= $char; + } + + if ($result !== '') { + yield \trim($result); + } + } + } + + /** + * @since 5.5 + */ + private function sendPsr7Response(ResponseInterface $response) + { + // Storing responses in a shared cache is unsafe, because they all contain session specific information. + // Add the 'private' value to the cache-control header and remove any 'public' value. + $cacheControl = [ + 'private', + ]; + foreach ($this->splitCacheControl($response->getHeader('cache-control')) as $value) { + [$field] = \explode('=', $value, 2); + + // Prevent duplication of the 'private' field. + if ($field === 'private') { + continue; + } + + // Drop the 'public' field. + if ($field === 'public') { + continue; + } + + $cacheControl[] = $value; + } + + $response = $response->withHeader( + 'cache-control', + // Manually imploding the fields is not required as per strict reading of the HTTP standard, + // but having duplicate 'cache-control' headers in the response certainly looks odd. + \implode(', ', $cacheControl) + ); + + $emitter = new SapiEmitter(); + $emitter->emit($response); + } + /** * Builds a new request. *