Lazy load large domains.php file only when it's really needed

I have seen this popping up once in a recent flame graph. I think most
services should be designed in a way that they can be instantiated
very quickly and only start doing expensive stuff when we are sure we
really need it. This was not the case here. The file domains.php is
about 150,000 lines long and can take several 100ms to load in the
worst case.

Bug: T200758
Change-Id: I7c0c787230e8cff40e8e73fede0ac1dce63ea1ca
(cherry picked from commit e5df1df69e)
This commit is contained in:
thiemowmde 2023-06-13 18:24:48 +02:00 committed by Reedy
parent 30f647a7c8
commit 721b323ad2
3 changed files with 16 additions and 9 deletions

View file

@ -21,15 +21,17 @@ namespace MediaWiki\SecureLinkFixer;
class HSTSPreloadLookup {
/**
* @var array
* @var string
*/
private $domains;
private string $path;
/** @var array<string,int> */
private array $domains;
/**
* @param array $domains
* @param string $path
*/
public function __construct( array $domains ) {
$this->domains = $domains;
public function __construct( string $path ) {
$this->path = $path;
}
/**
@ -37,7 +39,10 @@ class HSTSPreloadLookup {
*
* @return bool
*/
public function isPreloaded( $host ) {
public function isPreloaded( string $host ): bool {
// Lazy-load the domain mapping if it's not already set
$this->domains ??= require $this->path;
if ( isset( $this->domains[$host] ) ) {
// Host is directly in the preload list
return true;

View file

@ -6,6 +6,6 @@ namespace MediaWiki\SecureLinkFixer;
return [
'HSTSPreloadLookup' => static function () {
return new HSTSPreloadLookup( require __DIR__ . '/../domains.php' );
return new HSTSPreloadLookup( __DIR__ . '/../domains.php' );
}
];

View file

@ -20,6 +20,7 @@ namespace MediaWiki\SecureLinkFixer\Test;
use MediaWiki\SecureLinkFixer\HSTSPreloadLookup;
use MediaWikiIntegrationTestCase;
use Wikimedia\TestingAccessWrapper;
/**
* @covers \MediaWiki\SecureLinkFixer\HSTSPreloadLookup
@ -30,7 +31,8 @@ class HSTSPreloadLookupTest extends MediaWikiIntegrationTestCase {
* @dataProvider provideIsPreloaded
*/
public function testIsPreloaded( $host, $expected ) {
$lookup = new HSTSPreloadLookup( [
$lookup = new HSTSPreloadLookup( 'dummy' );
TestingAccessWrapper::newFromObject( $lookup )->domains = [
// TLD
'foobar' => 1,
'secure-example.org' => 1,
@ -38,7 +40,7 @@ class HSTSPreloadLookupTest extends MediaWikiIntegrationTestCase {
'insecure-subdomains-example.org' => 0,
// Subdomain is secure, root domain isn't
'secure.insecure-example.org' => 1,
] );
];
$this->assertSame( $expected, $lookup->isPreloaded( $host ) );
}