2022-09-13 13:13:11 +00:00
|
|
|
<?php
|
|
|
|
// HttpRequest.php
|
|
|
|
// Created: 2022-02-08
|
2023-01-07 19:03:43 +00:00
|
|
|
// Updated: 2023-01-07
|
2022-09-13 13:13:11 +00:00
|
|
|
|
|
|
|
namespace Index\Http;
|
|
|
|
|
|
|
|
use InvalidArgumentException;
|
|
|
|
use Index\Version;
|
|
|
|
use Index\MediaType;
|
|
|
|
use Index\Http\Content\IHttpContent;
|
|
|
|
use Index\Http\Content\JsonContent;
|
|
|
|
use Index\Http\Content\StreamContent;
|
|
|
|
use Index\Http\Content\FormContent;
|
|
|
|
|
|
|
|
class HttpRequest extends HttpMessage {
|
|
|
|
private string $method;
|
|
|
|
private string $path;
|
|
|
|
private array $params;
|
|
|
|
private array $cookies;
|
|
|
|
|
|
|
|
public function __construct(
|
|
|
|
Version $version,
|
|
|
|
string $method,
|
|
|
|
string $path,
|
|
|
|
array $params,
|
|
|
|
array $cookies,
|
|
|
|
HttpHeaders $headers,
|
|
|
|
?IHttpContent $content
|
|
|
|
) {
|
|
|
|
$this->method = $method;
|
|
|
|
$this->path = $path;
|
|
|
|
$this->params = $params;
|
|
|
|
$this->cookies = $cookies;
|
|
|
|
|
|
|
|
parent::__construct($version, $headers, $content);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMethod(): string {
|
|
|
|
return $this->method;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPath(): string {
|
|
|
|
return $this->path;
|
|
|
|
}
|
|
|
|
|
2023-01-07 19:03:43 +00:00
|
|
|
public function getParamString(bool $spacesAsPlus = false): string {
|
|
|
|
return http_build_query($this->params, '', '&', $spacesAsPlus ? PHP_QUERY_RFC1738 : PHP_QUERY_RFC3986);
|
2022-09-13 13:13:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getParams(): array {
|
|
|
|
return $this->params;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getParam(string $name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {
|
|
|
|
if(!isset($this->params[$name]))
|
|
|
|
return null;
|
|
|
|
return filter_var($this->params[$name] ?? null, $filter, $options);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function hasParam(string $name): bool {
|
|
|
|
return isset($this->params[$name]);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getCookies(): array {
|
|
|
|
return $this->cookies;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getCookie(string $name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed {
|
|
|
|
if(!isset($this->cookies[$name]))
|
|
|
|
return null;
|
|
|
|
return filter_var($this->cookies[$name] ?? null, $filter, $options);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static function fromRequest(): HttpRequest {
|
|
|
|
$build = new HttpRequestBuilder;
|
|
|
|
$build->setHttpVersion(new Version(...array_map('intval', explode('.', substr($_SERVER['SERVER_PROTOCOL'], 5)))));
|
|
|
|
$build->setMethod($_SERVER['REQUEST_METHOD']);
|
|
|
|
$build->setPath('/' . trim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/'));
|
|
|
|
$build->setParams($_GET);
|
|
|
|
$build->setCookies($_COOKIE);
|
|
|
|
|
|
|
|
$contentType = null;
|
|
|
|
$contentLength = 0;
|
|
|
|
|
|
|
|
$headers = self::getRawRequestHeaders();
|
|
|
|
foreach($headers as $name => $value) {
|
|
|
|
$nameLower = strtolower($name);
|
|
|
|
if($nameLower === 'content-type')
|
|
|
|
try {
|
|
|
|
$contentType = MediaType::parse($value);
|
|
|
|
} catch(InvalidArgumentException $ex) {
|
|
|
|
$contentType = null;
|
|
|
|
}
|
|
|
|
elseif($nameLower === 'content-length')
|
2023-01-01 19:00:00 +00:00
|
|
|
$contentLength = (int)$value;
|
2022-09-13 13:13:11 +00:00
|
|
|
|
|
|
|
$build->setHeader($name, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
if($contentType !== null
|
|
|
|
&& ($contentType->equals('application/json') || $contentType->equals('application/x-json')))
|
|
|
|
$build->setContent(JsonContent::fromRequest());
|
|
|
|
elseif($contentType !== null
|
|
|
|
&& ($contentType->equals('application/x-www-form-urlencoded') || $contentType->equals('multipart/form-data')))
|
|
|
|
$build->setContent(FormContent::fromRequest());
|
|
|
|
elseif($contentLength > 0)
|
|
|
|
$build->setContent(StreamContent::fromRequest());
|
|
|
|
|
|
|
|
return $build->toRequest();
|
|
|
|
}
|
|
|
|
|
|
|
|
private static function getRawRequestHeaders(): array {
|
|
|
|
if(function_exists('getallheaders'))
|
|
|
|
return getallheaders();
|
|
|
|
|
|
|
|
$headers = [];
|
|
|
|
|
|
|
|
foreach($_SERVER as $key => $value) {
|
|
|
|
if(substr($key, 0, 5) === 'HTTP_') {
|
|
|
|
$key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
|
|
|
|
$headers[$key] = $value;
|
|
|
|
} elseif($key === 'CONTENT_TYPE') {
|
|
|
|
$headers['Content-Type'] = $value;
|
|
|
|
} elseif($key === 'CONTENT_LENGTH') {
|
|
|
|
$headers['Content-Length'] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!isset($headers['Authorization'])) {
|
|
|
|
if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
|
|
|
$headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
|
|
|
} elseif(isset($_SERVER['PHP_AUTH_USER'])) {
|
|
|
|
$headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . ($_SERVER['PHP_AUTH_PW'] ?? ''));
|
|
|
|
} elseif(isset($_SERVER['PHP_AUTH_DIGEST'])) {
|
|
|
|
$headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $headers;
|
|
|
|
}
|
|
|
|
}
|