From 11b6078c57ff2eab80347a639432686dc499f0c0 Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Sun, 22 Jul 2018 10:00:30 +0800 Subject: [PATCH] Add error control for retrieving textures --- app/Http/Controllers/TextureController.php | 104 +++++++++++---------- tests/TextureControllerTest.php | 12 +++ 2 files changed, 67 insertions(+), 49 deletions(-) diff --git a/app/Http/Controllers/TextureController.php b/app/Http/Controllers/TextureController.php index 66cb3ac9..9906b4e5 100644 --- a/app/Http/Controllers/TextureController.php +++ b/app/Http/Controllers/TextureController.php @@ -7,6 +7,7 @@ use Option; use Storage; use Response; use Minecraft; +use Exception; use Carbon\Carbon; use App\Models\User; use App\Models\Player; @@ -16,6 +17,7 @@ use App\Events\GetSkinPreview; use App\Events\GetAvatarPreview; use App\Exceptions\PrettyPageException; use App\Services\Repositories\UserRepository; +use Symfony\Component\HttpFoundation\Response as SymfonyResponse; class TextureController extends Controller { @@ -51,15 +53,19 @@ class TextureController extends Controller } public function texture($hash) { - if (Storage::disk('textures')->has($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 { - return abort(404); + try { + if (Storage::disk('textures')->has($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), + ]); + } + } catch (Exception $e) { + report($e); } + + return abort(404); } public function textureWithApi($api, $hash) { @@ -121,22 +127,26 @@ class TextureController extends Controller $tid = $user->getAvatarId(); if ($t = Texture::find($tid)) { - if (Storage::disk('textures')->has($t->hash)) { - $responses = event(new GetAvatarPreview($t, $size)); + try { + if (Storage::disk('textures')->has($t->hash)) { + $responses = event(new GetAvatarPreview($t, $size)); - if (isset($responses[0]) && $responses[0] instanceof \Symfony\Component\HttpFoundation\Response) { - return $responses[0]; // @codeCoverageIgnore - } else { - $png = Minecraft::generateAvatarFromSkin(Storage::disk('textures')->read($t->hash), $size); + if (isset($responses[0]) && $responses[0] instanceof SymfonyResponse) { + return $responses[0]; // @codeCoverageIgnore + } else { + $png = Minecraft::generateAvatarFromSkin(Storage::disk('textures')->read($t->hash), $size); - ob_start(); - imagepng($png); - imagedestroy($png); - $image = ob_get_contents(); - ob_end_clean(); + ob_start(); + imagepng($png); + imagedestroy($png); + $image = ob_get_contents(); + ob_end_clean(); - return Response::png($image); + return Response::png($image); + } } + } catch (Exception $e) { + report($e); } } } @@ -159,28 +169,32 @@ class TextureController extends Controller public function preview($tid, $size = 250) { if ($t = Texture::find($tid)) { - if (Storage::disk('textures')->has($t->hash)) { - $responses = event(new GetSkinPreview($t, $size)); + try { + if (Storage::disk('textures')->has($t->hash)) { + $responses = event(new GetSkinPreview($t, $size)); - if (isset($responses[0]) && $responses[0] instanceof \Symfony\Component\HttpFoundation\Response) { - return $responses[0]; // @codeCoverageIgnore - } else { - $binary = Storage::disk('textures')->read($t->hash); - - if ($t->type == "cape") { - $png = Minecraft::generatePreviewFromCape($binary, $size*0.8, $size*1.125, $size); + if (isset($responses[0]) && $responses[0] instanceof \Symfony\Component\HttpFoundation\Response) { + return $responses[0]; // @codeCoverageIgnore } else { - $png = Minecraft::generatePreviewFromSkin($binary, $size, ($t->type == 'alex'), 'both', 4); + $binary = Storage::disk('textures')->read($t->hash); + + if ($t->type == "cape") { + $png = Minecraft::generatePreviewFromCape($binary, $size*0.8, $size*1.125, $size); + } else { + $png = Minecraft::generatePreviewFromSkin($binary, $size, ($t->type == 'alex'), 'both', 4); + } + + ob_start(); + imagepng($png); + imagedestroy($png); + $image = ob_get_contents(); + ob_end_clean(); + + return Response::png($image); } - - ob_start(); - imagepng($png); - imagedestroy($png); - $image = ob_get_contents(); - ob_end_clean(); - - return Response::png($image); } + } catch (Exception $e) { + report($e); } } @@ -205,17 +219,9 @@ class TextureController extends Controller abort(404); } - if ($t = Texture::find($tid)) { - - if (Storage::disk('textures')->has($t->hash)) { - return Response::png(Storage::disk('textures')->get($t->hash)); - } else { - return abort(404, trans('general.texture-deleted')); - } - } else { - return abort(404, trans('skinlib.non-existent')); - } - + return ($t = Texture::find($tid)) + ? $this->texture($t->hash) + : abort(404, trans('skinlib.non-existent')); } protected function getPlayerInstance($player_name) diff --git a/tests/TextureControllerTest.php b/tests/TextureControllerTest.php index 9cb49d0d..afd2be31 100644 --- a/tests/TextureControllerTest.php +++ b/tests/TextureControllerTest.php @@ -83,6 +83,9 @@ class TextureControllerTest extends TestCase ->assertHeader('Accept-Ranges', 'bytes') ->assertHeader('Content-Length', Storage::disk('textures')->size($steve->hash)) ->assertSuccessful(); + + Storage::shouldReceive('disk')->with('textures')->andThrow(new Exception); + $this->get('/textures/'.$steve->hash)->assertNotFound(); } public function testTextureWithApi() @@ -178,6 +181,10 @@ class TextureControllerTest extends TestCase $this->expectsEvents(\App\Events\GetAvatarPreview::class); $this->get('/avatar/'.base64_encode($user->email).'.png') ->assertHeader('Content-Type', 'image/png'); + + Storage::shouldReceive('disk')->with('textures')->andThrow(new Exception); + $this->get('/avatar/'.base64_encode($user->email).'.png') + ->assertHeader('Content-Type', 'image/png'); } public function testAvatarWithSize() @@ -226,6 +233,10 @@ class TextureControllerTest extends TestCase ->andReturn(imagecreatefromstring($png)); $this->get("/preview/{$cape->tid}.png") ->assertHeader('Content-Type', 'image/png'); + + Storage::shouldReceive('disk')->with('textures')->andThrow(new Exception); + $this->get("/preview/{$steve->tid}.png") + ->assertHeader('Content-Type', 'image/png'); } public function testPreviewWithSize() @@ -241,6 +252,7 @@ class TextureControllerTest extends TestCase // Not found $this->get('/raw/0.png') + ->assertNotFound() ->assertSee(trans('skinlib.non-existent')); // Success