I have a website that is set up like this:
client request --> gate.php --> requested file
Every request the client sends goes to gate.php were it is parsed. Gate.php then includes the requested file from a restricted directory so that the client cannot access any file but gate.php.
Gate file:
<?php
$_uri = strtok($_SERVER["REQUEST_URI"],'?');
$_root = "<root>";
// Index //
switch($_uri) {
case "/": $_uri = "<path>"; break;
case "/css": $_uri = "<path>"; break;
case "/js": $_uri = "<path>"; break;
case "/font": $_uri = "<path>".strtok($_GET["p"],".")."/".$_GET["p"]; break;
case "/ajax": $_uri = "<path>"; break;
case "/signin": $_uri = "<path>"; break;
case "/signup": $_uri = "<path>"; break;
default:
if(substr($_uri,0,8) == "/profile") { // profile
$_uri = "<path>";
$_page = substr($_uri,9);
} else {
header("HTTP/1.1 404");
require_once($_root."<path>");
die();
}
}
!isset($_page) and isset($_GET["p"]) ? $_page = $_GET["p"] : 0;
// Mime //
$_path = explode(".",$_uri);
switch($_path[1]) {
case "php": $_path[2] = "text/html"; break;
case "css": $_path[2] = "text/css"; break;
case "js": $_path[2] = "application/javascript"; break;
case "xml": $_path[2] = "application/xml"; break;
case "svg": $_path[2] = "application/xml+svg"; break;
case "jpg": $_path[2] = "image/jpeg"; break;
case "png": $_path[2] = "image/png"; break;
case "otf": $_path[2] = "x-font/otf"; break;
case "eot": $_path[2] = "x-font/eot"; break;
case "ttf": $_path[2] = "x-font/ttf"; break;
case "woff": $_path[2] = "x-font/woff"; break;
default:
header("HTTP/1.1 500");
require_once($_root."<path>");
die();
}
$_path[2] == "text/html" ? require_once($_root."<path>") : 0;
// File //
header("Content-Type: ".$_path[2]);
require_once($_root."/sys".$_uri);
?>
The problem is, when I pass a font file through the gate, the font file contains the text <? which PHP parses and returns an error.
Is there any way to escape the font file so that PHP does not parse it?
You can only require files that can be interpreted by PHP. If you want to serve other kinds of files through your script, you have to output them by reading them.
Something like:
$file = 'myfontfile.ttf';
if (file_exists($file)) {
header('Content-Type: application/octet-stream');
header('Content-Disposition: inline; filename="'.basename($file).'"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
Related
I have this script:
<?php
$id = $_GET["id"];
switch($id)
{
default: echo "Bad ID!"; exit;
case "MyPicture1": $file = "img/img1.jpg"; break;
case "MyPicture2": $file = "img/img2.jpg"; break;
case "MyPicture3": $file = "img/img3.jpg"; break;
case "MyPicture4": $file = "img/img4.jpg"; break;
}
if(file_exists($file))
{
$size = getimagesize($file);
$fp = fopen($file, 'rb');
if($size and $fp)
{
header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($file)).' GMT');
header('Content-Type: '.$size['mime']);
header('Content-Length: '.filesize($file));
fpassthru($fp);
}
exit;
}
else
{
echo "Bad ID!";
}
?>
Which works fine for loading images like this <IMG Src="/Script.php?id=MyPicture1" />!
But the problem occurs when I try to load ANY other MIME content, to be displayed directly on the page or to switch page with it, but unsuccessfully... I tried with:
<?php
$file_name = $_GET["id"];
switch($file_name)
{
default: echo 'Bad ID!'; exit;
case "style1": $file_name = "csss/style_one.css"; break;
case "style2": $file_name = "csss/style_two.css"; break;
case "image1": $file_name = "images/image_one.jpg"; break;
case "image2": $file_name = "images/image_one.png"; break;
case "image3": $file_name = "images/image_one.bmp"; break;
case "image4": $file_name = "images/image_one.gif"; break;
case "video1": $file_name = "videos/video_one.avi"; break;
case "video2": $file_name = "videos/video_two.mp4"; break;
case "video3": $file_name = "videos/video_three.mov"; break;
case "php_page_1": $file_name = "php_pages/php_one.php"; break;
case "html_page_1": $file_name = "html_pages/html_one.html"; break;
case "icon_fav_1": $file_name = "icons/icon_one.ico"; break;
case "font_1": $file_name = "fonts/font_one.otf"; break;
}
if(file_exists($file_name))
{
$size = getImageSize("$file_name");
$fP = fOpen("$file_name", "rb");
if($size and $fP)
{
header('last-modified: '.gmdate('D, d M Y H:i:s', filemtime($file_name)).' GMT');
header('content-type: '.$size['mime'].');
header('content-length: '.filesize($file_name).);
fPassThru($fP);
}
exit;
}
else
{
echo 'Bad ID!';
}
?>
If I load CSS sheet like /Script.php?id=MyCSS1, I want CSS file to be loaded properly on the page - that is I want CSS file to be loaded on the page as if it was loaded with <LINK rel="stylesheet" type="text/css" href="css/styles_one.css" />. The same applies to ANY and ALL other MIME content, including switching pages with ANY extension with it - like /Script.php?id=php_page_1 (if php page 1 is clicked).
Can you help?
You can use the php function mime_content_type. Here is an example with some syntactic sugar.
<?php
$file_name = $_GET["id"];
switch($file_name)
{
default: echo 'Bad ID!'; exit;
case "style1": $file_name = "csss/style_one.css"; break;
case "style2": $file_name = "csss/style_two.css"; break;
case "image1": $file_name = "images/image_one.jpg"; break;
case "image2": $file_name = "images/image_one.png"; break;
case "image3": $file_name = "images/image_one.bmp"; break;
case "image4": $file_name = "images/image_one.gif"; break;
case "video1": $file_name = "videos/video_one.avi"; break;
case "video2": $file_name = "videos/video_two.mp4"; break;
case "video3": $file_name = "videos/video_three.mov"; break;
case "php_page_1": $file_name = "php_pages/php_one.php"; break;
case "html_page_1": $file_name = "html_pages/html_one.html"; break;
case "icon_fav_1": $file_name = "icons/icon_one.ico"; break;
case "font_1": $file_name = "fonts/font_one.otf"; break;
}
if(file_exists($file_name)) {
header("last-modified: {gmdate('D, d M Y H:i:s', filemtime($file_name))} GMT");
header("content-type: {mime_content_type($file_name)}");
header("content-length: {filesize($file_name)}");
readfile($file_name);
} else {
echo 'Bad ID!';
}
exit;
If you are using php 8. You will have to write it like this.
<?php
$file_name = $_GET["id"];
switch($file_name)
{
default: echo 'Bad ID!'; exit;
case "style1": $file_name = "csss/style_one.css"; break;
case "style2": $file_name = "csss/style_two.css"; break;
case "image1": $file_name = "images/image_one.jpg"; break;
case "image2": $file_name = "images/image_one.png"; break;
case "image3": $file_name = "images/image_one.bmp"; break;
case "image4": $file_name = "images/image_one.gif"; break;
case "video1": $file_name = "videos/video_one.avi"; break;
case "video2": $file_name = "videos/video_two.mp4"; break;
case "video3": $file_name = "videos/video_three.mov"; break;
case "php_page_1": $file_name = "php_pages/php_one.php"; break;
case "html_page_1": $file_name = "html_pages/html_one.html"; break;
case "icon_fav_1": $file_name = "icons/icon_one.ico"; break;
case "font_1": $file_name = "fonts/font_one.otf"; break;
}
if(file_exists($file_name)) {
$last_modified = gmdate('D, d M Y H:i:s', filemtime($file_name));
header("last-modified: $last_modified GMT");
$content_type = mime_content_type($file_name);
header("content-type: $content_type");
$content_length = filesize($file_name);
header("content-length: $content_length");
readfile($file_name);
} else {
echo 'Bad ID!';
}
exit;
getImageSize() is just for image files. The more general function for getting MIME types is mime_content_type().
if(file_exists($file_name))
{
$type = mime_content_type("$file_name");
$fP = fOpen("$file_name", "rb");
if($type and $fP)
{
header('last-modified: '.gmdate('D, d M Y H:i:s', filemtime($file_name)).' GMT');
header('content-type: '.$type.');
header('content-length: '.filesize($file_name).);
fPassThru($fP);
}
exit;
}
else
{
echo 'Bad ID!';
}
I have a php code for downloading file based on file_id from URL. All works great, but I have problems with downloading files with extension .doc
Here is my code, what im doing wrong?
$file = mysql_fetch_array(mysql_query("SELECT * FROM ".sqlprefix."files WHERE id = '".$_GET['id']."'"));
$tmp = explode(".",$file['url']);
$tmp = $tmp[count($tmp)-1];
// $tmp = "doc";
switch ($tmp) {
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "docx": $ctype="application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break;
case "doc": $ctype="application/msword"; break;
case "csv":
case "xls":
case "xlsx": $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 "jpeg":
case "jpg": $ctype="image/jpg"; break;
case "tif":
case "tiff": $ctype="image/tiff"; break;
case "psd": $ctype="image/psd"; break;
case "bmp": $ctype="image/bmp"; break;
case "ico": $ctype="image/vnd.microsoft.icon"; break;
default: $ctype="application/force-download";
}
$baseName = basename($file['url_del']);
$fileSize = filesize($file['url_del']);
$url = $file['url_del'];
// $ctype = "application/msword";
// $baseName = "File name with spaces and diacritic ěščěšč.doc"
// $fileSize = "214016"
// $url = "./files/File name with spaces and diacritic ěščěšč.doc";
header('Content-Description: File Transfer');
header('Content-Type: '.$ctype);
header('Content-Disposition: attachment; filename='.$baseName);
header('Expires: 0');
header('Pragma: public');
header('Content-Length: '.$fileSize);
readfile($url);
exit;
After downloading file in word I get this.
I think, that problem must be in encoding... enter image description here
It was terrible for me too.
I have found the slution here: PHP readfile() causing corrupt file downloads
Try to put this lines before readfile():
//clean all levels of output buffering
while (ob_get_level()) {
ob_end_clean();
}
I have a php code for downloading file based on file_id from URL. All works great, but i have problems with downloading files with extension .doc
Here is my code, what im doing wrong?
$file = mysql_fetch_array(mysql_query("SELECT * FROM ".sqlprefix."files WHERE id = '".$_GET['id']."'"));
$tmp = explode(".",$file['url']);
$tmp = $tmp[count($tmp)-1];
// $tmp = "doc";
switch ($tmp) {
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "docx": $ctype="application/vnd.openxmlformats-officedocument.wordprocessingml.document"; break;
case "doc": $ctype="application/msword"; break;
case "csv":
case "xls":
case "xlsx": $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 "jpeg":
case "jpg": $ctype="image/jpg"; break;
case "tif":
case "tiff": $ctype="image/tiff"; break;
case "psd": $ctype="image/psd"; break;
case "bmp": $ctype="image/bmp"; break;
case "ico": $ctype="image/vnd.microsoft.icon"; break;
default: $ctype="application/force-download";
}
$baseName = basename($file['url_del']);
$fileSize = filesize($file['url_del']);
$url = $file['url_del'];
// $ctype = "application/msword";
// $baseName = "File name with spaces and diacritic ěščěšč.doc"
// $fileSize = "214016"
// $url = "./files/File name with spaces and diacritic ěščěšč.doc";
header('Content-Description: File Transfer');
header('Content-Type: '.$ctype);
header('Content-Disposition: attachment; filename='.$baseName);
header('Expires: 0');
header('Pragma: public');
header('Content-Length: '.$fileSize);
readfile($url);
exit;
After downloading file in word i get this. I think, that problem must be in encoding...
I'm downloading mp4,mp3 etc.. files from my server with php. But browsers are not showing the size of file.
I searched everywhere but i couldn't find any working answer. Hope you can help me. Thanks in advance.
Here is the code :
function force_download($file)
{
$ext = explode(".", $file);
switch($ext[sizeof($ext)-1])
{
case 'jar': $mime = "application/java-archive"; break;
case 'zip': $mime = "application/zip"; break;
case 'jpeg': $mime = "image/jpeg"; break;
case 'jpg': $mime = "image/jpg"; break;
case 'jad': $mime = "text/vnd.sun.j2me.app-descriptor"; break;
case "gif": $mime = "image/gif"; break;
case "png": $mime = "image/png"; break;
case "pdf": $mime = "application/pdf"; break;
case "txt": $mime = "text/plain"; break;
case "doc": $mime = "application/msword"; break;
case "ppt": $mime = "application/vnd.ms-powerpoint"; break;
case "wbmp": $mime = "image/vnd.wap.wbmp"; break;
case "wmlc": $mime = "application/vnd.wap.wmlc"; break;
case "mp4s": $mime = "application/mp4"; break;
case "ogg": $mime = "application/ogg"; break;
case "pls": $mime = "application/pls+xml"; break;
case "asf": $mime = "application/vnd.ms-asf"; break;
case "swf": $mime = "application/x-shockwave-flash"; break;
case "mp4": $mime = "video/mp4"; break;
case "m4a": $mime = "audio/mp4"; break;
case "m4p": $mime = "audio/mp4"; break;
case "mp4a": $mime = "audio/mp4"; break;
case "mp3": $mime = "audio/mpeg"; break;
case "m3a": $mime = "audio/mpeg"; break;
case "m2a": $mime = "audio/mpeg"; break;
case "mp2a": $mime = "audio/mpeg"; break;
case "mp2": $mime = "audio/mpeg"; break;
case "mpga": $mime = "audio/mpeg"; break;
case "wav": $mime = "audio/wav"; break;
case "m3u": $mime = "audio/x-mpegurl"; break;
case "bmp": $mime = "image/bmp"; break;
case "ico": $mime = "image/x-icon"; break;
case "3gp": $mime = "video/3gpp"; break;
case "3g2": $mime = "video/3gpp2"; break;
case "mp4v": $mime = "video/mp4"; break;
case "mpg4": $mime = "video/mp4"; break;
case "m2v": $mime = "video/mpeg"; break;
case "m1v": $mime = "video/mpeg"; break;
case "mpe": $mime = "video/mpeg"; break;
case "mpeg": $mime = "video/mpeg"; break;
case "mpg": $mime = "video/mpeg"; break;
case "mov": $mime = "video/quicktime"; break;
case "qt": $mime = "video/quicktime"; break;
case "avi": $mime = "video/x-msvideo"; break;
case "midi": $mime = "audio/midi"; break;
case "mid": $mime = "audio/mid"; break;
case "amr": $mime = "audio/amr"; break;
default: $mime = "application/force-download";
}
header('Content-Description: File Transfer');
header('Content-Type: '.$mime);
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '. filesize($file));
ob_clean();
flush();
readfile($file);
}
if (isset($_POST['downl'])){
$file = "http://localhost/project1/downloads/gmf.mp4";
force_download($file);
}
<form method="POST" action=''>
<?php echo'<input type="submit" name="downl" value="Download Baby" >' ; ?>
</form>
If i try to show file size with echo filesize($file) it gives this error :
Warning: filesize(): stat failed for http://localhost/project1/downloads...
Since php 5.0.0 the file command supports http wrappers but the http wrapper does not support stat commands like size. So you cannot get the file size in your case with size.
I'm have using Php, MongoDb and GridFs to store and retrieve files. It works fine for images, but I want to store files with docx, pdf, csv and etc. extensions. Here is my code:
$ext = $this->getFileExt($_FILES["news_attachment"]["name"]);
switch ($ext) {
case 'pdf':
$mimeType = 'application/pdf';
break;
case 'doc':
$mimeType = 'application/msword';
break;
case 'docx':
$mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
break;
case 'xls':
$mimeType = 'application/vnd.ms-excel';
break;
case 'xlsx':
$mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
case 'ppt':
$mimeType = 'application/x-mspowerpoint';
break;
case 'pptx':
$mimeType = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
break;
case 'csv':
$mimeType = 'text/csv';
break;
case 'txt':
$mimeType = 'text/plain';
break;
default:
$mimeType='application/pdf';
}
$gridFs = $this->getGridFs();
$fileData = array(
"filename" => microtime(true) . "." . $ext,
"contentType" => $mimeType);
$_id = $gridFs->storeUpload("news_attachment", $fileData);
But I get the same error message Message: error setting up file: . I've checked the file size is 78kb, $fileData is ok also. So, my question is - What else can caused this error?
Would you not be supplying the same argument when trying to upload:
$gridFs->storeUpload($_FILES["news_attachment"]["name"],
or possibly
$gridFs->storeUpload($_FILES["news_attachment"]["tmp_name"],
I just need to add check for error if(!empty($_FILES["news_attachment"]) && $_FILES["news_attachment"]["error"] == 0){ save file}