2013-02-08 74 views
0

我想让一些用户下载从我的网站的一些文件,我不希望他们看到下载文件的物理路径。隐藏文件下载的物理路径在ASP.NET

我移动的文件夹中的文件,我的网络文件夹之外,并使用Response.WriteFile(文件路径)下载它们。这有助于我隐藏路径,但这种方法不支持我真正想要的简历下载。

那么你推荐使用什么方法?

+0

您如何看待他们知道你的路径?对公众而言,你在揭露你的物理道路吗? –

+0

@Grant,我没有公开物理路径,但是您知道当您使用下载管理器(如IDM)下载文件时,您的物理路径将被暴露。但正如我所说我使用'Response.WriteFile'隐藏文件的物理路径,但它不是恢复支持。 – Libertad

回答

0

这里是最好的方法:

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(); 
    } 
1

创建一个临时目录和文件复制到那里。您甚至可以将文件重命名为其他内容,以便它不是“可猜测的”。

我假设,如果他们可以下载文件,它的内容是适用于人,因此不存在问题,该用户知道的直接联系。其他人将无法猜测随机目录和/或文件名。

var directoryName = String.Format("{0}\{1}\{2}", 
Server.MapPath("original Path"),System.Guid.NewGuid().Replace("-",""), fileName); 

这几乎是我们用来从我们的系统中导出信息的相同过程。

+0

当用户首次下载文件时,我在数据库中为该用户设置了到期日期。所以我希望此用户在下载时间到期后将无法下载该文件。 – Libertad

0

很简单,我以前做过这个。 只需隐藏“输入文件”控件,使其隐藏在用户界面上,然后创建一个按钮,单击事件触发“输入文件”控件的单击事件。 然后,你也可以使用JavaScript(在我的情况下,它是JQuery),将浏览的文件的名称放入代表文件名称的文本框中。

因此,该文件路径是从用户界面隐藏。

+0

上传与下载有什么关系? – ChrisBint

+0

从用户界面隐藏,也许。但不是从用户隐藏。 – jao