/** * Intercept a request for a cached image from the proxy and output it * * @param string|bool $error If non-false, an error that occurred when validating the request */ protected function _outputImage($error) { if (empty(XenForo_Application::getOptions()->imageLinkProxy['images'])) { $error = 'disabled'; } /* @var $proxyModel XenForo_Model_ImageProxy */ $proxyModel = XenForo_Model::create('XenForo_Model_ImageProxy'); $image = false; if (!$error) { $urlParts = parse_url($this->_url); if ($this->_isLocalHost($urlParts['host']) && (empty($_SERVER['SERVER_NAME']) || !$this->_isLocalHost($_SERVER['SERVER_NAME']))) { $error = 'local_url'; } } if (!$error) { $image = $proxyModel->getImage($this->_url); if ($image) { $image = $proxyModel->prepareImage($image); if ($image['use_file']) { $proxyModel->logImageView($image); $eTag = !empty($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] : null; if ($eTag && $eTag == '"' . $image['fetch_date'] . '"') { $this->_response->setHttpResponseCode(304); $this->_response->clearHeader('Last-Modified'); $this->_response->sendHeaders(); return; } } else { $image = false; $error = 'retrieve_failed'; } } } if (!$image) { $image = $proxyModel->getPlaceHolderImage(); } $imageTypes = array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/png'); if (in_array($image['mime_type'], $imageTypes)) { $this->_response->setHeader('Content-type', $image['mime_type'], true); $this->_setDownloadFileName($image['file_name'], true); } else { $this->_response->setHeader('Content-type', 'application/octet-stream', true); $this->_setDownloadFileName($image['file_name']); } if (!$error) { $this->_response->setHeader('ETag', '"' . $image['fetch_date'] . '"', true); } if ($image['file_size']) { $this->_response->setHeader('Content-Length', $image['file_size'], true); } $this->_response->setHeader('X-Content-Type-Options', 'nosniff'); if ($error) { $this->_response->setHeader('X-Proxy-Error', $error); } $this->_response->sendHeaders(); $imageData = new XenForo_FileOutput($image['file_path']); $imageData->output(); }