我想让一些用户下载从我的网站的一些文件,我不希望他们看到下载文件的物理路径。隐藏文件下载的物理路径在ASP.NET
我移动的文件夹中的文件,我的网络文件夹之外,并使用Response.WriteFile(文件路径)下载它们。这有助于我隐藏路径,但这种方法不支持我真正想要的简历下载。
那么你推荐使用什么方法?
我想让一些用户下载从我的网站的一些文件,我不希望他们看到下载文件的物理路径。隐藏文件下载的物理路径在ASP.NET
我移动的文件夹中的文件,我的网络文件夹之外,并使用Response.WriteFile(文件路径)下载它们。这有助于我隐藏路径,但这种方法不支持我真正想要的简历下载。
那么你推荐使用什么方法?
这里是最好的方法:
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();
}
创建一个临时目录和文件复制到那里。您甚至可以将文件重命名为其他内容,以便它不是“可猜测的”。
我假设,如果他们可以下载文件,它的内容是适用于人,因此不存在问题,该用户知道的直接联系。其他人将无法猜测随机目录和/或文件名。
var directoryName = String.Format("{0}\{1}\{2}",
Server.MapPath("original Path"),System.Guid.NewGuid().Replace("-",""), fileName);
这几乎是我们用来从我们的系统中导出信息的相同过程。
当用户首次下载文件时,我在数据库中为该用户设置了到期日期。所以我希望此用户在下载时间到期后将无法下载该文件。 – Libertad
我想实现一个文件处理程序(ashx的文件),提供基于某种在查询字符串ID或名字的文件,并将其发送这样的:
asp.net ashx handler prompting download instead of displaying file
此方法不是恢复支持。 – Libertad
您如何看待他们知道你的路径?对公众而言,你在揭露你的物理道路吗? –
@Grant,我没有公开物理路径,但是您知道当您使用下载管理器(如IDM)下载文件时,您的物理路径将被暴露。但正如我所说我使用'Response.WriteFile'隐藏文件的物理路径,但它不是恢复支持。 – Libertad