[PHP]
class ReportGenerator {
function ReportGenerator () {}
/**
* Generate the HTTP headers necessary for this file type. Can be
called statically
*
* @access public
* @param mixed $filename
* @see file_get_conten ts
* @see actual_path
*/
function &generateHTTPHe aders($filename ) { // STATIC VOID METHOD
if (!preg_match('/.+\.[a-zA-Z0-9\-_]+$/i', $filename)) die("Filename:
\"$filename\ " must have an extension");
$ext = substr($filenam e, strrpos($filena me, '.') + 1,
strlen($filenam e));
switch (strtolower(tri m($ext))) {
case 'pdf':
$ctype = 'application/pdf';
break;
case 'exe':
$ctype = 'application/octet-stream';
break;
case 'zip':
$ctype = 'appliation/zip';
break;
case 'doc':
$ctype = 'application/msword';
break;
case 'xls':
$ctype = 'application/vnd.ms-excel';
break;
case 'csv':
$ctype = 'application/vnd.ms-excel';
break;
case 'ppt':
$ctype = 'application/vnd.ms-powerpoint';
break;
case 'gif':
$ctype = 'image/gif';
break;
case 'png':
$ctype = 'image/png';
break;
case 'jpg':
$ctype = 'image/jpg';
break;
case 'jpeg':
$ctype = 'image/jpg';
break;
default:
$ctype = 'application/force-download';
break;
}
header('Pragma: public');
header('Expires : 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Type: $ctype");
$user_agent = strtolower($_SE RVER['HTTP_USER_AGEN T']);
if ((is_integer(st rpos($user_agen t, 'msie'))) &&
(is_integer(str pos($user_agent , 'win')))) {
header('Content-Disposition: filename=' .
basename(actual _path($filename )) . ';');
} else {
header('Content-Disposition: inline; filename=' .
basename(actual _path($filename )) . ';');
}
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . @filesize(actua l_path($filenam e)));
if (function_exist s('file_get_con tents')) {
echo @file_get_conte nts(actual_path ($filename));
} else {
@readfile(actua l_path($filenam e));
}
}
}
[/PHP]
The class method generateHTTPHea ders() can be called statically to
force-download a file (Excel, CSV, PDF, etc.) per customer requirement.
However, upon attempting to do so:
[PHP]
// REAL IMPORTANT!!! CHMOD OR THE WORLD CAN SEE YOUR REPORTS!!!!!!!
if ($this->isSuccessful ) @chmod(0770,
actual_path($ne wReportFileName )); // CHANGE PERMISSIONS (IF IN UNIX)
TO PREVENT WORLD FROM ACCESSING FILE
if ($this->isSuccessful )
ReportGenerator ::generateHTTPH eaders($newRepo rtFileName); // THIS
CAUSES THE FORCED DOWNLOAD
@unlink(actual_ path($newReport FileName)); // FILE HAS BEEN
FORCE-DOWNLOADED AND IS NO LONGER NEEDED ON SERVER
@unlink(actual_ path($reportFil eName)); // REMOVE THE
TEMPORARY FILE AS WELL, PROVIDED IT EXISTS AND/OR YOU CAN
if ($this->isSuccessful ) exit();
[/PHP]
The force-downloaded file you get is completely flooded with HTML,
particularly the HTML of the page itself! I do not understand how this
is possible, particularly since I ran careful traces up until the
headers are spawned, and the resulting file contents are legitimate
report data (no HTML) up until you generate the headers at the end of
the method, then suddenly HTML pours in like a breached levee!
Any ideas? This is as much code as I am able to display that would be
relevant to the problem, I'm afraid.
Thanx
Phil
class ReportGenerator {
function ReportGenerator () {}
/**
* Generate the HTTP headers necessary for this file type. Can be
called statically
*
* @access public
* @param mixed $filename
* @see file_get_conten ts
* @see actual_path
*/
function &generateHTTPHe aders($filename ) { // STATIC VOID METHOD
if (!preg_match('/.+\.[a-zA-Z0-9\-_]+$/i', $filename)) die("Filename:
\"$filename\ " must have an extension");
$ext = substr($filenam e, strrpos($filena me, '.') + 1,
strlen($filenam e));
switch (strtolower(tri m($ext))) {
case 'pdf':
$ctype = 'application/pdf';
break;
case 'exe':
$ctype = 'application/octet-stream';
break;
case 'zip':
$ctype = 'appliation/zip';
break;
case 'doc':
$ctype = 'application/msword';
break;
case 'xls':
$ctype = 'application/vnd.ms-excel';
break;
case 'csv':
$ctype = 'application/vnd.ms-excel';
break;
case 'ppt':
$ctype = 'application/vnd.ms-powerpoint';
break;
case 'gif':
$ctype = 'image/gif';
break;
case 'png':
$ctype = 'image/png';
break;
case 'jpg':
$ctype = 'image/jpg';
break;
case 'jpeg':
$ctype = 'image/jpg';
break;
default:
$ctype = 'application/force-download';
break;
}
header('Pragma: public');
header('Expires : 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header("Content-Type: $ctype");
$user_agent = strtolower($_SE RVER['HTTP_USER_AGEN T']);
if ((is_integer(st rpos($user_agen t, 'msie'))) &&
(is_integer(str pos($user_agent , 'win')))) {
header('Content-Disposition: filename=' .
basename(actual _path($filename )) . ';');
} else {
header('Content-Disposition: inline; filename=' .
basename(actual _path($filename )) . ';');
}
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . @filesize(actua l_path($filenam e)));
if (function_exist s('file_get_con tents')) {
echo @file_get_conte nts(actual_path ($filename));
} else {
@readfile(actua l_path($filenam e));
}
}
}
[/PHP]
The class method generateHTTPHea ders() can be called statically to
force-download a file (Excel, CSV, PDF, etc.) per customer requirement.
However, upon attempting to do so:
[PHP]
// REAL IMPORTANT!!! CHMOD OR THE WORLD CAN SEE YOUR REPORTS!!!!!!!
if ($this->isSuccessful ) @chmod(0770,
actual_path($ne wReportFileName )); // CHANGE PERMISSIONS (IF IN UNIX)
TO PREVENT WORLD FROM ACCESSING FILE
if ($this->isSuccessful )
ReportGenerator ::generateHTTPH eaders($newRepo rtFileName); // THIS
CAUSES THE FORCED DOWNLOAD
@unlink(actual_ path($newReport FileName)); // FILE HAS BEEN
FORCE-DOWNLOADED AND IS NO LONGER NEEDED ON SERVER
@unlink(actual_ path($reportFil eName)); // REMOVE THE
TEMPORARY FILE AS WELL, PROVIDED IT EXISTS AND/OR YOU CAN
if ($this->isSuccessful ) exit();
[/PHP]
The force-downloaded file you get is completely flooded with HTML,
particularly the HTML of the page itself! I do not understand how this
is possible, particularly since I ran careful traces up until the
headers are spawned, and the resulting file contents are legitimate
report data (no HTML) up until you generate the headers at the end of
the method, then suddenly HTML pours in like a breached levee!
Any ideas? This is as much code as I am able to display that would be
relevant to the problem, I'm afraid.
Thanx
Phil
Comment