53 lines
1.6 KiB
PHP
53 lines
1.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace NetBoxStore\Http;
|
|
|
|
use NetBoxStore\Config;
|
|
|
|
final class Request
|
|
{
|
|
/** @param array<string,mixed> $query @param array<string,mixed> $body @param array<string,string> $headers */
|
|
public function __construct(
|
|
public readonly string $method,
|
|
public readonly string $path,
|
|
public readonly array $query,
|
|
public readonly array $body,
|
|
public readonly array $headers,
|
|
public readonly string $ip,
|
|
) {
|
|
}
|
|
|
|
public static function fromGlobals(Config $config): self
|
|
{
|
|
$uri = (string) ($_SERVER['REQUEST_URI'] ?? '/');
|
|
$path = rawurldecode((string) parse_url($uri, PHP_URL_PATH));
|
|
$path = '/' . trim($path, '/');
|
|
if ($path !== '/') {
|
|
$path = rtrim($path, '/');
|
|
}
|
|
$headers = [];
|
|
foreach ($_SERVER as $key => $value) {
|
|
if (str_starts_with($key, 'HTTP_')) {
|
|
$headers[strtolower(str_replace('_', '-', substr($key, 5)))] = (string) $value;
|
|
}
|
|
}
|
|
$ip = (string) ($_SERVER['REMOTE_ADDR'] ?? '');
|
|
if ($config->trustProxy && in_array($ip, $config->network['trustedProxyIps'], true) && isset($headers['x-forwarded-for'])) {
|
|
$candidate = trim(explode(',', $headers['x-forwarded-for'])[0]);
|
|
if (filter_var($candidate, FILTER_VALIDATE_IP)) {
|
|
$ip = $candidate;
|
|
}
|
|
}
|
|
return new self(
|
|
strtoupper((string) ($_SERVER['REQUEST_METHOD'] ?? 'GET')),
|
|
$path,
|
|
$_GET,
|
|
$_POST,
|
|
$headers,
|
|
$ip,
|
|
);
|
|
}
|
|
}
|