<?php
+/**
+ * @copyright Copyright (C) 2010-2023, the Friendica project
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
namespace Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues;
+use Friendica\Core\System;
/**
* Container for the whole request
*/
class Request
{
- /** @var string the default possible headers, which could contain the client IP */
- const ORDERED_FORWARD_FOR_HEADER = 'HTTP_X_FORWARDED_FOR';
+ /**
+ * A comma separated list of default headers that could contain the client IP in a proxy request
+ *
+ * @var string
+ */
+ const DEFAULT_FORWARD_FOR_HEADER = 'HTTP_X_FORWARDED_FOR';
+ /**
+ * The default Request-ID header to retrieve the current transaction ID from the HTTP header (if set)
+ *
+ * @var string
+ */
+ const DEFAULT_REQUEST_ID_HEADER = 'HTTP_X_REQUEST_ID';
/** @var string The remote IP address of the current request */
protected $remoteAddress;
+ /** @var string The request-id of the current request */
+ protected $requestId;
/**
* @return string The remote IP address of the current request
+ *
+ * Do always use this instead of $_SERVER['REMOTE_ADDR']
*/
public function getRemoteAddress(): string
{
return $this->remoteAddress;
}
+ /**
+ * @return string The request ID of the current request
+ *
+ * Do always use this instead of $_SERVER['X_REQUEST_ID']
+ */
+ public function getRequestId(): string
+ {
+ return $this->requestId;
+ }
+
public function __construct(IManageConfigValues $config, array $server = [])
{
$this->remoteAddress = $this->determineRemoteAddress($config, $server);
+ $this->requestId = $server[static::DEFAULT_REQUEST_ID_HEADER] ?? System::createGUID(8, false);
}
/**
* Otherwise, $remoteAddress will be compared to $trustedProxy literally and the result
* will be returned.
*
+ * @param string $trustedProxy The current, trusted proxy to check
+ * @param string $remoteAddress The current remote IP address
+ *
+ *
* @return boolean true if $remoteAddress matches $trustedProxy, false otherwise
*/
protected function matchesTrustedProxy(string $trustedProxy, string $remoteAddress): bool
* Checks if given $remoteAddress matches any entry in the given array $trustedProxies.
* For details regarding what "match" means, refer to `matchesTrustedProxy`.
*
+ * @param string[] $trustedProxies A list of the trusted proxies
+ * @param string $remoteAddress The current remote IP address
+ *
* @return boolean true if $remoteAddress matches any entry in $trustedProxies, false otherwise
*/
protected function isTrustedProxy(array $trustedProxies, string $remoteAddress): bool
}
/**
+ * Determines the remote address, if the connection came from a trusted proxy
+ * and `forwarded_for_headers` has been configured then the IP address
+ * specified in this header will be returned instead.
+ *
* @param IManageConfigValues $config
- * @param array $server
+ * @param array $server The $_SERVER array
*
* @return string
*/
$trustedProxies = preg_split('/(\s*,*\s*)*,+(\s*,*\s*)*/', $config->get('proxy', 'trusted_proxies', ''));
if (\is_array($trustedProxies) && $this->isTrustedProxy($trustedProxies, $remoteAddress)) {
- $forwardedForHeaders = preg_split('/(\s*,*\s*)*,+(\s*,*\s*)*/', $config->get('proxy', 'forwarded_for_headers')) ?? static::ORDERED_FORWARD_FOR_HEADER;
+ $forwardedForHeaders = preg_split('/(\s*,*\s*)*,+(\s*,*\s*)*/', $config->get('proxy', 'forwarded_for_headers', static::DEFAULT_FORWARD_FOR_HEADER));
foreach ($forwardedForHeaders as $header) {
if (isset($server[$header])) {