开发者

Securing Large Downloads Using C# and IIS 7

开发者 https://www.devze.com 2022-12-18 13:13 出处:网络
Here\'s the setup: 1 web server running a C# app to which my users (stored in a MySQL database on said server) authenticate.

Here's the setup:

  • 1 web server running a C# app to which my users (stored in a MySQL database on said server) authenticate.

  • 1 file server running software TBD. In the past I've used lighttpd and mod_secdownload to secure the fi开发者_JS百科les on the file servers, and it's worked well(ish).

I'm wondering if there is a way to do this using a combination of IIS and C# .Net. All my other servers are running that combo, and it would simplify things a bit if I could do the same for the file servers. The kicker is, the files that are being hosted are large. I've seen examples of people using a small app to create a FileStream object, read in the file, and create the HTTP Response by hand. This works, but since I'm working with files 500+ MB in size, it's slow as heck. And I'll potentially have 300 users hitting the box at once, requesting files. That's no good.

So, anyone see a way around this? I'm trying to create a more transparent system, and if all my servers are running the same software/hardware, it will make my life a whole lot simpler. Thanks in advance for any advice you give!


You know what? The KB article is poo. Here is my official recommendation:

public void StreamFile(string filePath)
{
    string fileName = Path.GetFileName(filePath);

    using (var fStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        var contentLength = fStream.Length;

        if (Request.UserAgent.Contains("MSIE"))
        {
            Response.AddHeader("Content-Transfer-Encoding", "binary");
        }

        Response.ContentType = "application/octet-stream";
        Response.AddHeader("Content-Length", contentLength.ToString());

        // Even though "Content-Disposition" should have an upper-case "d", as per http://www.ietf.org/rfc/rfc2183.txt
        // IE fails to recognize this if the "d" is upper-cased.
        Response.AddHeader("Content-disposition", "attachment; filename=" + fileName);

        var buffer = new byte[8192];

        while (Response.IsClientConnected)
        {
            var count = fStream.Read(buffer, 0, buffer.Length);
            if (count == 0)
            {
                break;
            }

            Response.OutputStream.Write(buffer, 0, count);
            Response.Flush();
        }
    }

    Response.Close();
}


This thread has my solution to keep memory usage down while users are downloading files. You probably want a bigger buffer than my sample uses, though.


You may be interested in Microsoft's Background Intelligent Transfer Service (BITS).

http://msdn.microsoft.com/en-us/library/bb968799%28VS.85%29.aspx

Version 2.5 introduced HTTP authentication via certificates.


While this isn't directly applicable since you're using MySql but it's something to consider (might even be available for free by using sql server 2008 express). Sql Server 2008 offers Filestream support which lets you access files as if they are directly stored in the database but actually reside on a fileserver. Then information on the other posts can help you with getting it to the user.

FILESTREAM Storage in SQL Server 2008

0

精彩评论

暂无评论...
验证码 换一张
取 消