how to hide the actual download folder location
This is how I do it in PHP:
<?php
$fakeFileName= "fakeFileName.zip";
$realFileName = "realFileName.zip";
$file = "downloadFolder/".$realFileName;
$fp = fopen($file, 'rb');
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$fakeFileName");
header("Content-Length: " . filesize($file));
fpassthru($fp);
?>
Additionally, if you don't want anyone to have access to the file location, put a file named .htaccess
into your download folder with only the contents:
deny from all
I changed the code a little. First when I say fake file name and real file name, the fake filename is the name that the downloader will download the file as, where the real filename is the name of the actual file in the download folder on your server.
Also, I check to make sure the user is logged in and is able to download the file. If he chooses to download the file, a PHP file is called in a new tab (with the download code from above), then at the end of the file I have the line:
exit;
So when he clicks on the download link, a blank page pops up in a new tab quickly, then quickly exits and the download begins.
EDIT: The download link looks something like this:
<a href="simpleDown.php?id=<?php echo $_GET['id']; ?>" target="_blank">Download!</a>
Where id
is the id
of the download in the database, and in the download script from above I find the entry with that id
, then get its real file name and the fake file name. You can do this without the database though.
How to hide the source of a download on a webpage
Sorry not possible. You HAVE to tell the browser where the resource is located so any savy user can simply decode the address or scan the HTTP request or their firewall logs or download history in the browser.
If you're trying to hide the path on your server then URL rewriting with mod_rewrite or aliases or other similar method should be sufficient.
UPDATE: Ok if using your own bandwidth is not an issue then all you need to be doing is outputting the files binary content to the browser and setting the relevant HTTP headers (ie, Content-Type and Content-Disposition). If the files MUST be stored remotely then you'll need your script to download and read them on-the-fly using CURL or similar before outputting the content.
Hiding the physical path of a file downloading in ASP.NET
Here is the best approach:
public static bool DownloadFile(HttpContext httpContext, string filePath, long speed)
{
// Many changes: mostly declare variables near use
// Extracted duplicate references to HttpContext.Response and .Request
// also duplicate reference to .HttpMethod
// Removed try/catch blocks which hid any problems
var response = httpContext.Response;
var request = httpContext.Request;
var method = request.HttpMethod.ToUpper();
if (method != "GET" &&
method != "HEAD")
{
response.StatusCode = 501;
return false;
}
if (!File.Exists(filePath))
{
response.StatusCode = 404;
return false;
}
// Stream implements IDisposable so should be in a using block
using (var myFile = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
var fileLength = myFile.Length;
if (fileLength > Int32.MaxValue)
{
response.StatusCode = 413;
return false;
}
var lastUpdateTiemStr = File.GetLastWriteTimeUtc(filePath).ToString("r");
var fileName = Path.GetFileName(filePath);
var fileNameUrlEncoded = HttpUtility.UrlEncode(fileName, Encoding.UTF8);
var eTag = fileNameUrlEncoded + lastUpdateTiemStr;
var ifRange = request.Headers["If-Range"];
if (ifRange != null && ifRange.Replace("\"", "") != eTag)
{
response.StatusCode = 412;
return false;
}
long startBytes = 0;
// Just guessing, but I bet you want startBytes calculated before
// using to calculate content-length
var rangeHeader = request.Headers["Range"];
if (rangeHeader != null)
{
response.StatusCode = 206;
var range = rangeHeader.Split(new[] { '=', '-' });
startBytes = Convert.ToInt64(range[1]);
if (startBytes < 0 || startBytes >= fileLength)
{
// TODO: Find correct status code
response.StatusCode = (int)HttpStatusCode.BadRequest;
response.StatusDescription =
string.Format("Invalid start of range: {0}", startBytes);
return false;
}
}
response.Clear();
response.Buffer = false;
response.AddHeader("Content-MD5", GetMD5Hash(filePath));
response.AddHeader("Accept-Ranges", "bytes");
response.AppendHeader("ETag", string.Format("\"{0}\"", eTag));
response.AppendHeader("Last-Modified", lastUpdateTiemStr);
response.ContentType = "application/octet-stream";
response.AddHeader("Content-Disposition", "attachment;filename=" +
fileNameUrlEncoded.Replace("+", "%20").Replace(",",";"));
var remaining = fileLength - startBytes;
response.AddHeader("Content-Length", remaining.ToString());
response.AddHeader("Connection", "Keep-Alive");
response.ContentEncoding = Encoding.UTF8;
if (startBytes > 0)
{
response.AddHeader("Content-Range",
string.Format(" bytes {0}-{1}/{2}", startBytes, fileLength - 1, fileLength));
}
// BinaryReader implements IDisposable so should be in a using block
using (var br = new BinaryReader(myFile))
{
br.BaseStream.Seek(startBytes, SeekOrigin.Begin);
const int packSize = 1024 * 10; //read in block,every block 10K bytes
var maxCount = (int)Math.Ceiling((remaining + 0.0) / packSize); //download in block
for (var i = 0; i < maxCount && response.IsClientConnected; i++)
{
response.BinaryWrite(br.ReadBytes(packSize));
response.Flush();
// HACK: Unexplained sleep
var sleep = (int)Math.Ceiling(1000.0 * packSize / speed); //the number of millisecond
if (sleep > 1)
Thread.Sleep(sleep);
}
}
}
return true;
}
static string GetMD5Hash(string input)
{
// Create a new instance of the MD5CryptoServiceProvider object.
MD5 md5Hasher = MD5.Create();
// Convert the input string to a byte array and compute the hash.
byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
// Create a new Stringbuilder to collect the bytes
// and create a string.
StringBuilder sBuilder = new StringBuilder();
// Loop through each byte of the hashed data
// and format each one as a hexadecimal string.
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
// Return the hexadecimal string.
return sBuilder.ToString();
}
hide a folder path when user downloads a file
Example With PDF doc
$nameOld = "/public_html/wp-content/example.folder/oldnme.pdf";
$nameNew = "newName.pdf" ;
header("Content-Transfer-Encoding: binary");
header('Content-type: application/pdf');
header("Content-disposition: attachment; filename=$nameNew"); //
readfile($nameOld);
Edit
Prove of Concept for your image system using download.php?img=flower
without the extension and flower
show be the image name
$directory = "/public_html/wp-content/example.folder/";
$types = array("jpg","gif","png");
$ext = null;
if (! isset($_GET['img'])) {
die("Invalid URL");
}
$nameOld = filter_var($_GET['img'], FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW);
$nameNew = uniqid(basename($nameOld));
// File the file
foreach ( $types as $type ) {
if (is_file($nameOld . "." . $type)) {
$ext = $type;
break;
}
}
if ($ext == null) {
die("Sorry Image Not Found");
}
$nameOld .= "." . $ext;
$type = image_type_to_mime_type(exif_imagetype($nameOld));
header("Content-Transfer-Encoding: binary");
header('Content-type: ' . $type);
header("Content-disposition: attachment; filename=$nameNew"); //
readfile($nameOld);
Related Topics
How to Send 500 Internal Server Error Error from a PHP Script
PHP Gd Use One Image to Mask Another Image, Including Transparency
How to Check That an Object Is Empty in PHP
Redirecting to Authentication Dialog - "An Error Occurred. Please Try Again Later"
How to Set a Default Attribute Value for a Laravel/Eloquent Model
How to Use Special Characters in Recipients Name When Using PHP's Mail Function
Echo Menu Tree with Recursive Function
PHP What Is the Best Approach to Using Xml? Need to Create and Parse Xml Responses
Type-Juggling and (Strict) Greater/Lesser-Than Comparisons in PHP
PHP APIs for Hotmail, Gmail and Yahoo
How to Solve Time Out in PHPmyadmin
Laravel 5 - After Login Redirect Back to Previous Page
Getting Pear to Work on Xampp (Apache/MySQL Stack on Windows)