From 084e04c30aa138fc3a1cb794ed788a4f7e88324d Mon Sep 17 00:00:00 2001 From: printempw Date: Sun, 25 Sep 2016 11:40:50 +0800 Subject: [PATCH] add caching headers --- app/Http/Controllers/TextureController.php | 32 ++++++------------- app/Listeners/CacheSkinPreview.php | 4 ++- app/Models/Player.php | 13 +++++--- .../ResponseMacroServiceProvider.php | 19 ++++++++++- 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/app/Http/Controllers/TextureController.php b/app/Http/Controllers/TextureController.php index 3b9748bb..13ffd8af 100644 --- a/app/Http/Controllers/TextureController.php +++ b/app/Http/Controllers/TextureController.php @@ -47,7 +47,11 @@ class TextureController extends Controller public function texture($hash) { if (Storage::disk('textures')->has($hash)) { - return Response::png(Storage::disk('textures')->get($hash)); + return Response::png(Storage::disk('textures')->get($hash), 200, [ + 'Last-Modified' => Storage::disk('textures')->lastModified($hash), + 'Accept-Ranges' => 'bytes', + 'Content-Length' => Storage::disk('textures')->size($hash), + ]); } else { abort(404); } @@ -64,12 +68,10 @@ class TextureController extends Controller if ($player->is_banned) abort(404, '该角色拥有者已被本站封禁。'); - if (!$this->checkCache($player_name)) { - $model_preference = ($player->getPreference() == "default") ? "steve" : "alex"; - $model = ($model == "") ? $model_preference : $model; + $model_preference = ($player->getPreference() == "default") ? "steve" : "alex"; + $model = ($model == "") ? $model_preference : $model; - return $player->getBinaryTexture($model); - } + return $player->getBinaryTexture($model); } public function skinWithModel($model, $player_name) @@ -84,9 +86,7 @@ class TextureController extends Controller if ($player->is_banned) abort(404, '该角色拥有者已被本站封禁。'); - if (!$this->checkCache($player_name)) { - return $player->getBinaryTexture('cape'); - } + return $player->getBinaryTexture('cape'); } public function avatar($base64_email, $size = 128) @@ -181,18 +181,4 @@ class TextureController extends Controller } - private function checkCache($player_name) - { - // Cache friendly - $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? - strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : null; - - if ($if_modified_since >= (new Player(0, $player_name))->getLastModified()) { - http_response_code(304); - return true; - } else { - return false; - } - } - } diff --git a/app/Listeners/CacheSkinPreview.php b/app/Listeners/CacheSkinPreview.php index bf1c2034..34d0aada 100644 --- a/app/Listeners/CacheSkinPreview.php +++ b/app/Listeners/CacheSkinPreview.php @@ -34,6 +34,8 @@ class CacheSkinPreview } } - return \Response::png(Storage::disk('cache')->get("preview/$tid-$size")); + return \Response::png(Storage::disk('cache')->get("preview/$tid-$size"), 200, [ + 'Last-Modified' => Storage::disk('cache')->lastModified("preview/$tid-$size") + ]); } } diff --git a/app/Models/Player.php b/app/Models/Player.php index 09b26e9a..6425f676 100644 --- a/app/Models/Player.php +++ b/app/Models/Player.php @@ -5,6 +5,8 @@ namespace App\Models; use View; use Event; use Utils; +use Storage; +use Response; use App\Events\GetPlayerJson; use App\Events\PlayerWasDeleted; use App\Events\PlayerProfileUpdated; @@ -105,12 +107,13 @@ class Player $hash = $this->getTexture($type); $path = BASE_DIR."/storage/textures/".$hash; - if (\Storage::disk('textures')->has($hash)) { + if (Storage::disk('textures')->has($hash)) { // Cache friendly - return response(\Storage::disk('textures')->get($hash)) - ->header('Content-Type', 'image/png') - ->header('Last-Modified', gmdate('D, d M Y H:i:s', $this->getLastModified()).' GMT') - ->header('Content-Length', filesize($path)); + return Response::png(Storage::disk('textures')->get($hash), 200, [ + 'Last-Modified' => $this->getLastModified(), + 'Accept-Ranges' => 'bytes', + 'Content-Length' => Storage::disk('textures')->size($hash), + ]); } else { abort(404, '请求的贴图已被删除。'); } diff --git a/app/Providers/ResponseMacroServiceProvider.php b/app/Providers/ResponseMacroServiceProvider.php index 623e38cf..279ca3d1 100644 --- a/app/Providers/ResponseMacroServiceProvider.php +++ b/app/Providers/ResponseMacroServiceProvider.php @@ -3,6 +3,7 @@ namespace App\Providers; use Response; +use Illuminate\Support\Arr; use Illuminate\Support\ServiceProvider; class ResponseMacroServiceProvider extends ServiceProvider @@ -16,10 +17,26 @@ class ResponseMacroServiceProvider extends ServiceProvider public function boot() { Response::macro('png', function ($src = "", $status = 200, $header = []) { + $last_modified = Arr::pull($header, 'Last-Modified', time()); + $etag = md5($src); + + // Checking if the client is validating his cache and if it is current. + if ((strtotime(Arr::get($_SERVER, 'If-Modified-Since')) == $last_modified) || + trim(Arr::get($_SERVER, 'HTTP_IF_NONE_MATCH')) == $etag + ) { + // Client's cache IS current, so we just respond '304 Not Modified'. + $status = 304; + $src = ""; + } + return Response::stream(function() use ($src, $status) { echo $src; }, $status, array_merge([ - 'Content-type' => 'image/png', + 'Content-type' => 'image/png', + 'Last-Modified' => gmdate('D, d M Y H:i:s', $last_modified).' GMT', + 'Cache-Control' => 'public, max-age=31536000', // 365 days + 'Expires' => gmdate('D, d M Y H:i:s', $last_modified + 31536000).' GMT', + 'Etag' => $etag ], $header)); });