Files
azuracast-on-demand-hls/src/Service/CachePaths.php
T

66 lines
2.1 KiB
PHP

<?php
declare(strict_types=1);
namespace Plugin\AzuraCastOnDemandHls\Service;
use Plugin\AzuraCastOnDemandHls\Config;
use RuntimeException;
final readonly class CachePaths
{
public function __construct(private Config $config)
{
}
public function root(string $stationTempDirectory): string
{
return rtrim($stationTempDirectory, DIRECTORY_SEPARATOR)
. DIRECTORY_SEPARATOR . $this->config->cacheDirectory;
}
public function sessions(string $stationTempDirectory): string
{
return $this->root($stationTempDirectory) . '/sessions';
}
public function assets(string $stationTempDirectory): string
{
return $this->root($stationTempDirectory) . '/assets';
}
public function locks(string $stationTempDirectory): string
{
return $this->root($stationTempDirectory) . '/locks';
}
public function asset(string $stationTempDirectory, string $cacheKey): string
{
if (1 !== preg_match('/^[a-f0-9]{64}$/D', $cacheKey)) {
throw new RuntimeException('Unsafe cache key.');
}
return $this->assets($stationTempDirectory) . '/' . $cacheKey;
}
public function ensure(string $stationTempDirectory): void
{
$directories = [
$this->root($stationTempDirectory) => 0755,
$this->sessions($stationTempDirectory) => 0700,
$this->assets($stationTempDirectory) => 0755,
$this->locks($stationTempDirectory) => 0700,
];
foreach ($directories as $directory => $mode) {
if (is_link($directory)) {
throw new RuntimeException('Refusing to use a symlinked HLS cache directory.');
}
// Another request may create the same directory after is_dir().
// Suppress that benign E_WARNING, then verify the final state.
if (!is_dir($directory) && !@mkdir($directory, $mode, true) && !is_dir($directory)) {
throw new RuntimeException('Could not create the HLS cache directory.');
}
chmod($directory, $mode);
}
}
}