private function readUrl_Curl($url, $destFile, ImThumb $requestor) { self::$curlFH = @fopen($destFile, 'w'); if (!self::$curlFH) { throw new ImThumbException('Could not open cache file for remote image', ImThumb::ERR_CACHE); } self::$curlDataWritten = 0; $curl = curl_init($url); curl_setopt($curl, CURLOPT_TIMEOUT, $requestor->param('externalRequestTimeout')); curl_setopt($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.122 Safari/534.30"); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($curl, CURLOPT_HEADER, 0); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_WRITEFUNCTION, 'ImThumbSource_HTTP::curlWrite'); @curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); @curl_setopt($curl, CURLOPT_MAXREDIRS, 10); $curlResult = curl_exec($curl); $httpStatus = curl_getinfo($curl, CURLINFO_HTTP_CODE); fclose(self::$curlFH); curl_close($curl); if ($httpStatus == 404) { throw new ImThumbNotFoundException('Could not locate remote image', ImThumb::ERR_SRC_IMAGE); } if ($httpStatus == 302) { throw new ImThumbNotFoundException("External Image is Redirecting. Try alternate image url", ImThumb::ERR_SRC_IMAGE); } if (!$curlResult) { throw new ImThumbException("Internal cURL error fetching remote file", ImThumb::ERR_SRC_IMAGE); } }
public function validateWith(ImThumb $generator) { if (!$this->valid) { throw new ImThumbNotFoundException("Could not read image metadata", ImThumb::ERR_SRC_IMAGE); } if ($this->fileSize > $generator->param('maxSize')) { throw new ImThumbException("Image file exceeds maximum processable size", ImThumb::ERR_SRC_IMAGE); } }
public function readMetadata($src, ImThumb $requestor) { $fallbackMeta = new ImThumbMeta(); $src = $this->getRealImagePath($src, $requestor->param('baseDir')); $mtime = @filemtime($src); if (false === $mtime) { return $fallbackMeta->invalid(); } $fileSize = @filesize($src); $sData = @getimagesize($src); // ensure it's an image if (!$sData) { return $fallbackMeta->invalid(); } $mimeType = strtolower($sData['mime']); if (!preg_match('/^image\\//i', $mimeType)) { $mimeType = 'image/' . $mimeType; } if ($mimeType == 'image/jpg') { $mimeType = 'image/jpeg'; } return new ImThumbMeta($src, $mtime, $fileSize, $mimeType); }
public static function processRequest(array $params) { // set timezone if unset to avoid warnings date_default_timezone_set(@date_default_timezone_get()); // set memory limit if required if ($params['memoryLimit']) { $inibytes = self::returnBytes(ini_get('memory_limit')); $ourbytes = self::returnBytes($params['memoryLimit']); if ($inibytes < $ourbytes) { @ini_set('memory_limit', $params['memoryLimit']); } } // load up the configured rate limiter class, if any if (!empty($params['rateLimiter'])) { $limiter = $params['rateLimiter']; // if the configured class does not exist, this is a hack attempt and someone is hitting the imthumb.php script directly to bypass rate limiting if (!class_exists($limiter)) { $remoteIPString = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '')); throw new ImThumbCriticalException("Rate limiter class not found, hack attempt! Source {$remoteIPString}", ImThumb::ERR_HACK_ATTEMPT); } $params['rateLimiter'] = new $limiter(); } $handler = new ImThumb($params); $http = new ImThumbHTTP($handler, $params); try { // check for referrer if (!$params['externalReferrerAllowed'] && !self::isReferrerOk()) { self::quickImageResponse('leeching'); } // check for rate limiting if (!$handler->checkRateLimits()) { self::quickImageResponse('ratelimited'); } // load up the image $handler->loadImage($params['src']); // check for browser cache if ($handler->hasBrowserCache()) { $http->sendHeaders(); exit(0); } // check and write to caches if (!$handler->writeCache()) { // check cache directory for expired content if we processed an already cached image if ($handler->cache) { $handler->cache->checkExpiredCaches(); } } // output the image and all headers if (!$http->display()) { // nothing to display, we aren't configured to show any fallback 404 image throw new ImThumbCriticalException("Source image not found. Source querystring: {$_SERVER['QUERY_STRING']}", ImThumb::ERR_SERVER_CONFIG); } } catch (Exception $e) { if ($e instanceof ImThumbCriticalException) { throw $e; } // attempt to load any configured error image. If this errors out it will just throw the exception naturally. $handler->loadErrorImage(); $handler->configureUnalteredFitImage(); $handler->doResize(); if ($e instanceof ImThumbException) { if ($e->getCode() == ImThumb::ERR_SRC_IMAGE) { // log the querystring passed in addition to regular message $msg = $e->getMessage() . ' Source querystring: ' . $_SERVER['QUERY_STRING']; } else { $msg = $e->getMessage(); } } else { $msg = 'Unknown error ' . $e->getCode() . ': ' . $e->getMessage(); } $theImage = $handler->getImage(); if (!$theImage) { throw $e; } $http->sendHeaders($msg); echo $theImage; exit(0); } }
public function getCachePath(ImThumb $imageHandle, $src = null) { $cacheDir = $this->baseDir; if (!$cacheDir) { return false; } if (!$src) { $src = $imageHandle->getSrc(); } $extension = substr($src, strrpos($src, '.') + 1); if ($this->cacheFilenameFormat) { list($width, $height) = $imageHandle->getTargetSize(); return $cacheDir . '/' . str_replace(array('%filename%', '%ext%', '%w%', '%h%', '%q%', '%a%', '%zc%', '%s%', '%cc%', '%ct%', '%cr%', '%filters%', '%pjpg%', '%upscale%'), array(basename($src, '.' . $extension), $extension, $width, $height, $imageHandle->param('quality'), $imageHandle->param('align'), $imageHandle->param('cropMode'), $imageHandle->param('sharpen') ? 's' : '', $imageHandle->param('canvasColor'), $imageHandle->param('canvasTransparent') ? 't' : '', $imageHandle->param('cropRect'), $imageHandle->param('filters'), $imageHandle->param('jpgProgressive') ? 'p' : '', $imageHandle->param('upscale') ? '' : 'nu'), $this->cacheFilenameFormat); } return $cacheDir . '/' . $this->cachePrefix . md5($this->cacheSalt . json_encode($imageHandle->params()) . ImThumb::VERSION) . $this->cacheSuffix; }
} $tryFile = '/imthumb-source-' . strtolower(str_replace('ImThumbSource_', '', $class)) . '.class.php'; if (file_exists(IMTHUMB_BASE . $tryFile)) { require_once IMTHUMB_BASE . $tryFile; return true; } if ($this->params['extraSourceHandlerPath'] && file_exists($this->params['extraSourceHandlerPath'] . $tryFile)) { require_once $this->params['extraSourceHandlerPath'] . $tryFile; return true; } return false; } //-------------------------------------------------------------------------- // Rate limiting /** * @return true if rate is OK, false if exceeded */ public function checkRateLimits() { if ($limiter = $this->param('rateLimiter')) { $limiter->setGenerator($this); if (!$limiter->checkRateLimits()) { return false; } } return true; } } ImThumb::$HAS_MBSTRING = extension_loaded('mbstring'); ImThumb::$MBSTRING_SHADOW = (int) ini_get('mbstring.func_overload');