From 55d991d261234d3828eca5fdb5c8c40e58857ee7 Mon Sep 17 00:00:00 2001 From: flashwave Date: Thu, 3 Jan 2019 18:00:56 +0100 Subject: [PATCH] Add ETag cache support to avatars, backgrounds and proxied media. --- public/profile.php | 32 +++++++++++++++++++++++++------- public/proxy.php | 8 ++++++++ utility.php | 2 +- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/public/profile.php b/public/profile.php index 13cf00ed..cb234ae5 100644 --- a/public/profile.php +++ b/public/profile.php @@ -27,13 +27,13 @@ switch ($mode) { if (is_file($croppedAvatar)) { $avatarFilename = $croppedAvatar; } 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 { file_put_contents( $croppedAvatar, - crop_image_centred_path($original_avatar, 200, 200)->getImagesBlob(), + crop_image_centred_path($originalAvatar, 200, 200)->getImagesBlob(), 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("ETag: {$entityTag}"); echo file_get_contents($avatarFilename); break; @@ -56,18 +65,27 @@ switch ($mode) { break; } - $user_background = build_path( + $userBackground = build_path( create_directory(build_path(MSZ_STORAGE, 'backgrounds/original')), "{$userId}.msz" ); - if (!is_file($user_background)) { + if (!is_file($userBackground)) { echo render_error(404); break; } - header('Content-Type: ' . mime_content_type($user_background)); - echo file_get_contents($user_background); + $fileTime = filemtime($userBackground); + $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; default: diff --git a/public/proxy.php b/public/proxy.php index 5720c256..94b087ad 100644 --- a/public/proxy.php +++ b/public/proxy.php @@ -56,6 +56,13 @@ curl_setopt_array($curl, [ $curlBody = curl_exec($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); $fileMime = finfo_buffer($finfo, $curlBody); finfo_close($finfo); @@ -71,5 +78,6 @@ $fileName = basename($parsedUrl['path'] ?? "proxied-image-{$expectedHash}"); header("Content-Type: {$fileMime}"); header("Content-Length: {$fileSize}"); header("Content-Disposition: inline; filename=\"{$fileName}\""); +header("ETag: {$entityTag}"); echo $curlBody; diff --git a/utility.php b/utility.php index ee0cbd0d..57fc7e96 100644 --- a/utility.php +++ b/utility.php @@ -354,7 +354,7 @@ function proxy_media_url(?string $url): ?string } $secret = config_get_default('insecure', 'Proxy', 'secret_key'); - $hash = hash_hmac('sha256', $url, $secret); + $hash = hash_hmac('sha256', rawurldecode($url), $secret); $encodedUrl = rawurlencode($url); return "/proxy.php?h={$hash}&u={$encodedUrl}";