88 self::HEADER_FORWARDED =>
'FORWARDED',
89 self::HEADER_CLIENT_IP =>
'X_FORWARDED_FOR',
90 self::HEADER_CLIENT_HOST =>
'X_FORWARDED_HOST',
91 self::HEADER_CLIENT_PROTO =>
'X_FORWARDED_PROTO',
92 self::HEADER_CLIENT_PORT =>
'X_FORWARDED_PORT',
223 private $isHostValid =
true;
224 private $isClientIpsValid =
true;
225 private $isForwardedValid =
true;
227 private static $trustedHeaderSet = -1;
230 private static $trustedHeaderNames = array(
231 self::HEADER_FORWARDED =>
'FORWARDED',
232 self::HEADER_CLIENT_IP =>
'X_FORWARDED_FOR',
233 self::HEADER_CLIENT_HOST =>
'X_FORWARDED_HOST',
234 self::HEADER_CLIENT_PROTO =>
'X_FORWARDED_PROTO',
235 self::HEADER_CLIENT_PORT =>
'X_FORWARDED_PORT',
238 private static $forwardedParams = array(
239 self::HEADER_X_FORWARDED_FOR =>
'for',
240 self::HEADER_X_FORWARDED_HOST =>
'host',
241 self::HEADER_X_FORWARDED_PROTO =>
'proto',
242 self::HEADER_X_FORWARDED_PORT =>
'host',
282 $this->headers =
new HeaderBag($this->server->getHeaders());
285 $this->languages =
null;
286 $this->charsets =
null;
287 $this->encodings =
null;
288 $this->acceptableContentTypes =
null;
289 $this->pathInfo =
null;
290 $this->requestUri =
null;
291 $this->baseUrl =
null;
292 $this->basePath =
null;
293 $this->method =
null;
294 $this->format =
null;
308 if (
'cli-server' === PHP_SAPI) {
309 if (array_key_exists(
'HTTP_CONTENT_LENGTH', $_SERVER)) {
310 $server[
'CONTENT_LENGTH'] = $_SERVER[
'HTTP_CONTENT_LENGTH'];
312 if (array_key_exists(
'HTTP_CONTENT_TYPE', $_SERVER)) {
313 $server[
'CONTENT_TYPE'] = $_SERVER[
'HTTP_CONTENT_TYPE'];
317 $request = self::createRequestFromFactory($_GET, $_POST, array(), $_COOKIE, $_FILES,
$server);
319 if (0 === strpos(
$request->headers->get(
'CONTENT_TYPE'),
'application/x-www-form-urlencoded')
320 && in_array(strtoupper(
$request->server->get(
'REQUEST_METHOD',
'GET')), array(
'PUT',
'DELETE',
'PATCH'))
322 parse_str(
$request->getContent(), $data);
348 'SERVER_NAME' =>
'localhost',
350 'HTTP_HOST' =>
'localhost',
351 'HTTP_USER_AGENT' =>
'Symfony/3.X',
352 'HTTP_ACCEPT' =>
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
353 'HTTP_ACCEPT_LANGUAGE' =>
'en-us,en;q=0.5',
354 'HTTP_ACCEPT_CHARSET' =>
'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
355 'REMOTE_ADDR' =>
'127.0.0.1',
357 'SCRIPT_FILENAME' =>
'',
358 'SERVER_PROTOCOL' =>
'HTTP/1.1',
359 'REQUEST_TIME' => time(),
365 $components = parse_url($uri);
366 if (isset($components[
'host'])) {
367 $server[
'SERVER_NAME'] = $components[
'host'];
368 $server[
'HTTP_HOST'] = $components[
'host'];
371 if (isset($components[
'scheme'])) {
372 if (
'https' === $components[
'scheme']) {
381 if (isset($components[
'port'])) {
382 $server[
'SERVER_PORT'] = $components[
'port'];
383 $server[
'HTTP_HOST'] =
$server[
'HTTP_HOST'].
':'.$components[
'port'];
386 if (isset($components[
'user'])) {
387 $server[
'PHP_AUTH_USER'] = $components[
'user'];
390 if (isset($components[
'pass'])) {
391 $server[
'PHP_AUTH_PW'] = $components[
'pass'];
394 if (!isset($components[
'path'])) {
395 $components[
'path'] =
'/';
402 if (!isset(
$server[
'CONTENT_TYPE'])) {
403 $server[
'CONTENT_TYPE'] =
'application/x-www-form-urlencoded';
417 if (isset($components[
'query'])) {
418 parse_str(html_entity_decode($components[
'query']), $qs);
422 $queryString = http_build_query(
$query,
'',
'&');
425 $queryString = $components[
'query'];
428 $queryString = http_build_query(
$query,
'',
'&');
431 $server[
'REQUEST_URI'] = $components[
'path'].(
'' !== $queryString ?
'?'.$queryString :
'');
432 $server[
'QUERY_STRING'] = $queryString;
448 self::$requestFactory = $callable;
467 $dup->query =
new ParameterBag(
$query);
470 $dup->request =
new ParameterBag(
$request);
476 $dup->cookies =
new ParameterBag(
$cookies);
479 $dup->files =
new FileBag(
$files);
482 $dup->server =
new ServerBag(
$server);
483 $dup->headers =
new HeaderBag($dup->server->getHeaders());
485 $dup->languages =
null;
486 $dup->charsets =
null;
487 $dup->encodings =
null;
488 $dup->acceptableContentTypes =
null;
489 $dup->pathInfo =
null;
490 $dup->requestUri =
null;
491 $dup->baseUrl =
null;
492 $dup->basePath =
null;
496 if (!$dup->get(
'_format') && $this->get(
'_format')) {
497 $dup->attributes->set(
'_format', $this->
get(
'_format'));
500 if (!$dup->getRequestFormat(
null)) {
533 }
catch (\LogicException $e) {
534 return trigger_error($e, E_USER_ERROR);
538 sprintf(
'%s %s %s', $this->
getMethod(), $this->
getRequestUri(), $this->server->get(
'SERVER_PROTOCOL')).
"\r\n".
539 $this->headers.
"\r\n".
551 $this->server->set(
'QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(),
null,
'&')));
553 $_GET = $this->query->all();
554 $_POST = $this->request->all();
555 $_SERVER = $this->server->all();
556 $_COOKIE = $this->cookies->all();
558 foreach ($this->headers->all() as $key => $value) {
559 $key = strtoupper(str_replace(
'-',
'_', $key));
560 if (in_array($key, array(
'CONTENT_TYPE',
'CONTENT_LENGTH'))) {
561 $_SERVER[$key] = implode(
', ', $value);
563 $_SERVER[
'HTTP_'.$key] = implode(
', ', $value);
567 $request = array(
'g' => $_GET,
'p' => $_POST,
'c' => $_COOKIE);
569 $requestOrder = ini_get(
'request_order') ?: ini_get(
'variables_order');
570 $requestOrder = preg_replace(
'#[^cgp]#',
'', strtolower($requestOrder)) ?:
'gp';
573 foreach (str_split($requestOrder) as $order) {
574 $_REQUEST = array_merge($_REQUEST,
$request[$order]);
590 self::$trustedProxies = $proxies;
592 if (2 > func_num_args()) {
593 @trigger_error(sprintf(
'The %s() method expects a bit field of Request::HEADER_* as second argument since version 3.3. Defining it will be required in 4.0. ', __METHOD__), E_USER_DEPRECATED);
597 $trustedHeaderSet = (int) func_get_arg(1);
599 foreach (self::$trustedHeaderNames as $header => $name) {
600 self::$trustedHeaders[$header] = $header & $trustedHeaderSet ? $name :
null;
602 self::$trustedHeaderSet = $trustedHeaderSet;
622 return self::$trustedHeaderSet;
634 self::$trustedHostPatterns = array_map(
function ($hostPattern) {
635 return sprintf(
'#%s#i', $hostPattern);
638 self::$trustedHosts = array();
673 @trigger_error(sprintf(
'The "%s()" method is deprecated since version 3.3 and will be removed in 4.0. Use the $trustedHeaderSet argument of the Request::setTrustedProxies() method instead.', __METHOD__), E_USER_DEPRECATED);
675 if (
'forwarded' === $key) {
677 } elseif (
'client_ip' === $key) {
679 } elseif (
'client_host' === $key) {
681 } elseif (
'client_proto' === $key) {
683 } elseif (
'client_port' === $key) {
685 } elseif (!array_key_exists($key, self::$trustedHeaders)) {
686 throw new \InvalidArgumentException(sprintf(
'Unable to set the trusted header name for key "%s".', $key));
689 self::$trustedHeaders[$key] = $value;
691 if (
null !== $value) {
692 self::$trustedHeaderNames[$key] = $value;
693 self::$trustedHeaderSet |= $key;
695 self::$trustedHeaderSet &= ~$key;
712 if (2 > func_num_args() || func_get_arg(1)) {
713 @trigger_error(sprintf(
'The "%s()" method is deprecated since version 3.3 and will be removed in 4.0. Use the Request::getTrustedHeaderSet() method instead.', __METHOD__), E_USER_DEPRECATED);
716 if (!array_key_exists($key, self::$trustedHeaders)) {
717 throw new \InvalidArgumentException(sprintf(
'Unable to get the trusted header name for key "%s".', $key));
720 return self::$trustedHeaders[$key];
742 foreach (explode(
'&', $qs) as $param) {
743 if (
'' === $param ||
'=' === $param[0]) {
750 $keyValuePair = explode(
'=', $param, 2);
755 $parts[] = isset($keyValuePair[1]) ?
756 rawurlencode(urldecode($keyValuePair[0])).
'='.rawurlencode(urldecode($keyValuePair[1])) :
757 rawurlencode(urldecode($keyValuePair[0]));
758 $order[] = urldecode($keyValuePair[0]);
761 array_multisort($order, SORT_ASC, $parts);
763 return implode(
'&', $parts);
779 self::$httpMethodParameterOverride =
true;
806 public function get($key, $default =
null)
808 if ($this !== $result = $this->attributes->get($key, $this)) {
812 if ($this !== $result = $this->query->get($key, $this)) {
816 if ($this !== $result = $this->request->get($key, $this)) {
842 return $this->
hasSession() && $this->cookies->has($this->session->getName());
884 $ip = $this->server->get(
'REMOTE_ADDR');
890 return $this->getTrustedValues(self::HEADER_CLIENT_IP, $ip) ?: array($ip);
915 return $ipAddresses[0];
925 return $this->server->get(
'SCRIPT_NAME', $this->server->get(
'ORIG_SCRIPT_NAME',
''));
944 if (
null === $this->pathInfo) {
965 if (
null === $this->basePath) {
984 if (
null === $this->baseUrl) {
998 return $this->
isSecure() ?
'https' :
'http';
1017 if ($this->
isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_PORT)) {
1019 } elseif ($this->
isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_HOST)) {
1021 } elseif (!$host = $this->headers->get(
'HOST')) {
1022 return $this->server->get(
'SERVER_PORT');
1025 if ($host[0] ===
'[') {
1026 $pos = strpos($host,
':', strrpos($host,
']'));
1028 $pos = strrpos($host,
':');
1031 if (
false !== $pos) {
1032 return (
int) substr($host, $pos + 1);
1035 return 'https' === $this->
getScheme() ? 443 : 80;
1045 return $this->headers->get(
'PHP_AUTH_USER');
1055 return $this->headers->get(
'PHP_AUTH_PW');
1069 $userinfo .=
":$pass";
1087 if ((
'http' == $scheme && $port == 80) || (
'https' == $scheme && $port == 443)) {
1091 return $this->
getHost().
':'.$port;
1101 if (
null === $this->requestUri) {
1171 if (!isset($path[0]) ||
'/' !== $path[0]) {
1180 $targetDirs = explode(
'/', isset($path[0]) &&
'/' === $path[0] ? substr($path, 1) : $path);
1181 array_pop($sourceDirs);
1182 $targetFile = array_pop($targetDirs);
1184 foreach ($sourceDirs as $i => $dir) {
1185 if (isset($targetDirs[$i]) && $dir === $targetDirs[$i]) {
1186 unset($sourceDirs[$i], $targetDirs[$i]);
1192 $targetDirs[] = $targetFile;
1193 $path = str_repeat(
'../', count($sourceDirs)).implode(
'/', $targetDirs);
1199 return !isset($path[0]) ||
'/' === $path[0]
1200 ||
false !== ($colonPos = strpos($path,
':')) && ($colonPos < ($slashPos = strpos($path,
'/')) ||
false === $slashPos)
1201 ?
"./$path" : $path;
1214 $qs = static::normalizeQueryString($this->server->get(
'QUERY_STRING'));
1216 return '' === $qs ? null : $qs;
1235 if ($this->
isFromTrustedProxy() && $proto = $this->getTrustedValues(self::HEADER_CLIENT_PROTO)) {
1236 return in_array(strtolower($proto[0]), array(
'https',
'on',
'ssl',
'1'),
true);
1239 $https = $this->server->get(
'HTTPS');
1241 return !empty($https) &&
'off' !== strtolower($https);
1262 if ($this->
isFromTrustedProxy() && $host = $this->getTrustedValues(self::HEADER_CLIENT_HOST)) {
1264 } elseif (!$host = $this->headers->get(
'HOST')) {
1265 if (!$host = $this->server->get(
'SERVER_NAME')) {
1266 $host = $this->server->get(
'SERVER_ADDR',
'');
1272 $host = strtolower(preg_replace(
'/:\d+$/',
'', trim($host)));
1277 if ($host &&
'' !== preg_replace(
'/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/',
'', $host)) {
1278 if (!$this->isHostValid) {
1281 $this->isHostValid =
false;
1286 if (count(self::$trustedHostPatterns) > 0) {
1289 if (in_array($host, self::$trustedHosts)) {
1293 foreach (self::$trustedHostPatterns as $pattern) {
1294 if (preg_match($pattern, $host)) {
1295 self::$trustedHosts[] = $host;
1301 if (!$this->isHostValid) {
1304 $this->isHostValid =
false;
1306 throw new SuspiciousOperationException(sprintf(
'Untrusted Host "%s".', $host));
1319 $this->method =
null;
1320 $this->server->set(
'REQUEST_METHOD',
$method);
1340 if (
null === $this->method) {
1341 $this->method = strtoupper($this->server->get(
'REQUEST_METHOD',
'GET'));
1343 if (
'POST' === $this->method) {
1344 if (
$method = $this->headers->get(
'X-HTTP-METHOD-OVERRIDE')) {
1345 $this->method = strtoupper(
$method);
1346 } elseif (self::$httpMethodParameterOverride) {
1347 $this->method = strtoupper($this->request->get(
'_method', $this->query->get(
'_method',
'POST')));
1364 return strtoupper($this->server->get(
'REQUEST_METHOD',
'GET'));
1376 if (
null === static::$formats) {
1377 static::initializeFormats();
1392 if (
null === static::$formats) {
1393 static::initializeFormats();
1396 return isset(static::$formats[
$format]) ? static::$formats[
$format] : array();
1408 $canonicalMimeType =
null;
1409 if (
false !== $pos = strpos($mimeType,
';')) {
1410 $canonicalMimeType = substr($mimeType, 0, $pos);
1413 if (
null === static::$formats) {
1414 static::initializeFormats();
1417 foreach (static::$formats as
$format => $mimeTypes) {
1418 if (in_array($mimeType, (array) $mimeTypes)) {
1421 if (
null !== $canonicalMimeType && in_array($canonicalMimeType, (array) $mimeTypes)) {
1435 if (
null === static::$formats) {
1436 static::initializeFormats();
1439 static::$formats[
$format] = is_array($mimeTypes) ? $mimeTypes : array($mimeTypes);
1457 if (
null === $this->format) {
1458 $this->format = $this->attributes->get(
'_format');
1481 return $this->
getFormat($this->headers->get(
'CONTENT_TYPE'));
1491 $this->defaultLocale =
$locale;
1493 if (
null === $this->locale) {
1494 $this->setPhpDefaultLocale(
$locale);
1515 $this->setPhpDefaultLocale($this->locale =
$locale);
1525 return null === $this->locale ? $this->defaultLocale :
$this->locale;
1551 if (!func_num_args() || func_get_arg(0)) {
1554 @trigger_error(
'Checking only for cacheable HTTP methods with Symfony\Component\HttpFoundation\Request::isMethodSafe() is deprecated since version 3.2 and will throw an exception in 4.0. Disable checking only for cacheable methods by calling the method with `false` as first argument or use the Request::isMethodCacheable() instead.', E_USER_DEPRECATED);
1556 return in_array($this->
getMethod(), array(
'GET',
'HEAD'));
1559 return in_array($this->
getMethod(), array(
'GET',
'HEAD',
'OPTIONS',
'TRACE'));
1569 return in_array($this->
getMethod(), array(
'HEAD',
'GET',
'PUT',
'DELETE',
'TRACE',
'OPTIONS',
'PURGE'));
1581 return in_array($this->
getMethod(), array(
'GET',
'HEAD'));
1593 public function getContent($asResource =
false)
1595 $currentContentIsResource = is_resource($this->content);
1596 if (\PHP_VERSION_ID < 50600 && false === $this->content) {
1597 throw new \LogicException(
'getContent() can only be called once when using the resource return type and PHP below 5.6.');
1600 if (
true === $asResource) {
1601 if ($currentContentIsResource) {
1602 rewind($this->content);
1608 if (is_string($this->content)) {
1609 $resource = fopen(
'php://temp',
'r+');
1610 fwrite($resource, $this->content);
1616 $this->content =
false;
1618 return fopen(
'php://input',
'rb');
1621 if ($currentContentIsResource) {
1622 rewind($this->content);
1624 return stream_get_contents($this->content);
1627 if (
null === $this->content ||
false === $this->content) {
1628 $this->content = file_get_contents(
'php://input');
1641 return preg_split(
'/\s*,\s*/', $this->headers->get(
'if_none_match'),
null, PREG_SPLIT_NO_EMPTY);
1649 return $this->headers->hasCacheControlDirective(
'no-cache') ||
'no-cache' == $this->headers->get(
'Pragma');
1663 if (empty($locales)) {
1664 return isset($preferredLanguages[0]) ? $preferredLanguages[0] :
null;
1667 if (!$preferredLanguages) {
1671 $extendedPreferredLanguages = array();
1672 foreach ($preferredLanguages as $language) {
1673 $extendedPreferredLanguages[] = $language;
1674 if (
false !== $position = strpos($language,
'_')) {
1675 $superLanguage = substr($language, 0, $position);
1676 if (!in_array($superLanguage, $preferredLanguages)) {
1677 $extendedPreferredLanguages[] = $superLanguage;
1682 $preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
1684 return isset($preferredLanguages[0]) ? $preferredLanguages[0] : $locales[0];
1694 if (
null !== $this->languages) {
1699 $this->languages = array();
1700 foreach (
$languages as $lang => $acceptHeaderItem) {
1701 if (
false !== strpos($lang,
'-')) {
1702 $codes = explode(
'-', $lang);
1703 if (
'i' === $codes[0]) {
1707 if (count($codes) > 1) {
1711 for ($i = 0, $max = count($codes); $i < $max; ++$i) {
1713 $lang = strtolower($codes[0]);
1715 $lang .=
'_'.strtoupper($codes[$i]);
1721 $this->languages[] = $lang;
1734 if (
null !== $this->charsets) {
1748 if (
null !== $this->encodings) {
1762 if (
null !== $this->acceptableContentTypes) {
1781 return 'XMLHttpRequest' == $this->headers->get(
'X-Requested-With');
1796 if ($this->headers->has(
'X_ORIGINAL_URL')) {
1798 $requestUri = $this->headers->get(
'X_ORIGINAL_URL');
1799 $this->headers->remove(
'X_ORIGINAL_URL');
1800 $this->server->remove(
'HTTP_X_ORIGINAL_URL');
1801 $this->server->remove(
'UNENCODED_URL');
1802 $this->server->remove(
'IIS_WasUrlRewritten');
1803 } elseif ($this->headers->has(
'X_REWRITE_URL')) {
1805 $requestUri = $this->headers->get(
'X_REWRITE_URL');
1806 $this->headers->remove(
'X_REWRITE_URL');
1807 } elseif ($this->server->get(
'IIS_WasUrlRewritten') ==
'1' && $this->server->get(
'UNENCODED_URL') !=
'') {
1810 $this->server->remove(
'UNENCODED_URL');
1811 $this->server->remove(
'IIS_WasUrlRewritten');
1812 } elseif ($this->server->has(
'REQUEST_URI')) {
1816 if (strpos(
$requestUri, $schemeAndHttpHost) === 0) {
1819 } elseif ($this->server->has(
'ORIG_PATH_INFO')) {
1821 $requestUri = $this->server->get(
'ORIG_PATH_INFO');
1822 if (
'' != $this->server->get(
'QUERY_STRING')) {
1825 $this->server->remove(
'ORIG_PATH_INFO');
1841 $filename = basename($this->server->get(
'SCRIPT_FILENAME'));
1843 if (basename($this->server->get(
'SCRIPT_NAME')) === $filename) {
1844 $baseUrl = $this->server->get(
'SCRIPT_NAME');
1845 } elseif (basename($this->server->get(
'PHP_SELF')) === $filename) {
1846 $baseUrl = $this->server->get(
'PHP_SELF');
1847 } elseif (basename($this->server->get(
'ORIG_SCRIPT_NAME')) === $filename) {
1848 $baseUrl = $this->server->get(
'ORIG_SCRIPT_NAME');
1852 $path = $this->server->get(
'PHP_SELF',
'');
1853 $file = $this->server->get(
'SCRIPT_FILENAME',
'');
1854 $segs = explode(
'/', trim($file,
'/'));
1855 $segs = array_reverse($segs);
1857 $last = count($segs);
1860 $seg = $segs[$index];
1863 }
while ($last > $index && (
false !== $pos = strpos($path,
$baseUrl)) && 0 != $pos);
1874 if (
$baseUrl &&
false !== $prefix = $this->getUrlencodedPrefix(
$requestUri, rtrim(dirname(
$baseUrl),
'/'.DIRECTORY_SEPARATOR).
'/')) {
1876 return rtrim($prefix,
'/'.DIRECTORY_SEPARATOR);
1881 $truncatedRequestUri = substr(
$requestUri, 0, $pos);
1885 if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
1897 return rtrim(
$baseUrl,
'/'.DIRECTORY_SEPARATOR);
1907 $filename = basename($this->server->get(
'SCRIPT_FILENAME'));
1913 if (basename(
$baseUrl) === $filename) {
1919 if (
'\\' === DIRECTORY_SEPARATOR) {
1960 static::$formats = array(
1961 'html' => array(
'text/html',
'application/xhtml+xml'),
1962 'txt' => array(
'text/plain'),
1963 'js' => array(
'application/javascript',
'application/x-javascript',
'text/javascript'),
1964 'css' => array(
'text/css'),
1965 'json' => array(
'application/json',
'application/x-json'),
1966 'xml' => array(
'text/xml',
'application/xml',
'application/x-xml'),
1967 'rdf' => array(
'application/rdf+xml'),
1968 'atom' => array(
'application/atom+xml'),
1969 'rss' => array(
'application/rss+xml'),
1970 'form' => array(
'application/x-www-form-urlencoded'),
1979 private function setPhpDefaultLocale(
$locale)
1985 if (class_exists(
'Locale',
false)) {
1988 }
catch (\Exception $e) {
2001 private function getUrlencodedPrefix($string, $prefix)
2003 if (0 !== strpos(rawurldecode($string), $prefix)) {
2007 $len = strlen($prefix);
2009 if (preg_match(sprintf(
'#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) {
2018 if (self::$requestFactory) {
2022 throw new \LogicException(
'The Request factory must return an instance of Symfony\Component\HttpFoundation\Request.');
2041 return self::$trustedProxies &&
IpUtils::checkIp($this->server->get(
'REMOTE_ADDR'), self::$trustedProxies);
2044 private function getTrustedValues($type, $ip =
null)
2046 $clientValues = array();
2047 $forwardedValues = array();
2049 if (self::$trustedHeaders[$type] && $this->headers->has(self::$trustedHeaders[$type])) {
2050 foreach (explode(
',', $this->headers->get(self::$trustedHeaders[$type])) as $v) {
2051 $clientValues[] = (self::HEADER_CLIENT_PORT === $type ?
'0.0.0.0:' :
'').trim($v);
2055 if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) {
2056 $forwardedValues = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]);
2057 $forwardedValues = preg_match_all(sprintf(
'{(?:%s)=(?:"?\[?)([a-zA-Z0-9\.:_\-/]*+)}', self::$forwardedParams[$type]), $forwardedValues, $matches) ? $matches[1] : array();
2061 $clientValues = $this->normalizeAndFilterClientIps($clientValues, $ip);
2062 $forwardedValues = $this->normalizeAndFilterClientIps($forwardedValues, $ip);
2065 if ($forwardedValues === $clientValues || !$clientValues) {
2066 return $forwardedValues;
2069 if (!$forwardedValues) {
2070 return $clientValues;
2073 if (!$this->isForwardedValid) {
2074 return null !== $ip ? array(
'0.0.0.0', $ip) : array();
2076 $this->isForwardedValid =
false;
2078 throw new ConflictingHeadersException(sprintf(
'The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::$trustedHeaders[self::HEADER_FORWARDED], self::$trustedHeaders[$type]));
2081 private function normalizeAndFilterClientIps(array $clientIps, $ip)
2087 $firstTrustedIp =
null;
2089 foreach ($clientIps as $key => $clientIp) {
2091 if (preg_match(
'{((?:\d+\.){3}\d+)\:\d+}', $clientIp, $match)) {
2092 $clientIps[$key] = $clientIp = $match[1];
2095 if (!filter_var($clientIp, FILTER_VALIDATE_IP)) {
2096 unset($clientIps[$key]);
2102 unset($clientIps[$key]);
2105 if (
null === $firstTrustedIp) {
2106 $firstTrustedIp = $clientIp;
2112 return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp);