@@ -212,6 +212,8 @@ class Request
212
212
private bool $ isForwardedValid = true ;
213
213
private bool $ isSafeContentPreferred ;
214
214
215
+ private array $ trustedValuesCache = [];
216
+
215
217
private static int $ trustedHeaderSet = -1 ;
216
218
217
219
private const FORWARDED_PARAMS = [
@@ -1997,8 +1999,20 @@ public function isFromTrustedProxy(): bool
1997
1999
return self ::$ trustedProxies && IpUtils::checkIp ($ this ->server ->get ('REMOTE_ADDR ' , '' ), self ::$ trustedProxies );
1998
2000
}
1999
2001
2002
+ /**
2003
+ * This method is rather heavy because it splits and merges headers, and it's called by many other methods such as
2004
+ * getPort(), isSecure(), getHost(), getClientIps(), getBaseUrl() etc. Thus, we try to cache the results for
2005
+ * best performance.
2006
+ */
2000
2007
private function getTrustedValues (int $ type , string $ ip = null ): array
2001
2008
{
2009
+ $ cacheKey = $ type ."\0" .((self ::$ trustedHeaderSet & $ type ) ? $ this ->headers ->get (self ::TRUSTED_HEADERS [$ type ]) : '' );
2010
+ $ cacheKey .= "\0" .$ ip ."\0" .$ this ->headers ->get (self ::TRUSTED_HEADERS [self ::HEADER_FORWARDED ]);
2011
+
2012
+ if (isset ($ this ->trustedValuesCache [$ cacheKey ])) {
2013
+ return $ this ->trustedValuesCache [$ cacheKey ];
2014
+ }
2015
+
2002
2016
$ clientValues = [];
2003
2017
$ forwardedValues = [];
2004
2018
@@ -2011,7 +2025,6 @@ private function getTrustedValues(int $type, string $ip = null): array
2011
2025
if ((self ::$ trustedHeaderSet & self ::HEADER_FORWARDED ) && (isset (self ::FORWARDED_PARAMS [$ type ])) && $ this ->headers ->has (self ::TRUSTED_HEADERS [self ::HEADER_FORWARDED ])) {
2012
2026
$ forwarded = $ this ->headers ->get (self ::TRUSTED_HEADERS [self ::HEADER_FORWARDED ]);
2013
2027
$ parts = HeaderUtils::split ($ forwarded , ',;= ' );
2014
- $ forwardedValues = [];
2015
2028
$ param = self ::FORWARDED_PARAMS [$ type ];
2016
2029
foreach ($ parts as $ subParts ) {
2017
2030
if (null === $ v = HeaderUtils::combine ($ subParts )[$ param ] ?? null ) {
@@ -2033,15 +2046,15 @@ private function getTrustedValues(int $type, string $ip = null): array
2033
2046
}
2034
2047
2035
2048
if ($ forwardedValues === $ clientValues || !$ clientValues ) {
2036
- return $ forwardedValues ;
2049
+ return $ this -> trustedValuesCache [ $ cacheKey ] = $ forwardedValues ;
2037
2050
}
2038
2051
2039
2052
if (!$ forwardedValues ) {
2040
- return $ clientValues ;
2053
+ return $ this -> trustedValuesCache [ $ cacheKey ] = $ clientValues ;
2041
2054
}
2042
2055
2043
2056
if (!$ this ->isForwardedValid ) {
2044
- return null !== $ ip ? ['0.0.0.0 ' , $ ip ] : [];
2057
+ return $ this -> trustedValuesCache [ $ cacheKey ] = null !== $ ip ? ['0.0.0.0 ' , $ ip ] : [];
2045
2058
}
2046
2059
$ this ->isForwardedValid = false ;
2047
2060
0 commit comments