improvements with the request class

misc-improvements
n0nag0n 1 week ago
parent b331797ae3
commit c8f39b7a11

@ -1020,8 +1020,10 @@ class Engine
public function _lastModified(int $time): void public function _lastModified(int $time): void
{ {
$this->response()->header('Last-Modified', gmdate('D, d M Y H:i:s \G\M\T', $time)); $this->response()->header('Last-Modified', gmdate('D, d M Y H:i:s \G\M\T', $time));
$request = $this->request();
$ifModifiedSince = $request->header('If-Modified-Since');
$hit = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) === $time; $hit = isset($ifModifiedSince) && strtotime($ifModifiedSince) === $time;
$this->triggerEvent('flight.cache.checked', 'lastModified', $hit, 0.0); $this->triggerEvent('flight.cache.checked', 'lastModified', $hit, 0.0);
if ($hit === true) { if ($hit === true) {

@ -155,27 +155,37 @@ class Request
public function __construct(array $config = []) public function __construct(array $config = [])
{ {
// Default properties // Default properties
if (empty($config)) { if (empty($config) === true) {
$scheme = $this->getScheme();
$url = $this->getVar('REQUEST_URI', '/');
if (strpos($url, '@') !== false) {
$url = str_replace('@', '%40', $url);
}
$base = $this->getVar('SCRIPT_NAME', '');
if (strpos($base, ' ') !== false || strpos($base, '\\') !== false) {
$base = str_replace(['\\', ' '], ['/', '%20'], $base);
}
$base = dirname($base);
$config = [ $config = [
'url' => str_replace('@', '%40', self::getVar('REQUEST_URI', '/')), 'url' => $url,
'base' => str_replace(['\\', ' '], ['/', '%20'], \dirname(self::getVar('SCRIPT_NAME'))), 'base' => $base,
'method' => self::getMethod(), 'method' => $this->getMethod(),
'referrer' => self::getVar('HTTP_REFERER'), 'referrer' => $this->getVar('HTTP_REFERER'),
'ip' => self::getVar('REMOTE_ADDR'), 'ip' => $this->getVar('REMOTE_ADDR'),
'ajax' => self::getVar('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest', 'ajax' => $this->getVar('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest',
'scheme' => self::getScheme(), 'scheme' => $scheme,
'user_agent' => self::getVar('HTTP_USER_AGENT'), 'user_agent' => $this->getVar('HTTP_USER_AGENT'),
'type' => self::getVar('CONTENT_TYPE'), 'type' => $this->getVar('CONTENT_TYPE'),
'length' => intval(self::getVar('CONTENT_LENGTH', 0)), 'length' => intval($this->getVar('CONTENT_LENGTH', 0)),
'query' => new Collection($_GET), 'query' => new Collection($_GET),
'data' => new Collection($_POST), 'data' => new Collection($_POST),
'cookies' => new Collection($_COOKIE), 'cookies' => new Collection($_COOKIE),
'files' => new Collection($_FILES), 'files' => new Collection($_FILES),
'secure' => self::getScheme() === 'https', 'secure' => $scheme === 'https',
'accept' => self::getVar('HTTP_ACCEPT'), 'accept' => $this->getVar('HTTP_ACCEPT'),
'proxy_ip' => self::getProxyIpAddress(), 'proxy_ip' => $this->getProxyIpAddress(),
'host' => self::getVar('HTTP_HOST'), 'host' => $this->getVar('HTTP_HOST'),
'servername' => self::getVar('SERVER_NAME', ''), 'servername' => $this->getVar('SERVER_NAME', ''),
]; ];
} }
@ -201,7 +211,7 @@ class Request
// (such as installing on a subdirectory in a web server) // (such as installing on a subdirectory in a web server)
// @see testInitUrlSameAsBaseDirectory // @see testInitUrlSameAsBaseDirectory
if ($this->base !== '/' && $this->base !== '' && strpos($this->url, $this->base) === 0) { if ($this->base !== '/' && $this->base !== '' && strpos($this->url, $this->base) === 0) {
$this->url = substr($this->url, \strlen($this->base)); $this->url = substr($this->url, strlen($this->base));
} }
// Default url // Default url
@ -249,11 +259,11 @@ class Request
return $body; return $body;
} }
$method = $this->method ?? self::getMethod(); $method = $this->method ?? $this->getMethod();
if ($method === 'POST' || $method === 'PUT' || $method === 'DELETE' || $method === 'PATCH') { if (in_array($method, ['POST', 'PUT', 'DELETE', 'PATCH'], true) === true) {
$body = file_get_contents($this->stream_path); $body = file_get_contents($this->stream_path);
} }
$this->body = $body; $this->body = $body;
@ -267,8 +277,8 @@ class Request
{ {
$method = self::getVar('REQUEST_METHOD', 'GET'); $method = self::getVar('REQUEST_METHOD', 'GET');
if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']) === true) { if (self::getVar('HTTP_X_HTTP_METHOD_OVERRIDE') !== '') {
$method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']; $method = self::getVar('HTTP_X_HTTP_METHOD_OVERRIDE');
} elseif (isset($_REQUEST['_method']) === true) { } elseif (isset($_REQUEST['_method']) === true) {
$method = $_REQUEST['_method']; $method = $_REQUEST['_method'];
} }
@ -295,8 +305,9 @@ class Request
$flags = \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE; $flags = \FILTER_FLAG_NO_PRIV_RANGE | \FILTER_FLAG_NO_RES_RANGE;
foreach ($forwarded as $key) { foreach ($forwarded as $key) {
if (\array_key_exists($key, $_SERVER) === true) { $serverVar = self::getVar($key);
sscanf($_SERVER[$key], '%[^,]', $ip); if ($serverVar !== '') {
sscanf($serverVar, '%[^,]', $ip);
if (filter_var($ip, \FILTER_VALIDATE_IP, $flags) !== false) { if (filter_var($ip, \FILTER_VALIDATE_IP, $flags) !== false) {
return $ip; return $ip;
} }
@ -403,14 +414,16 @@ class Request
*/ */
public static function parseQuery(string $url): array public static function parseQuery(string $url): array
{ {
$params = []; $queryPos = strpos($url, '?');
if ($queryPos === false) {
$args = parse_url($url); return [];
if (isset($args['query']) === true) { }
parse_str($args['query'], $params); $query = substr($url, $queryPos + 1);
} if ($query === '') {
return [];
return $params; }
parse_str($query, $params);
return $params;
} }
/** /**
@ -421,13 +434,13 @@ class Request
public static function getScheme(): string public static function getScheme(): string
{ {
if ( if (
(isset($_SERVER['HTTPS']) === true && strtolower($_SERVER['HTTPS']) === 'on') (strtolower(self::getVar('HTTPS')) === 'on')
|| ||
(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) === true && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') (self::getVar('HTTP_X_FORWARDED_PROTO') === 'https')
|| ||
(isset($_SERVER['HTTP_FRONT_END_HTTPS']) === true && $_SERVER['HTTP_FRONT_END_HTTPS'] === 'on') (self::getVar('HTTP_FRONT_END_HTTPS') === 'on')
|| ||
(isset($_SERVER['REQUEST_SCHEME']) === true && $_SERVER['REQUEST_SCHEME'] === 'https') (self::getVar('REQUEST_SCHEME') === 'https')
) { ) {
return 'https'; return 'https';
} }

@ -324,10 +324,11 @@ class Response
); );
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
} else { } else {
$serverProtocol = Request::getVar('SERVER_PROTOCOL') ?: 'HTTP/1.1';
$this->setRealHeader( $this->setRealHeader(
sprintf( sprintf(
'%s %d %s', '%s %d %s',
$_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1', $serverProtocol,
$this->status, $this->status,
self::$codes[$this->status] self::$codes[$this->status]
), ),

@ -356,4 +356,25 @@ class RequestTest extends TestCase
$this->assertEquals('/tmp/php456', $files[1]->getTempName()); $this->assertEquals('/tmp/php456', $files[1]->getTempName());
$this->assertEquals(0, $files[1]->getError()); $this->assertEquals(0, $files[1]->getError());
} }
public function testUrlWithAtSymbol(): void
{
$_SERVER['REQUEST_URI'] = '/user@domain';
$_SERVER['SCRIPT_NAME'] = '/index.php';
$request = new Request();
$this->assertEquals('/user%40domain', $request->url);
}
public function testBaseWithSpaceAndBackslash(): void
{
$_SERVER['SCRIPT_NAME'] = '\\dir name\\base folder\\index.php';
$request = new Request();
$this->assertEquals('/dir%20name/base%20folder', $request->base);
}
public function testParseQueryWithEmptyQueryString(): void
{
$result = Request::parseQuery('/foo?');
$this->assertEquals([], $result);
}
} }

Loading…
Cancel
Save