X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModule%2FProxy.php;h=419289c39f6e2927b57871c20abec77e89d39880;hb=6dbbd081795fa1c8fe57db2248ac162efeeada88;hp=e43852baba0e8906890cb3be41f5261ca755b05b;hpb=53e38b03130ea798bba44db44ccb7f331dc4b91d;p=friendica.git diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php index e43852baba..419289c39f 100644 --- a/src/Module/Proxy.php +++ b/src/Module/Proxy.php @@ -1,6 +1,6 @@ getRequestInfo(); - /// @TODO Stop here? - exit(); + if (!DI::config()->get('system', 'proxify_content')) { + Logger::notice('Proxy access is forbidden', ['request' => $request, 'agent' => $_SERVER['HTTP_USER_AGENT'] ?? '', 'accept' => $_SERVER['HTTP_ACCEPT'] ?? '']); + throw new \Friendica\Network\HTTPException\NotFoundException(); } - if (function_exists('header_remove')) { - header_remove('Pragma'); - header_remove('pragma'); + if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) { + header("Last-Modified: " . gmdate("D, d M Y H:i:s", time()) . " GMT"); + if (!empty($_SERVER["HTTP_IF_NONE_MATCH"])) { + header("Etag: " . $_SERVER["HTTP_IF_NONE_MATCH"]); + } + header("Expires: " . gmdate("D, d M Y H:i:s", time() + (31536000)) . " GMT"); + header("Cache-Control: max-age=31536000"); + if (function_exists("header_remove")) { + header_remove("Last-Modified"); + header_remove("Expires"); + header_remove("Cache-Control"); + } + throw new NotModifiedException(); } - $direct_cache = self::setupDirectCache(); - - $request = self::getRequestInfo(); - if (empty($request['url'])) { throw new \Friendica\Network\HTTPException\BadRequestException(); } - // Webserver already tried direct cache... - - // Try to use filecache; - $cachefile = self::responseFromCache($request); - - // Try to use photo from db - self::responseFromDB($request); - - // - // If script is here, the requested url has never cached before. - // Let's fetch it, scale it if required, then save it in cache. - // + if (!local_user()) { + Logger::info('Redirecting not logged in user to original address', ['url' => $request['url']]); + System::externalRedirect($request['url']); + } // It shouldn't happen but it does - spaces in URL $request['url'] = str_replace(' ', '+', $request['url']); - $fetchResult = HTTPSignature::fetchRaw($request['url'], local_user(), ['timeout' => 10]); + + // Fetch the content with the local user + $fetchResult = HTTPSignature::fetchRaw($request['url'], local_user(), ['accept_content' => [], 'timeout' => 10]); $img_str = $fetchResult->getBody(); - // If there is an error then return a blank image - if ((substr($fetchResult->getReturnCode(), 0, 1) == '4') || empty($img_str)) { + if (!$fetchResult->isSuccess() || empty($img_str)) { Logger::info('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); self::responseError(); // stop. } - $tempfile = tempnam(get_temppath(), 'cache'); - file_put_contents($tempfile, $img_str); - $mime = mime_content_type($tempfile); - unlink($tempfile); + $mime = Images::getMimeTypeByData($img_str); $image = new Image($img_str, $mime); if (!$image->isValid()) { @@ -126,100 +99,53 @@ class Proxy extends BaseModule // stop. } - $basepath = $a->getBasePath(); - $filepermission = DI::config()->get('system', 'proxy_file_chmod'); - - // Store original image - if ($direct_cache) { - // direct cache , store under ./proxy/ - $filename = $basepath . '/proxy/' . ProxyUtils::proxifyUrl($request['url'], true); - file_put_contents($filename, $image->asString()); - if (!empty($filepermission)) { - chmod($filename, $filepermission); - } - } elseif($cachefile !== '') { - // cache file - file_put_contents($cachefile, $image->asString()); - } else { - // database - Photo::store($image, 0, 0, $request['urlhash'], $request['url'], '', 100); - } - - // reduce quality - if it isn't a GIF if ($image->getType() != 'image/gif') { $image->scaleDown($request['size']); } - - // Store scaled image - if ($direct_cache && $request['sizetype'] != '') { - $filename = $basepath . '/proxy/' . ProxyUtils::proxifyUrl($request['url'], true) . $request['sizetype']; - file_put_contents($filename, $image->asString()); - if (!empty($filepermission)) { - chmod($filename, $filepermission); - } - } - self::responseImageHttpCache($image); // stop. } - /** * Build info about requested image to be proxied * * @return array * [ * 'url' => requested url, - * 'urlhash' => sha1 has of the url prefixed with 'pic:', * 'size' => requested image size (int) * 'sizetype' => requested image size (string): ':micro', ':thumb', ':small', ':medium', ':large' * ] * @throws \Exception */ - private static function getRequestInfo() + private function getRequestInfo() { - $a = DI::app(); - $size = 1024; + $size = ProxyUtils::PIXEL_LARGE; $sizetype = ''; - // Look for filename in the arguments - // @TODO: Replace with parameter from router - if (($a->argc > 1) && !isset($_REQUEST['url'])) { - if (isset($a->argv[3])) { - $url = $a->argv[3]; - } elseif (isset($a->argv[2])) { - $url = $a->argv[2]; - } else { - $url = $a->argv[1]; - } - - /// @TODO: Why? And what about $url in this case? - /// @TODO: Replace with parameter from router - if (isset($a->argv[3]) && ($a->argv[3] == 'thumb')) { - $size = 200; - } + if (!empty($this->parameters['url']) && empty($_REQUEST['url'])) { + $url = $this->parameters['url']; // thumb, small, medium and large. if (substr($url, -6) == ':micro') { - $size = 48; + $size = ProxyUtils::PIXEL_MICRO; $sizetype = ':micro'; $url = substr($url, 0, -6); } elseif (substr($url, -6) == ':thumb') { - $size = 80; + $size = ProxyUtils::PIXEL_THUMB; $sizetype = ':thumb'; $url = substr($url, 0, -6); } elseif (substr($url, -6) == ':small') { - $size = 300; + $size = ProxyUtils::PIXEL_SMALL; $url = substr($url, 0, -6); $sizetype = ':small'; } elseif (substr($url, -7) == ':medium') { - $size = 600; + $size = ProxyUtils::PIXEL_MEDIUM; $url = substr($url, 0, -7); $sizetype = ':medium'; } elseif (substr($url, -6) == ':large') { - $size = 1024; + $size = ProxyUtils::PIXEL_LARGE; $url = substr($url, 0, -6); $sizetype = ':large'; } @@ -232,87 +158,17 @@ class Proxy extends BaseModule $url = str_replace(['.jpg', '.jpeg', '.gif', '.png'], ['','','',''], $url); $url = base64_decode(strtr($url, '-_', '+/'), true); - } else { $url = $_REQUEST['url'] ?? ''; } return [ 'url' => $url, - 'urlhash' => 'pic:' . sha1($url), 'size' => $size, 'sizetype' => $sizetype, ]; } - - /** - * setup ./proxy folder for direct cache - * - * @return bool False if direct cache can't be used. - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - */ - private static function setupDirectCache() - { - $a = DI::app(); - $basepath = $a->getBasePath(); - - // If the cache path isn't there, try to create it - if (!is_dir($basepath . '/proxy') && is_writable($basepath)) { - mkdir($basepath . '/proxy'); - } - - // Checking if caching into a folder in the webroot is activated and working - $direct_cache = (is_dir($basepath . '/proxy') && is_writable($basepath . '/proxy')); - // we don't use direct cache if image url is passed in args and not in querystring - $direct_cache = $direct_cache && ($a->argc > 1) && !isset($_REQUEST['url']); - - return $direct_cache; - } - - - /** - * Try to reply with image in cachefile - * - * @param array $request Array from getRequestInfo - * - * @return string Cache file name, empty string if cache is not enabled. - * - * If cachefile exists, script ends here and this function will never returns - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @throws \ImagickException - */ - private static function responseFromCache(&$request) - { - $cachefile = get_cachefile(hash('md5', $request['url'])); - if ($cachefile != '' && file_exists($cachefile)) { - $img = new Image(file_get_contents($cachefile), mime_content_type($cachefile)); - self::responseImageHttpCache($img); - // stop. - } - return $cachefile; - } - - /** - * Try to reply with image in database - * - * @param array $request Array from getRequestInfo - * - * If the image exists in database, then script ends here and this function will never returns - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @throws \ImagickException - */ - private static function responseFromDB(&$request) - { - $photo = Photo::getPhoto($request['urlhash']); - - if ($photo !== false) { - $img = Photo::getImageForPhoto($photo); - self::responseImageHttpCache($img); - // stop. - } - } - /** * In case of an error just stop. We don't return content to avoid caching problems *