Exemplo n.º 1
0
    public static void DownloadFile(HttpContext context, string filepath, string filename, bool isPublic)
    {
        if (context == null)
        {
            throw (new ArgumentNullException("context"));
        }
        if (filepath == null)
        {
            throw (new ArgumentNullException("filepath"));
        }
        if (filename == null)
        {
            throw (new ArgumentNullException("filename"));
        }

        if (!File.Exists(filepath))
        {
            throw (new HttpException(404, filename + " not found!"));
        }

        FileInfo fileinfo = new FileInfo(filepath);
        int      filesize = (int)fileinfo.Length;

        int  start, length;
        bool hasRange = GetRange(context, filesize, out start, out length);

        if (!hasRange)
        {
            string since = context.Request.Headers["If-Modified-Since"];
            if (!string.IsNullOrEmpty(since))
            {
                DateTime sinceDate = DateTime.Parse(since);
                TimeSpan sinceSpan = fileinfo.LastWriteTime - sinceDate;

                if (sinceSpan.TotalSeconds < 1 && sinceSpan.TotalSeconds > -1)
                {
                    context.Response.Status = "304 (Not Modified)";
                    context.Response.End();
                    return;
                }
            }
        }

        if (isPublic)
        {
            context.Response.Cache.SetCacheability(HttpCacheability.Private);
            context.Response.Cache.SetETag(CalcETag(fileinfo.FullName + ":" + fileinfo.LastWriteTime.Ticks));
            context.Response.Cache.SetLastModified(fileinfo.LastWriteTime);
        }
        else
        {
            //maybe the attachment is security file . do not cache it!
            context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        }

        string attachemntame = filename;

        string mime = SampleUtil.GetMimeType(filename);

        context.Response.ContentType = mime;

        if (mime.StartsWith("text/"))
        {
            //all text file can be html or script.
            //it's dangerous that let the user open the html file on the browser directly.
            //the html may contains javascript that can thieve the cookie of the user on your website.

            //change the response and force the browser download the file.
            context.Response.ContentType = "application/unknown";
            attachemntame = attachemntame + ".download";
        }

        //attachemntame = context.Server.UrlEncode(attachemntame);
        context.Response.AddHeader("Content-Disposition", "inline;filename=" + attachemntame);


        byte[] buff = new byte[0x10000];
        Stream outp = context.Response.OutputStream;

        using (FileStream fs = new FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            if (hasRange)
            {
                context.Response.StatusCode = 206;
                context.Response.AddHeader("Content-Length", length.ToString());
                context.Response.AddHeader("Content-Range", "bytes " + start + "-" + (start + length - 1) + "/" + filesize);
            }
            else
            {
                context.Response.AddHeader("Content-Length", filesize.ToString());
                start  = 0;
                length = filesize;
            }

            if (start != 0)
            {
                fs.Seek(start, SeekOrigin.Begin);
            }

            int readlen = 0;

            while (true)
            {
                int readnow = Math.Min(0x10000, length - readlen);
                if (readnow <= 0)
                {
                    break;
                }

                int rc = fs.Read(buff, 0, readnow);
                if (rc <= 0)
                {
                    break;
                }

                readlen += rc;

                if (CuteWebUI.UploadModule.LimitSpeedForTest)
                {
                    System.Threading.Thread.Sleep(100);
                }

                outp.Write(buff, 0, rc);

                //if the client is disconnect , this method will throw an exception and stop sending file data
                context.Response.Flush();
            }
        }
    }