From 16dbc6cff0952e5fbfc2991ef9bd9375882e9cb9 Mon Sep 17 00:00:00 2001 From: printempw Date: Sun, 5 Aug 2018 16:38:46 +0800 Subject: [PATCH] Fix timezone of Last-Modified header --- app/Http/Controllers/TextureController.php | 27 +++++--------- app/Models/Player.php | 12 +----- .../ResponseMacroServiceProvider.php | 37 ++++++++++--------- 3 files changed, 29 insertions(+), 47 deletions(-) diff --git a/app/Http/Controllers/TextureController.php b/app/Http/Controllers/TextureController.php index 8e0fd6bf..d01b2862 100644 --- a/app/Http/Controllers/TextureController.php +++ b/app/Http/Controllers/TextureController.php @@ -40,10 +40,8 @@ class TextureController extends Controller $content = $player->getJsonProfile(Option::get('api_type')); } - return Response::rawJson($content, 200, [ - 'Last-Modified' => Carbon::createFromTimestamp( - $player->getLastModified() - )->format('D, d M Y H:i:s \G\M\T') + return Response::jsonProfile($content, 200, [ + 'Last-Modified' => strtotime($player->last_modified) ]); } @@ -52,20 +50,20 @@ class TextureController extends Controller return $this->json($player_name, $api); } - public function texture($hash) { + public function texture($hash, $headers = [], $message = '') { try { if (Storage::disk('textures')->has($hash)) { - return Response::png(Storage::disk('textures')->get($hash), 200, [ + return Response::png(Storage::disk('textures')->get($hash), 200, array_merge([ 'Last-Modified' => Storage::disk('textures')->lastModified($hash), 'Accept-Ranges' => 'bytes', 'Content-Length' => Storage::disk('textures')->size($hash), - ]); + ], $headers)); } } catch (Exception $e) { report($e); } - return abort(404); + return abort(404, $message); } public function textureWithApi($api, $hash) { @@ -104,16 +102,9 @@ class TextureController extends Controller $player = $this->getPlayerInstance($player_name); if ($hash = $player->getTexture($type)) { - if (Storage::disk('textures')->has($hash)) { - // Cache friendly - return Response::png(Storage::disk('textures')->read($hash), 200, [ - 'Last-Modified' => $player->getLastModified(), - 'Accept-Ranges' => 'bytes', - 'Content-Length' => Storage::disk('textures')->size($hash), - ]); - } else { - abort(404, trans('general.texture-deleted')); - } + return $this->texture($hash, [ + 'Last-Modified' => strtotime($player->last_modified) + ], trans('general.texture-deleted')); } else { abort(404, trans('general.texture-not-uploaded', ['type' => $type])); } diff --git a/app/Models/Player.php b/app/Models/Player.php index 42f984bf..b39d0df2 100644 --- a/app/Models/Player.php +++ b/app/Models/Player.php @@ -249,7 +249,7 @@ class Player extends Model $sec_model = ($model == 'default') ? 'slim' : 'default'; if ($api_type == self::USM_API) { - $json['last_update'] = $this->getLastModified(); + $json['last_update'] = strtotime($this->last_modified); $json['model_preference'] = [$model, $sec_model]; } @@ -275,14 +275,4 @@ class Player extends Model $this->update(['last_modified' => Utils::getTimeFormatted()]); return event(new PlayerProfileUpdated($this)); } - - /** - * Get time of last modified. - * - * @return int|false - */ - public function getLastModified() - { - return strtotime($this['last_modified']); - } } diff --git a/app/Providers/ResponseMacroServiceProvider.php b/app/Providers/ResponseMacroServiceProvider.php index ac470a38..ca28a41c 100644 --- a/app/Providers/ResponseMacroServiceProvider.php +++ b/app/Providers/ResponseMacroServiceProvider.php @@ -16,41 +16,42 @@ class ResponseMacroServiceProvider extends ServiceProvider */ public function boot() { - Response::macro('png', function ($src = "", $status = 200, $header = []) { + Response::macro('png', function ($src = '', $status = 200, $header = []) { + // Handle fucking cache control $last_modified = Arr::pull($header, 'Last-Modified', time()); + $if_modified_since = strtotime(request()->headers->get('If-Modified-Since')); + $if_none_match = strtotime(request()->headers->get('If-None-Match')); $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'. + // Return `304 Not Modified` if given `If-Modified-Since` header + // is newer than our `Last-Modified` time or the `Etag` matches. + if ($if_modified_since >= $last_modified || $if_none_match == $etag) { + $src = ''; $status = 304; - $src = ""; } - return Response::stream(function() use ($src, $status) { - echo $src; - }, $status, array_merge([ + return Response::make($src, $status, array_merge([ 'Content-type' => 'image/png', - 'Last-Modified' => gmdate('D, d M Y H:i:s', $last_modified).' GMT', - 'Cache-Control' => 'public, max-age='.option('cache_expire_time'), // 365 days - 'Expires' => gmdate('D, d M Y H:i:s', $last_modified + option('cache_expire_time')).' GMT', + 'Last-Modified' => format_http_date($last_modified), + 'Cache-Control' => 'public, max-age='.option('cache_expire_time'), + 'Expires' => format_http_date($last_modified + option('cache_expire_time')), 'Etag' => $etag ], $header)); }); - Response::macro('rawJson', function ($src = "", $status = 200, $header = []) { - $last_modified = Arr::get($header, 'Last-Modified', time()); + Response::macro('jsonProfile', function ($src = '', $status = 200, $header = []) { + $last_modified = Arr::pull($header, 'Last-Modified', time()); + $if_modified_since = strtotime(request()->headers->get('If-Modified-Since')); - if (strtotime(Arr::get($_SERVER, 'If-Modified-Since')) >= $last_modified) { + if ($if_modified_since && $if_modified_since >= $last_modified) { + $src = ''; $status = 304; - $src = ""; } return Response::make($src, $status, array_merge([ 'Content-type' => 'application/json', - 'Cache-Control' => 'public, max-age='.option('cache_expire_time') // 365 days + 'Cache-Control' => 'public, max-age='.option('cache_expire_time'), + 'Last-Modified' => format_http_date($last_modified), ], $header)); }); }