-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
165 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?php | ||
|
||
namespace Drupal\quant_purger\Entity; | ||
|
||
/** | ||
* Helper class that centralizes string hashing for security and maintenance. | ||
*/ | ||
class Hash { | ||
|
||
/** | ||
* Create a hash with the given input and length. | ||
* | ||
* @param string $input | ||
* The input string to be hashed. | ||
* @param int $length | ||
* The length of the hash. | ||
* | ||
* @return string | ||
* Cryptographic hash with the given length. | ||
*/ | ||
protected static function hashInput($input, $length) { | ||
// MD5 is the fastest algorithm beyond CRC32 (which is 30% faster, but high | ||
// collision risk), so this is the best bet for now. If collisions are going | ||
// to be a major problem in the future, we might have to consider a hash DB. | ||
$hex = md5($input); | ||
// The produced HEX can be converted to BASE32 number to take less space. | ||
// For example 5 characters HEX can be stored in 4 characters BASE32. | ||
$hash = base_convert(substr($hex, 0, ceil($length * 1.25)), 16, 32); | ||
// Return a hash with consistent length, padding zeroes if needed. | ||
return strtolower(str_pad(substr($hash, 0, $length), $length, '0', STR_PAD_LEFT)); | ||
} | ||
|
||
/** | ||
* Create unique hashes/IDs for a list of cache tag strings. | ||
* | ||
* @param string[] $tags | ||
* Non-associative array cache tags. | ||
* | ||
* @return string[] | ||
* Non-associative array with hashed copies of the given cache tags. | ||
*/ | ||
public static function cacheTags(array $tags) { | ||
$hashes = []; | ||
foreach ($tags as $tag) { | ||
if (strlen($tag) > 4) { | ||
$hashes[] = self::hashInput($tag, 4); | ||
} | ||
else { | ||
$hashes[] = $tag; | ||
} | ||
} | ||
return $hashes; | ||
} | ||
|
||
/** | ||
* Create a unique hash that identifies this site. | ||
* | ||
* @param string $site_name | ||
* The identifier of the site on Acquia Cloud. | ||
* @param string $site_path | ||
* The path of the site, e.g. 'site/default' or 'site/database_a'. | ||
* | ||
* @return string | ||
* Cryptographic hash that's long enough to be unique. | ||
*/ | ||
public static function siteIdentifier($site_name, $site_path) { | ||
return self::hashInput($site_name . $site_path, 16); | ||
} | ||
|
||
} |
68 changes: 68 additions & 0 deletions
68
modules/quant_purger/src/Plugin/Purge/TagsHeader/CacheTagsHeaderValue.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
<?php | ||
|
||
namespace Drupal\quant_purger\Plugin\Purge\TagsHeader; | ||
|
||
/** | ||
* Provides simple value object for cache tag headers. | ||
*/ | ||
class CacheTagsHeaderValue { | ||
|
||
/** | ||
* String: separation character used. | ||
*/ | ||
const SEPARATOR = ' '; | ||
|
||
/** | ||
* List of original cache tags. | ||
* | ||
* @var string[] | ||
*/ | ||
protected $tags = []; | ||
|
||
/** | ||
* List of hashed cache tags. | ||
* | ||
* @var string[] | ||
*/ | ||
protected $tagsHashed = []; | ||
|
||
/** | ||
* Constructs a TagsHeaderValue object. | ||
* | ||
* @param string[] $tags | ||
* Non-associative array cache tags. | ||
* @param string[] $tags_hashed | ||
* Non-associative array with hashed cache tags. | ||
* | ||
* @throws \LogicException | ||
* Thrown when both tags arrays aren't of equal length. | ||
*/ | ||
public function __construct(array $tags, array $tags_hashed) { | ||
if (count($tags) !== count($tags_hashed)) { | ||
throw new \LogicException("TagsHeaderValue received unequal tag sets!"); | ||
} | ||
$this->tags = array_unique($tags); | ||
$this->tagsHashed = array_unique($tags_hashed); | ||
} | ||
|
||
/** | ||
* Generate the header value for a cache tags header. | ||
* | ||
* @return string | ||
* String representation of the cache tags for use on headers. | ||
*/ | ||
public function __toString() { | ||
return implode(self::SEPARATOR, $this->tagsHashed); | ||
} | ||
|
||
/** | ||
* Get an associative array mapping keys. | ||
* | ||
* @return array | ||
* Associative mapping original and hashed cache tags. | ||
*/ | ||
public function getTagsMap() { | ||
return array_combine($this->tags, $this->tagsHashed); | ||
} | ||
|
||
} |
26 changes: 26 additions & 0 deletions
26
modules/quant_purger/src/Plugin/Purge/TagsHeader/QuantCacheTagsHeader.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace Drupal\quant_purger\Plugin\Purge\TagsHeader; | ||
|
||
use Drupal\quant_purger\Entity\Hash; | ||
use Drupal\purge\Plugin\Purge\TagsHeader\TagsHeaderInterface; | ||
use Drupal\purge\Plugin\Purge\TagsHeader\TagsHeaderBase; | ||
|
||
/** | ||
* Sets and formats the default response header with cache tags. | ||
* | ||
* @PurgeTagsHeader( | ||
* id = "quant_tagsheader", | ||
* header_name = "Cache-Tags", | ||
* ) | ||
*/ | ||
class QuantCacheTagsHeader extends TagsHeaderBase implements TagsHeaderInterface { | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function getValue(array $tags) { | ||
return new CacheTagsHeaderValue($tags, Hash::cacheTags($tags)); | ||
} | ||
|
||
} |