diff --git a/core/inlineimage.class.inc.php b/core/inlineimage.class.inc.php
index a204ca493..4782efff4 100644
--- a/core/inlineimage.class.inc.php
+++ b/core/inlineimage.class.inc.php
@@ -16,7 +16,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with iTop. If not, see
');
}
$.post(sUrl, oParams, function(data) {
- var sDownloadLink = GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?operation=download_document&class=Attachment&field=contents&id='+data.att_id;
+ var sDownloadLink = GetAbsoluteUrlAppRoot()+'pages/ajax.document.php?operation=download_document&class=Attachment&field=contents&id='+data.att_id;
var sIcon = GetAbsoluteUrlModulesRoot()+'itop-attachments/icons/pdf.png';
if (jTab != null)
{
diff --git a/pages/ajax.document.php b/pages/ajax.document.php
new file mode 100644
index 000000000..64358aac1
--- /dev/null
+++ b/pages/ajax.document.php
@@ -0,0 +1,106 @@
+
+
+
+/**
+ * Handles various ajax requests
+ *
+ * @copyright Copyright (C) 2010-2016 Combodo SARL
+ * @license http://opensource.org/licenses/AGPL-3.0
+ */
+
+require_once('../approot.inc.php');
+require_once(APPROOT.'application/utils.inc.php');
+
+
+if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) && (strlen($_SERVER['HTTP_IF_MODIFIED_SINCE']) > 0))
+{
+ // The content is garanteed to be unmodified since the URL includes a signature based on the contents of the document
+ header('not modified', true, 304);
+ exit;
+}
+
+try
+{
+ require_once(APPROOT.'/application/application.inc.php');
+ require_once(APPROOT.'/application/webpage.class.inc.php');
+ require_once(APPROOT.'/application/ajaxwebpage.class.inc.php');
+ require_once(APPROOT.'/application/startup.inc.php');
+
+ require_once(APPROOT.'/application/loginwebpage.class.inc.php');
+ LoginWebPage::DoLoginEx(null /* any portal */, false);
+
+ $oPage = new ajax_page("");
+ $oPage->no_cache();
+
+ $operation = utils::ReadParam('operation', '');
+ $sClass = utils::ReadParam('class', 'MissingAjaxParam', false, 'class');
+
+ switch($operation)
+ {
+ case 'download_document':
+ $id = utils::ReadParam('id', '');
+ $sField = utils::ReadParam('field', '');
+ if ($sClass == 'Attachment')
+ {
+ $iCacheSec = 31556926; // One year ahead: an attachment cannot change
+ }
+ else
+ {
+ $iCacheSec = (int)utils::ReadParam('cache', 0);
+ }
+ if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField))
+ {
+ ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'attachment');
+ if ($iCacheSec > 0)
+ {
+ $oPage->add_header("Expires: "); // Reset the value set in ajax_page
+ $oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec");
+ $oPage->add_header("Pragma: cache"); // Reset the value set .... where ?
+ $oPage->add_header("Last-Modified: Wed, 15 Jun 2015 13:21:15 GMT"); // An arbitrary date in the past is ok
+ }
+ }
+ break;
+
+ case 'download_inlineimage':
+ $id = utils::ReadParam('id', '');
+ $sSecret = utils::ReadParam('s', '');
+ $iCacheSec = 31556926; // One year ahead: an inline image cannot change
+ if (!empty($id) && !empty($sSecret))
+ {
+ ormDocument::DownloadDocument($oPage, 'InlineImage', $id, 'contents', 'attachment', 'secret', $sSecret);
+ $oPage->add_header("Expires: "); // Reset the value set in ajax_page
+ $oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec");
+ $oPage->add_header("Pragma: cache"); // Reset the value set .... where ?
+ $oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok
+ }
+ break;
+
+ default:
+ $oPage->p("Invalid query.");
+ }
+
+ $oPage->output();
+}
+catch (Exception $e)
+{
+ // note: transform to cope with XSS attacks
+ echo htmlentities($e->GetMessage(), ENT_QUOTES, 'utf-8');
+ IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
+}
+
diff --git a/pages/ajax.render.php b/pages/ajax.render.php
index 94caa8be0..76debff93 100644
--- a/pages/ajax.render.php
+++ b/pages/ajax.render.php
@@ -772,22 +772,7 @@ try
$sField = utils::ReadParam('field', '');
if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField))
{
- DownloadDocument($oPage, $sClass, $id, $sField, 'inline');
- }
- break;
-
- case 'download_document':
- $id = utils::ReadParam('id', '');
- $sField = utils::ReadParam('field', '');
- $iCacheSec = (int) utils::ReadParam('cache', 0);
- if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField))
- {
- DownloadDocument($oPage, $sClass, $id, $sField, 'attachment');
- if ($iCacheSec > 0)
- {
- $oPage->add_header("Expires: "); // Reset the value set in ajax_page
- $oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec");
- }
+ ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'inline');
}
break;
@@ -2433,21 +2418,6 @@ EOF
$oPage->add("");
break;
- case 'download_inlineimage':
- $id = utils::ReadParam('id', '');
- $sSecret = utils::ReadParam('s', '');
- $iCacheSec = (int) utils::ReadParam('cache', 0);
- if (!empty($id) && !empty($sSecret))
- {
- DownloadDocument($oPage, 'InlineImage', $id, 'contents', 'attachment', 'secret', $sSecret);
- if ($iCacheSec > 0)
- {
- $oPage->add_header("Expires: "); // Reset the value set in ajax_page
- $oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec");
- }
- }
- break;
-
case 'custom_fields_update':
$oPage->SetContentType('application/json');
$sAttCode = utils::ReadParam('attcode', '');
@@ -2489,47 +2459,3 @@ catch (Exception $e)
echo htmlentities($e->GetMessage(), ENT_QUOTES, 'utf-8');
IssueLog::Error($e->getMessage()."\nDebug trace:\n".$e->getTraceAsString());
}
-
-
-
-/**
- * Downloads a document to the browser, either as 'inline' or 'attachment'
- *
- * @param WebPage $oPage The web page for the output
- * @param string $sClass Class name of the object
- * @param mixed $id Identifier of the object
- * @param string $sAttCode Name of the attribute containing the document to download
- * @param string $sContentDisposition Either 'inline' or 'attachment'
- * @param string $sSecretField The attcode of the field containing a "secret" to be provided in order to retrieve the file
- * @param string $sSecretValue The value of the secret to be compared with the value of the attribute $sSecretField
- * @return none
- */
-function DownloadDocument(WebPage $oPage, $sClass, $id, $sAttCode, $sContentDisposition = 'attachment', $sSecretField = null, $sSecretValue = null)
-{
- try
- {
- $oObj = MetaModel::GetObject($sClass, $id, false, false);
- if (!is_object($oObj))
- {
- throw new Exception("Invalid id ($id) for class '$sClass' - the object does not exist or you are not allowed to view it");
- }
- if (($sSecretField != null) && ($oObj->Get($sSecretField) != $sSecretValue))
- {
- usleep(200);
- throw new Exception("Invalid secret for class '$sClass' - the object does not exist or you are not allowed to view it");
- }
- $oDocument = $oObj->Get($sAttCode);
- if (is_object($oDocument))
- {
- $oPage->TrashUnexpectedOutput();
- $oPage->SetContentType($oDocument->GetMimeType());
- $oPage->SetContentDisposition($sContentDisposition,$oDocument->GetFileName());
- $oPage->add($oDocument->GetData());
- }
- }
- catch(Exception $e)
- {
- $oPage->p($e->getMessage());
- }
-}
-?>