Add ETag cache support to avatars, backgrounds and proxied media.

This commit is contained in:
flash 2019-01-03 18:00:56 +01:00
parent e3e8b2f1aa
commit 55d991d261
3 changed files with 34 additions and 8 deletions

View file

@ -27,13 +27,13 @@ switch ($mode) {
if (is_file($croppedAvatar)) { if (is_file($croppedAvatar)) {
$avatarFilename = $croppedAvatar; $avatarFilename = $croppedAvatar;
} else { } else {
$original_avatar = build_path(MSZ_STORAGE, 'avatars/original', $userAvatar); $originalAvatar = build_path(MSZ_STORAGE, 'avatars/original', $userAvatar);
if (is_file($original_avatar)) { if (is_file($originalAvatar)) {
try { try {
file_put_contents( file_put_contents(
$croppedAvatar, $croppedAvatar,
crop_image_centred_path($original_avatar, 200, 200)->getImagesBlob(), crop_image_centred_path($originalAvatar, 200, 200)->getImagesBlob(),
LOCK_EX LOCK_EX
); );
@ -44,7 +44,16 @@ switch ($mode) {
} }
} }
$fileTime = filemtime($avatarFilename);
$entityTag = "\"avatar-{$userId}-{$fileTime}\"";
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && strtolower($_SERVER['HTTP_IF_NONE_MATCH']) === $entityTag) {
http_response_code(304);
break;
}
header('Content-Type: ' . mime_content_type($avatarFilename)); header('Content-Type: ' . mime_content_type($avatarFilename));
header("ETag: {$entityTag}");
echo file_get_contents($avatarFilename); echo file_get_contents($avatarFilename);
break; break;
@ -56,18 +65,27 @@ switch ($mode) {
break; break;
} }
$user_background = build_path( $userBackground = build_path(
create_directory(build_path(MSZ_STORAGE, 'backgrounds/original')), create_directory(build_path(MSZ_STORAGE, 'backgrounds/original')),
"{$userId}.msz" "{$userId}.msz"
); );
if (!is_file($user_background)) { if (!is_file($userBackground)) {
echo render_error(404); echo render_error(404);
break; break;
} }
header('Content-Type: ' . mime_content_type($user_background)); $fileTime = filemtime($userBackground);
echo file_get_contents($user_background); $entityTag = "\"background-{$userId}-{$fileTime}\"";
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && strtolower($_SERVER['HTTP_IF_NONE_MATCH']) === $entityTag) {
http_response_code(304);
break;
}
header('Content-Type: ' . mime_content_type($userBackground));
header("ETag: {$entityTag}");
echo file_get_contents($userBackground);
break; break;
default: default:

View file

@ -56,6 +56,13 @@ curl_setopt_array($curl, [
$curlBody = curl_exec($curl); $curlBody = curl_exec($curl);
curl_close($curl); curl_close($curl);
$entityTag = '"' . hash('sha256', $curlBody) . '"';
if (!empty($_SERVER['HTTP_IF_NONE_MATCH']) && strtolower($_SERVER['HTTP_IF_NONE_MATCH']) === $entityTag) {
http_response_code(304);
return;
}
$finfo = finfo_open(FILEINFO_MIME_TYPE); $finfo = finfo_open(FILEINFO_MIME_TYPE);
$fileMime = finfo_buffer($finfo, $curlBody); $fileMime = finfo_buffer($finfo, $curlBody);
finfo_close($finfo); finfo_close($finfo);
@ -71,5 +78,6 @@ $fileName = basename($parsedUrl['path'] ?? "proxied-image-{$expectedHash}");
header("Content-Type: {$fileMime}"); header("Content-Type: {$fileMime}");
header("Content-Length: {$fileSize}"); header("Content-Length: {$fileSize}");
header("Content-Disposition: inline; filename=\"{$fileName}\""); header("Content-Disposition: inline; filename=\"{$fileName}\"");
header("ETag: {$entityTag}");
echo $curlBody; echo $curlBody;

View file

@ -354,7 +354,7 @@ function proxy_media_url(?string $url): ?string
} }
$secret = config_get_default('insecure', 'Proxy', 'secret_key'); $secret = config_get_default('insecure', 'Proxy', 'secret_key');
$hash = hash_hmac('sha256', $url, $secret); $hash = hash_hmac('sha256', rawurldecode($url), $secret);
$encodedUrl = rawurlencode($url); $encodedUrl = rawurlencode($url);
return "/proxy.php?h={$hash}&u={$encodedUrl}"; return "/proxy.php?h={$hash}&u={$encodedUrl}";