MIMEtype array and MS Project file download


#1

I have a php document manager that enable me to upload and download file. Everything functions file except for Microsoft Project files with the file extension .mpp. The download attempt returns “Error opening file or invalid filename.”

Do anybody know of a reason why an map file will not download?

There are many MIMEtypes in the array so I won’t list them all, just the one I am having issues with.

[php]
$MIMEtypes = array(
“application/vnd.ms-project” => “mpp”,
);[/php]

Thanks for any help you can provide…


#2

Well, show some download code… But, a logical guess is that you are not downloading by code, but, simply posting the file name for the user to click on for download with a … If so, the problem is that the browser is using Windows to OPEN the file as it is supposed to. Downloading files in Windows makes the browser open the corresponding plugin for the filetype. As an example, if you find a PDF file online, and click on it, it opens the Adobe Acrobat Reader. (Current version loaded on the user’s system not the one on mine or yours!) So, if you are using a MS .MPP file, the user would have to have that app installed on their system. It should attempt to open it.
Try this… Go to the same page you are attempting to download the file and RIGHT-CLICK on it and select the option SAVE-TARGET-AS and see if you can download it. Some filetypes must be saved this way. Or, you can program a button to start the download as a SAVE-TARGET-AS instead of using the browser’s default setting. Hope that made sense. Good luck…


#3

Please keep in mind that .mpp files are the only file types that are not functioning properly. The programming works for all the other file types I have in my array. (.xls, ppt, pdf etc.) File types are added to a config.php file.

So with that in mind here is my code.

download.php

[php]<?php
if (!@ include_once ("./inc/auth.php"))
include_once ("…/inc/auth.php");
if (isset ($_GET[‘filename’]))
$filename = stripslashes($_GET[‘filename’]);
if ($AllowDownload) {
print “<table align=“center” class=“menu” cellpadding=“2” cellspacing=“0”>”;
print “\n\t

”;
if ($AllowAdmin)
print “\n\t\t<td style=“padding: 0 4px 0 4px;”><a href=”$base_url&path=" . htmlentities(rawurlencode($path)) . “&action=admin” class=“fade”><img class=“absmiddle” src=“gfx/nav_admin_panel.png” width=“140” height=“32” alt="$StrMenuAdmin" border=“0”>  “;
print “<td style=“padding: 0 4px 0 4px;”><a href=”$base_url&path=” . htmlentities(rawurlencode($path)) . “” class=“fade”><img class=“absmiddle” src=“gfx/nav_file_browser.png” width=“140” height=“32” alt="$StrUserDir" border=“0”>  “;
if ($AllowCreate)
print “\n\t\t<td style=“padding: 0 4px 0 4px;”><a href=”$base_url&path=” . htmlentities(rawurlencode($path)) . “&action=create&type=directory” class=“fade”><img class=“absmiddle” src=“gfx/nav_new_folder.png” width=“140” height=“32” alt="$StrMenuCreateFolder" border=“0”>  “;
if ($AllowCreate)
print “\n\t\t<td style=“padding: 0 4px 0 4px;”><a href=”$base_url&path=” . htmlentities(rawurlencode($path)) . “&action=create&type=file” class=“fade”><img class=“absmiddle” src=“gfx/nav_new_file.png” width=“120” height=“32” alt="$StrMenuCreateFile" border=“0”>  “;
if ($AllowUpload)
print “\n\t\t<td style=“padding: 0 4px 0 4px;”><a href=”$base_url&path=” . htmlentities(rawurlencode($path)) . “&action=upload” class=“fade”><img class=“absmiddle” src=“gfx/nav_upload_files.png” width=“140” height=“32” alt="$StrMenuUploadFiles" border=“0”>  “;
print “\n\t\t<td style=“padding: 0 4px 0 4px;”><a href=”$_SERVER[PATH_TRANSLATED]” class=“fade”><img class=“absmiddle” src=“gfx/nav_refresh_page.png” width=103 height=32 alt="$StrMenuRefreshPage" border=“0”>  “;
print “\n\t\t<td style=“padding: 0 4px 0 4px;”><a href=”$base_url&action=logout” class=“fade”><img class=“absmiddle” src=“gfx/nav_log_out.png” width=“106” height=“32” alt="$StrMenuLogOut" border=“0”>  “;
print “\n\t”;
print “\n
\n\n”;
print “<table align=“center” class=“cap”>”;
print “\n\t”;
print “\n\t\t<td class=“capLeft” align=“left”>”;
print “\n\t\t<td align=“center” style=“vertical-align: bottom;”>”;
print “<font class=“statusWrap”><font class=“status”> $StrDownload “” . htmlentities($filename) . “” “;
print “\n\t\t<td class=“capRight” align=“right”>”;
print “\n\t”;
print “\n”;
print “\n<table align=“center” class=“container”><td align=“center” class=“container”>”;
print “\n\t<table align=“center” class=“content”><td valign=“top”>”;
print “<div align=“center” style=“margin-bottom: 40px;”>
<img src=“gfx/download.gif” width=“25” height=“24” alt=”$StrDownloadFile” border=“0”>

”;
print “<div style=“font-weight: normal”>$StrDownloadClickLink

”;
print “<a href=“inc/libfile.php?path=” . htmlentities(rawurlencode($path)) . “&filename=” . htmlentities(rawurlencode($filename)) . “&action=download”>”;
print “” . htmlentities($path . $filename);
print “

”;
print “<div style=“margin-top: 40px;”><a href=”$base_url&path=” . htmlentities(rawurlencode($path)) . “”><img class=“absmiddle” src=“gfx/button_cancel.png” alt="$StrCancel" width=“122” height=“27” border=“0”>";
print "    “;
print “<a href=“inc/libfile.php?path=” . htmlentities(rawurlencode($path)) . “&filename=” . htmlentities(rawurlencode($filename)) . “&action=download”><img class=“absmiddle” src=“gfx/button_download.png” alt=”$StrYes” width=“145” height=“27” border=“0”>";
print “”;
print “\n\t”;
print “\n\n\n”;
}
else
print “<div class=“msg_alert”><img class=“absmiddle” src=“gfx/icon_alert.png” width=“36” height=“32” alt=”$StrUserAlert" border=“0”>    $StrAccessDenied";
?>[/php]

libfile.php

[php]<?php
if (!@ include_once ("./inc/auth.php"))
include_once ("…/inc/auth.php");
include ("…/config.php");
include ("…/inc/functions.php");
include ("…/lang/$language.php");
session_save_path($session_save_dir);
if (isset ($_GET[‘path’]) && $_GET[‘path’] != ‘’)
$path = validate_path($_GET[‘path’]);
if (!isset ($path))
$path = FALSE;
if ($path == “./” || $path == “.\” || $path == “/” || $path == “\”)
$path = FALSE;
if (isset ($_GET[‘filename’]))
$filename = basename(stripslashes($_GET[‘filename’]));
if ($AllowDownload || $AllowView) {
if (empty ($home_directory)) {
if (!empty ($_SESSION[‘home_directory’]))
$home_directory = $_SESSION[‘home_directory’];
}
if (isset ($_GET[‘filename’]) && isset ($_GET[‘action’]) && is_file($home_directory . $path . $filename) || is_file("…/" . $home_directory . $path . $filename)) {
if (is_file($home_directory . $path . $filename) && !strstr($home_directory, “./”) && !strstr($home_directory, “.\”))
$fullpath = $home_directory . $path . $filename;
else
if (is_file("…/" . $home_directory . $path . $filename))
$fullpath = “…/” . $home_directory . $path . $filename;
if (!$AllowDownload && $AllowView && !is_viewable_file($filename)) {
print “$StrAccessDenied”;
exit ();
}
if ($HTTPS)
header(“Pragma:”);
header(“Content-Type: " . get_mimetype($filename));
header(“Content-Length: " . filesize($fullpath));
if ($_GET[‘action’] == “download”)
;
//header(“Content-Disposition: attachment; filename=$filename”);
header(“Content-Disposition: attachment; filename=””.$filename.”";" );
readfile($fullpath);
}
else
print “$StrDownloadFail”;
}
?>[/php]

functions.php
This file does a number of different functions. I have only posted code that may be relevant to the issue.

[php]function is_valid_name($input)

Checks whether the directory- or filename is valid

{
if (strstr($input, "\\"))
	return FALSE;
else
	if (strstr($input, "/"))
		return FALSE;
	else
		if (strstr($input, ":"))
			return FALSE;
		else
			if (strstr($input, "?"))
				return FALSE;
			else
				if (strstr($input, "*"))
					return FALSE;
				else
					if (strstr($input, "\""))
						return FALSE;
					else
						if (strstr($input, "<"))
							return FALSE;
						else
							if (strstr($input, ">"))
								return FALSE;
							else
								if (strstr($input, "|"))
									return FALSE;
								else
									return TRUE;

}
function get_current_zoom_level($current_zoom_level, $zoom)

Get current zoom level

{
global $ZoomArray;
reset($ZoomArray);
while (list($number, $zoom_level) = each($ZoomArray))
if ($zoom_level == $current_zoom_level)
	if (($number + $zoom) < 0)
		return $number;
	else
		if (($number + $zoom) >= count($ZoomArray))
			return $number;
		else
			return $number + $zoom;

}
function validate_path($path)

Validate path

{
global $StrAccessDenied;
if (stristr($path, "../") || stristr($path, "..\\"))
	return TRUE;
else
	return stripslashes($path);

}
function get_mimetype($filename)

Get MIME-type for file

{
global $MIMEtypes;
reset($MIMEtypes);
$extension = strtolower(substr(strrchr($filename, "."), 1));
if ($extension == "")
	return "Unknown/Unknown";
while (list($mimetype, $file_extensions) = each($MIMEtypes))
foreach (explode(" ", $file_extensions) as $file_extension)
	if ($extension == $file_extension)
		return $mimetype;
	return "Unknown/Unknown";

}
function get_linked_path($path, $base_url)

Get path with links to each folder

{
$string = "&nbsp;&laquo;&nbsp;&nbsp;<a href=\"$base_url\">Home</a>&nbsp;&nbsp;&raquo;&nbsp;";
$array = explode("/", htmlentities($path));
unset ($array [count($array) - 1]);
foreach ($array as $entry) {
	@ $temppath .= $entry . "/";
	$string .= "<a href='$base_url&amp;path=" . htmlentities(rawurlencode($temppath)) . "'>$entry</a> &raquo;&nbsp;";
}
return $string;

}[/php]


#4

Sorry, I didn’t know how you were downloading the files… Since you are using PHP headers to force downloading, that was what I needed to know.

I could not see anything wrong with your code. Normal header downloads are in this format:
header(“Cache-Control: public”);
header(“Content-Description: File Transfer”);
header(“Content-Disposition: attachment; filename=$file”);
header(“Content-Type: application/zip”);
header(“Content-Transfer-Encoding: binary”);
// Read the file from disk
readfile($filepath);
This will force ANY file to download in “binary” format and treating all files as a zipped file, so no special encoding checking is done. As far as I can see your code is in this format:
if ($HTTPS)
header(“Pragma:”);
header(“Content-Type: " . get_mimetype($filename));
header(“Content-Length: " . filesize($fullpath));
if ($_GET[‘action’] == “download”)
;
header(“Content-Disposition: attachment; filename=””.$filename.”";" );
readfile($fullpath);
Sooo, I don’t think my sample’s description line is important, same as your size line. Doubt either is needed for the download. I think the transfer-encoding defaults to binary. So, I think the issue is the Content-Type header. If you force a certain type, it may be checking for that type and sending it in a different way. Here is a quote from a site I was reading about these headers:

The critical ones here are the File Transfer, attachment, and application/zip definitions. The "Content-Description: File Transfer" will help force a download for the user. By defining a "Content-Disposition: attachment" in the next line, we tell the browser that we are indeed going to link to a file. The next line, "Content-Type", tells the browser what type of application association we want the browser to reference.
They hinted that you can force the download by assigning it as a zipped/executable attachment. So, perhaps forcing all of your downloads this way may fix it. Worth a try... Also, I do not know what this line does: if ($_GET['action'] == "download") ; A mistype? Not sure if this all helps, but, good luck...

#5

I am such an idiot. Why didn’t I think of this first… :-[

The issue was in the file name. There was an “&” in the name of the file that was uploaded and the downloader did not like that.

Thank you for your time.


#6

glad you found it… Sometimes just talking about it will make you look harder…

CYA in the bitstream…