Skip to content

Cache ipCheck (2.8) #22819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

Cache ipCheck (2.8) #22819

wants to merge 1 commit into from

Conversation

gonzalovilaseca
Copy link
Contributor

@gonzalovilaseca gonzalovilaseca commented May 21, 2017

In our app we use trusted proxies. Using Blackfire we found IpUtils::checkIp was being called 454 times taking 3.15ms.
Caching the result saves those 3ms.

Q A
Branch? 2.8
Bug fix? no
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets
License MIT
Doc PR

@@ -213,6 +213,11 @@ class Request
protected $defaultLocale = 'en';

/**
* @var boolean
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be bool, see fabbot.io patch

return false;
}

if (!isset($this->validTrustedProxyIP)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible that self::$trustedProxies is changed between method calls. Make sure to reset the cached result in setTrustedProxies and that this is tested.

@nicolas-grekas
Copy link
Member

shouldnt this fix be submitted against the 2.8 branch?

@nicolas-grekas nicolas-grekas added this to the 2.8 milestone May 21, 2017
@tgalopin
Copy link
Contributor

tgalopin commented Jun 4, 2017

I stumbled upon the same issue. Shouldn't the cache be stored statically in IpUtils instead of in the request? It makes more sense to me, as the request is a representation of a HTTP object, using it to store cache feels wrong. Moreover, using a cache in IpUtils ensure a usage outside of the Request would still be cached.

WDYT?

@fabpot
Copy link
Member

fabpot commented Jun 4, 2017

Indeed, a cache in IpUtils seems a better idea.

@tgalopin
Copy link
Contributor

tgalopin commented Jun 4, 2017

@gonzalovilaseca do you want to do it? I can if you don't have time right now.

$request = new Request(array(), array(), array(), array(), array(), array('REMOTE_ADDR' => '8.8.8.8'));
Request::setTrustedProxies(array('8.8.8.8'), Request::HEADER_FORWARDED);

$this->assertEquals(true, $request->isFromTrustedProxy());
Copy link
Contributor

@robfrawley robfrawley Jun 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$this->assertTrue($this->isFromTrustedProxy());

Also seen below in testIsFromTrustedProxyCacheIsInValidatedOnSetTrustedProxies().

@gonzalovilaseca
Copy link
Contributor Author

@tgalopin Sure, I'll do it, will be ready by tuesday


Request::setTrustedProxies(array('5.5.5.5'), Request::HEADER_FORWARDED);

$this->assertEquals(false, $request->isFromTrustedProxy());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertFalse()

public function testIsFromTrustedProxyReturnsFalseIfNoTrustedProxies()
{
$request = new Request();
$this->assertEquals(false, $request->isFromTrustedProxy());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertFalse()

}

$remoteAddr = $this->server->get('REMOTE_ADDR');
if (!array_key_exists($remoteAddr, self::$validTrustedProxyIP) || null === self::$validTrustedProxyIP[$remoteAddr]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be simply: !isset(self::$validTrustedProxyIP[$remoteAddr]) cause you do check for null anyway.

@gonzalovilaseca
Copy link
Contributor Author

I've updated the PR moving the cache to IpUtils, I think that an IpUtils decorator would be a better solution, but being called statically from other places it would mean a bit of refactoring, should I go the decorator way or is this ok?

Feel free to improve the naming of the new methods, naming is not my strength, even less with jet lag :-).

@@ -19,6 +19,11 @@
class IpUtils
{
/**
* @var array
*/
protected static $checkedIps = array();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be private

@@ -61,6 +66,60 @@ public static function checkIp($requestIp, $ips)
*/
public static function checkIp4($requestIp, $ip)
{
return self::checkIpInternal($requestIp, $ip, 'self::checkIp4Internal');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not delegate to another method but just copy/paste the cache logic in the methods directly.

@@ -61,6 +66,50 @@ public static function checkIp($requestIp, $ips)
*/
public static function checkIp4($requestIp, $ip)
{
$cacheKey = $requestIp.'-'.$ip;
if (!array_key_exists($cacheKey, self::$checkedIps)) {
self::$checkedIps[$cacheKey] = self::checkIp4Internal($requestIp, $ip);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would inline the checkIp4Internal method as well.

@@ -19,6 +19,11 @@
class IpUtils
{
/**
* @var array
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phpdoc should be removed

return false;
}
$cacheKey = $requestIp.'-'.$ip;
if (!array_key_exists($cacheKey, self::$checkedIps)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would return early:

if (array_key_exists($cacheKey, self::$checkedIps)) {
    return self::$checkedIps[$cacheKey];
}

I would even change arra_key_exists() to isset()

@@ -61,26 +63,31 @@ public static function checkIp($requestIp, $ips)
*/
public static function checkIp4($requestIp, $ip)
{
$cacheKey = $requestIp.'-'.$ip;
if (isset($cacheKey, self::$checkedIps)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks wrong to me

@fabpot
Copy link
Member

fabpot commented Jun 6, 2017

@gonzalovilaseca Can you change the branch of the PR to 2.7?

@gonzalovilaseca
Copy link
Contributor Author

@fabpot 2.7 or 2.8? (nicolas mentioned 2.8)

@gonzalovilaseca gonzalovilaseca changed the base branch from master to 2.7 June 6, 2017 19:23
@fabpot
Copy link
Member

fabpot commented Jun 6, 2017

I would say 2.7.

@gonzalovilaseca gonzalovilaseca changed the base branch from 2.7 to 2.8 June 6, 2017 19:25
@gonzalovilaseca gonzalovilaseca changed the base branch from 2.8 to 2.7 June 6, 2017 19:26
@gonzalovilaseca
Copy link
Contributor Author

@fabpot IpUtils changed from 2.7 to 2.8, should I do a PR for each branch?

@fabpot
Copy link
Member

fabpot commented Jun 6, 2017

That would be wonderful, thanks.

@gonzalovilaseca gonzalovilaseca changed the base branch from 2.7 to 2.8 June 7, 2017 19:13
@gonzalovilaseca
Copy link
Contributor Author

2.7 version here: #23098

@gonzalovilaseca gonzalovilaseca changed the title Cache ipCheck Cache ipCheck (2.8) Jun 7, 2017
@fabpot fabpot closed this Jun 8, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants