1

ダウンロード可能なファイルをウェブサイトのユーザーに提供したいのですが、ファイルの URL をユーザーから隠したいのです... HTTPHandler でうまくいくと思いますが、外部サーバーからファイルを取得して、ユーザーにストリーミングしますか?

おそらく、誰かがこれを達成する方法のヒントを教えてくれたり、以前にそれが行われたリソースを教えてくれませんか?


私が達成しようとしていることを詳しく説明するために...音楽ダウンロードリンクを含むASP.NET Webサイトを構築しています。ファイルの実際の URL を保護したいし、それらを外部 (PHP) サーバーに保存したい (はるかに安い)...

したがって、私がする必要があるのは、URL からファイルを取得できる (別のサーバーを指す) ストリームをセットアップし、それが別のサーバーからのものであることをユーザーが認識せずに Response オブジェクトにストリーミングすることです。

TransmitFile メソッドを使用すると、完全に別のサーバーからファイルをストリーミングできますか? ファイルがサーバーを介してストリーミングされるのは望ましくありません。これは目的に反するためです(帯域幅を節約する)...クライアント(ブラウザ)に他のサーバーから直接ファイルをダウンロードさせたいのです。

おそらくファイルホスティングサーバーにハンドラーが必要ですか? たぶん、反対側のPHPスクリプトが行く方法です...?

4

5 に答える 5

1

帯域幅を自分のものではなく外部サーバーから取得することを明確にすると、問題が大きく変わります。

これを実現するには、外部サーバーにユーザーを送信できるWebサイトが必要です。ファイルをサイト経由でストリーミングすることはできませんが、帯域幅に影響されることはありません。または、サイトからファイルを制御するが他のサーバー経由でストリーミングすることはできないため、他のサイトを通じて完全に処理する必要があります。これに関する問題は、通常のURLベースのアプローチでは、ユーザーにURLが表示されることです。これは、URLを表示しないという2番目の要件です。

しかし、外部サイトのファイルを提供する一般的なページと、ストリーミングするファイルの詳細が元のサイトのページからの投稿を通過するだけではありませんか?これにより、特定のファイルを指すURLが削除されます。ドメインは表示されますが、ユーザーは投稿フィールドを知らずにファイルをプルすることはできません。

これはHTTPHandlerである必要はなく、通常のページです。

于 2008-10-02T14:08:13.057 に答える
1

TransmitFile メソッドを確認することをお勧めします: http://msdn.microsoft.com/en-us/library/12s31dhy.aspx

于 2008-10-02T02:40:57.780 に答える
1

はい、リモート ストリーム (別のサーバーからダウンロード) から出力ストリームにストリーミングできます。serviceUrlがストリーミングするファイルの場所であると仮定します。

HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(serviceUrl);
            webrequest.AllowAutoRedirect = false;
            webrequest.Timeout = 30 * 1000;
            webrequest.ReadWriteTimeout = 30 * 1000;
            webrequest.KeepAlive = false;

            Stream remoteStream = null;
            byte[] buffer = new byte[4 * 1024];
            int bytesRead;

            try {
                WebResponse responce = webrequest.GetResponse();
                remoteStream = responce.GetResponseStream();
                bytesRead = remoteStream.Read(buffer, 0, buffer.Length);

                Server.ScriptTimeout = 30 * 60;
                Response.Buffer = false;
                Response.BufferOutput = false;
                Response.Clear();
                Response.ContentType = "application/octet-stream";
                Response.AppendHeader("Content-Disposition", "attachment; filename=" + Uid + ".EML");
                if (responce.ContentLength != -1)
                    Response.AppendHeader("Content-Length", responce.ContentLength.ToString());

                while (bytesRead > 0 && Response.IsClientConnected) {
                    Response.OutputStream.Write(buffer, 0, bytesRead);
                    bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
                }

            } catch (Exception E) {
                Logger.LogErrorFormat(LogModules.DomainUsers, "Error transfering message from remote host: {0}", E.Message);
                Response.End();
                return;
            } finally {
                if (remoteStream != null) remoteStream.Close();
            }

            Response.End();
于 2008-12-06T02:11:15.243 に答える
0

さて、いくつかのphpコードの作成/展開を避けるための私の探求は無駄に思えます...これがファイル(php)サーバーで実行するものです:

http://www.zubrag.com/scripts/download.php

次に、私のasp.net Webサーバーからのリンクがそのスクリプトを指し、関連するファイルをダウンロードします(したがって、直接ダウンロードを回避し、Googleアナリティクスによるダウンロードの追跡を許可します)...それでうまくいくと思います

ありがとうグレッグ

于 2008-10-02T23:38:13.437 に答える
0

私は前にこれをやったことがあります。まず、明らかに、ファイルは、Web サイトのユーザー プロセスがアクセスできる外部サーバー上の共有に存在する必要があります。

HTTPHandler に関する限り、ダウンロードしたいファイルを含む zip ファイルをユーザーに提供することでこれを処理しました。このようにして、ハンドラーは .zip ファイルの呼び出しをインターセプトし、作成した zip ファイルをストリーミングできます。

コードは次のとおりです (かなりの量です。私は MVP を使用しているため、ハンドラーとプレゼンターに分割されています)。

public class ZipDownloadModule: IHttpHandler, ICompressFilesView, IErrorView 
{
    CompressFilesPresenter _presenter;

    public ZipDownloadModule()
    {
        _presenter = new CompressFilesPresenter(this, this);
    }
    #region IHttpHandler Members

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        OnDownloadFiles();
    }

    private void OnDownloadFiles()
    {
        if(Compress != null)
            Compress(this, EventArgs.Empty);
    }

    #endregion

    #region IFileListDownloadView Members

    public IEnumerable<string> FileNames
    {
        get 
        {
            string files = HttpContext.Current.Request["files"] ?? string.Empty;

            return files.Split(new Char[] { ',' });
        }
    }

    public System.IO.Stream Stream
    {
        get
        {
            HttpContext.Current.Response.ContentType = "application/x-zip-compressed";
            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=ads.zip");
            return HttpContext.Current.Response.OutputStream;
        }
    }

    public event EventHandler Compress;

    #endregion

    #region IErrorView Members

    public string errorMessage
    {
        set {  }
    }

    #endregion
}

プレゼンター:

public class CompressFilesPresenter: PresenterBase<ICompressFilesView>
{
    IErrorView _errorView;

    public CompressFilesPresenter(ICompressFilesView view, IErrorView errorView)
        : base(view)
    {
        _errorView = errorView;
        this.View.Compress += new EventHandler(View_Compress);
    }

    void View_Compress(object sender, EventArgs e)
    {
        CreateZipFile();
    }

    private void CreateZipFile()
    {
        MemoryStream stream = new MemoryStream();

        try
        {
            CreateZip(stream, this.View.FileNames);

            WriteZip(stream);
        }
        catch(Exception ex)
        {
            HandleException(ex);
        }
    }

    private void WriteZip(MemoryStream stream)
    {
        byte[] data = stream.ToArray();

        this.View.Stream.Write(data, 0, data.Length);
    }

    private void CreateZip(MemoryStream stream, IEnumerable<string> filePaths)
    {
        using(ZipOutputStream s = new ZipOutputStream(stream)) // this.View.Stream))
        {
            s.SetLevel(9); // 0 = store only to 9 = best compression

            foreach(string fullPath in filePaths)
                AddFileToZip(fullPath, s);

            s.Finish();
        }
    }

    private static void AddFileToZip(string fullPath, ZipOutputStream s)
    {
        byte[] buffer = new byte[4096];

        ZipEntry entry;

        // Using GetFileName makes the result compatible with XP
        entry = new ZipEntry(Path.GetFileName(fullPath));

        entry.DateTime = DateTime.Now;
        s.PutNextEntry(entry);

        using(FileStream fs = File.OpenRead(fullPath))
        {
            int sourceBytes;
            do
            {
                sourceBytes = fs.Read(buffer, 0, buffer.Length);
                s.Write(buffer, 0, sourceBytes);
            } while(sourceBytes > 0);
        }
    }

    private void HandleException(Exception ex)
    {
        switch(ex.GetType().ToString())
        {
            case "DirectoryNotFoundException":
                _errorView.errorMessage = "The expected directory does not exist.";
                break;
            case "FileNotFoundException":
                _errorView.errorMessage = "The expected file does not exist.";
                break;
            default:
                _errorView.errorMessage = "There has been an error. If this continues please contact AMG IT Support.";
                break;
        }
    }

    private void ClearError()
    {
        _errorView.errorMessage = "";
    }
}

お役に立てれば!!

于 2008-10-02T02:55:49.960 に答える