diff --git a/app/controllers/api/avatars.php b/app/controllers/api/avatars.php index e0d967eb0..b9df4b634 100644 --- a/app/controllers/api/avatars.php +++ b/app/controllers/api/avatars.php @@ -23,6 +23,7 @@ use Utopia\Validator\URL; use Utopia\Validator\WhiteList; use chillerlan\QRCode\QRCode; use chillerlan\QRCode\QROptions; +use Utopia\Fetch\Client; $avatarCallback = function (string $type, string $code, int $width, int $height, int $quality, Response $response) { @@ -283,14 +284,17 @@ App::get('/v1/avatars/image') throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED); } - $fetch = @\file_get_contents($url); + $client = new Client(); + $res = $client + ->setAllowRedirects(false) + ->fetch($url); - if (!$fetch) { + if ($res->getStatusCode() !== 200) { throw new Exception(Exception::AVATAR_IMAGE_NOT_FOUND); } try { - $image = new Image($fetch); + $image = new Image($res->getBody()); } catch (\Exception $exception) { throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Unable to parse image'); } @@ -339,31 +343,23 @@ App::get('/v1/avatars/favicon') throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED); } - $curl = \curl_init(); + $client = new Client(); + $res = $client + ->setAllowRedirects(false) + ->setUserAgent(\sprintf( + APP_USERAGENT, + App::getEnv('_APP_VERSION', 'UNKNOWN'), + App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) + )) + ->fetch($url); - \curl_setopt_array($curl, [ - CURLOPT_RETURNTRANSFER => 1, - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_MAXREDIRS => 3, - CURLOPT_URL => $url, - CURLOPT_USERAGENT => \sprintf( - APP_USERAGENT, - App::getEnv('_APP_VERSION', 'UNKNOWN'), - App::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY) - ), - ]); - - $html = \curl_exec($curl); - - \curl_close($curl); - - if (!$html) { + if ($res->getStatusCode() !== 200) { throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED); } $doc = new DOMDocument(); $doc->strictErrorChecking = false; - @$doc->loadHTML($html); + @$doc->loadHTML($res->getBody()); $links = $doc->getElementsByTagName('link'); $outputHref = ''; @@ -418,9 +414,18 @@ App::get('/v1/avatars/favicon') throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED); } - if ('ico' == $outputExt) { // Skip crop, Imagick isn\'t supporting icon files - $data = @\file_get_contents($outputHref, false); + $client = new Client(); + $res = $client + ->setAllowRedirects(false) + ->fetch($outputHref); + if ($res->getStatusCode() !== 200) { + throw new Exception(Exception::AVATAR_ICON_NOT_FOUND); + } + + $data = $res->getBody(); + + if ('ico' == $outputExt) { // Skip crop, Imagick isn\'t supporting icon files if (empty($data) || (\mb_substr($data, 0, 5) === 'file($data); } - $fetch = @\file_get_contents($outputHref, false); - - if (!$fetch) { - throw new Exception(Exception::AVATAR_ICON_NOT_FOUND); - } - - $image = new Image($fetch); + $image = new Image($data); $image->crop((int) $width, (int) $height); $output = (empty($output)) ? $type : $output; $data = $image->output($output, $quality); diff --git a/composer.json b/composer.json index faf30a117..eaa6cfa20 100644 --- a/composer.json +++ b/composer.json @@ -54,6 +54,7 @@ "utopia-php/domains": "0.5.*", "utopia-php/dsn": "0.1.*", "utopia-php/framework": "0.33.*", + "utopia-php/fetch": "0.2.*", "utopia-php/image": "0.6.*", "utopia-php/locale": "0.4.*", "utopia-php/logger": "0.3.*", diff --git a/composer.lock b/composer.lock index c7fd4959b..606338c67 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9492cb777590ff776c2a73620783d74b", + "content-hash": "95d4c9ccd4b2f958ca247d83b04d1391", "packages": [ { "name": "adhocore/jwt", @@ -1352,6 +1352,45 @@ }, "time": "2022-10-26T10:06:20+00:00" }, + { + "name": "utopia-php/fetch", + "version": "0.2.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/fetch.git", + "reference": "1423c0ee3eef944d816ca6e31706895b585aea82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/fetch/zipball/1423c0ee3eef944d816ca6e31706895b585aea82", + "reference": "1423c0ee3eef944d816ca6e31706895b585aea82", + "shasum": "" + }, + "require": { + "php": ">=8.0" + }, + "require-dev": { + "laravel/pint": "^1.5.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Fetch\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A simple library that provides an interface for making HTTP Requests.", + "support": { + "issues": "https://github.com/utopia-php/fetch/issues", + "source": "https://github.com/utopia-php/fetch/tree/0.2.1" + }, + "time": "2024-03-18T11:50:59+00:00" + }, { "name": "utopia-php/framework", "version": "0.33.3", @@ -2585,16 +2624,16 @@ }, { "name": "matthiasmullie/minify", - "version": "1.3.72", + "version": "1.3.73", "source": { "type": "git", "url": "https://github.com/matthiasmullie/minify.git", - "reference": "531fdeef1911ffe27a53f8a19c297648c78f757e" + "reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/531fdeef1911ffe27a53f8a19c297648c78f757e", - "reference": "531fdeef1911ffe27a53f8a19c297648c78f757e", + "url": "https://api.github.com/repos/matthiasmullie/minify/zipball/cb7a9297b4ab070909cefade30ee95054d4ae87a", + "reference": "cb7a9297b4ab070909cefade30ee95054d4ae87a", "shasum": "" }, "require": { @@ -2644,7 +2683,7 @@ ], "support": { "issues": "https://github.com/matthiasmullie/minify/issues", - "source": "https://github.com/matthiasmullie/minify/tree/1.3.72" + "source": "https://github.com/matthiasmullie/minify/tree/1.3.73" }, "funding": [ { @@ -2652,7 +2691,7 @@ "type": "github" } ], - "time": "2024-03-13T12:02:00+00:00" + "time": "2024-03-15T10:27:10+00:00" }, { "name": "matthiasmullie/path-converter", @@ -4500,16 +4539,16 @@ }, { "name": "sebastian/resource-operations", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", "shasum": "" }, "require": { @@ -4521,7 +4560,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -4542,8 +4581,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" }, "funding": [ { @@ -4551,8 +4589,7 @@ "type": "github" } ], - "abandoned": true, - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-03-14T16:00:52+00:00" }, { "name": "sebastian/type",