Added better header parsing to Request-class.

- Added `tryParse` argument to the `getHeader` method. When enabled the method will try to parse headers from both server and client-side (enabled by default).
- Simplified references that checks for both variants of header (http/non http).
- Simplified getIp method of the Request-class.
This commit is contained in:
Simon Sessingø
2021-03-22 11:14:22 +01:00
parent 0aeefa1cba
commit d2b3ea4f54
4 changed files with 33 additions and 20 deletions
@@ -67,7 +67,7 @@ class BaseCsrfVerifier implements IMiddleware
$token = $request->getInputHandler()->value( $token = $request->getInputHandler()->value(
static::POST_KEY, static::POST_KEY,
$request->getHeader(static::HEADER_KEY) ?? $request->getHeader('HTTP-' . static::HEADER_KEY), $request->getHeader(static::HEADER_KEY),
Request::$requestTypesPost Request::$requestTypesPost
); );
+29 -16
View File
@@ -4,6 +4,7 @@ namespace Pecee\Http;
use Pecee\Http\Exceptions\MalformedUrlException; use Pecee\Http\Exceptions\MalformedUrlException;
use Pecee\Http\Input\InputHandler; use Pecee\Http\Input\InputHandler;
use Pecee\Http\Middleware\BaseCsrfVerifier;
use Pecee\SimpleRouter\Route\ILoadableRoute; use Pecee\SimpleRouter\Route\ILoadableRoute;
use Pecee\SimpleRouter\Route\RouteUrl; use Pecee\SimpleRouter\Route\RouteUrl;
use Pecee\SimpleRouter\SimpleRouter; use Pecee\SimpleRouter\SimpleRouter;
@@ -110,14 +111,14 @@ class Request
{ {
foreach ($_SERVER as $key => $value) { foreach ($_SERVER as $key => $value) {
$this->headers[strtolower($key)] = $value; $this->headers[strtolower($key)] = $value;
$this->headers[strtolower(str_replace('_', '-', $key))] = $value; $this->headers[str_replace('_', '-', strtolower($key))] = $value;
} }
$this->setHost($this->getHeader('http-host')); $this->setHost($this->getHeader('http-host'));
// Check if special IIS header exist, otherwise use default. // Check if special IIS header exist, otherwise use default.
$this->setUrl(new Url($this->getHeader('unencoded-url', $this->getHeader('request-uri')))); $this->setUrl(new Url($this->getHeader('unencoded-url', $this->getHeader('request-uri'))));
$this->method = strtolower($this->getHeader('request-method')); $this->method = strtolower($this->getHeader('request-method'));
$this->inputHandler = new InputHandler($this); $this->inputHandler = new InputHandler($this);
$this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method'))); $this->method = strtolower($this->inputHandler->value('_method', $this->getHeader('request-method')));
@@ -186,7 +187,7 @@ class Request
*/ */
public function getCsrfToken(): ?string public function getCsrfToken(): ?string
{ {
return $this->getHeader('x-csrf-token') ?? $this->getHeader('http-x-csrf-token'); return $this->getHeader(BaseCsrfVerifier::HEADER_KEY);
} }
/** /**
@@ -204,15 +205,13 @@ class Request
*/ */
public function getIp(): ?string public function getIp(): ?string
{ {
if ($this->getHeader('http-cf-connecting-ip') !== null) { return $this->getHeader(
return $this->getHeader('http-cf-connecting-ip'); 'http-cf-connecting-ip',
} $this->getHeader(
'http-x-forwarded-for',
if ($this->getHeader('http-x-forwarded-for') !== null) { $this->getHeader('remote-addr')
return $this->getHeader('http-x-forwarded-for'); )
} );
return $this->getHeader('remote-addr');
} }
/** /**
@@ -247,14 +246,28 @@ class Request
/** /**
* Get header value by name * Get header value by name
* *
* @param string $name * @param string $name Name of the header.
* @param string|null $defaultValue * @param string|null $defaultValue Value to be returned if header is not found.
* @param bool $tryParse When enabled the method will try to find the header from both from client (http) and server-side variants, if the header is not found.
* *
* @return string|null * @return string|null
*/ */
public function getHeader($name, $defaultValue = null): ?string public function getHeader(string $name, $defaultValue = null, $tryParse = true): ?string
{ {
return $this->headers[strtolower($name)] ?? $defaultValue; $name = strtolower($name);
$header = $this->headers[$name] ?? null;
if ($tryParse === true && $header === null) {
if (strpos($name, 'http-') === 0) {
// Trying to find client header variant which was not found, searching for header variant without http- prefix.
$header = $this->headers[str_replace('http-', '', $name)] ?? null;
} else {
// Trying to find server variant which was not found, searching for client variant with http- prefix.
$header = $this->headers['http-' . $name] ?? null;
}
}
return $header ?? $defaultValue;
} }
/** /**
+2 -2
View File
@@ -305,8 +305,8 @@ class Router
* Start the routing * Start the routing
* *
* @return string|null * @return string|null
* @throws \Pecee\SimpleRouter\Exceptions\NotFoundHttpException * @throws NotFoundHttpException
* @throws \Pecee\Http\Middleware\Exceptions\TokenMismatchException * @throws TokenMismatchException
* @throws HttpException * @throws HttpException
* @throws \Exception * @throws \Exception
*/ */
+1 -1
View File
@@ -466,7 +466,7 @@ class SimpleRouter
/** /**
* Get the request * Get the request
* *
* @return \Pecee\Http\Request * @return Request
*/ */
public static function request(): Request public static function request(): Request
{ {