none
Response.TransmitFileメソッドで2GB以上のファイルをダウンロードできない。 RRS feed

  • 質問

  • Response.TransmitFileメソッドで2GB以上のファイルをダウンロードできないです。
    http://support.microsoft.com/kb/913393/
    で、バグとして取り扱われているのですが、
    .Net Framework 2.0 SP1で修正された項目にあるのですが、
    現在最新版のSP2でも同じエラーがでます。
    実験した環境は、WindowsXP SP3、.Net Framework 3.5 SP1、IIS5.1と、
    WindowsXP SP3、.Net Framework 3.5 SP1、開発サーバーです。
    まだ、バグが残っていて修正しきれていないとか、
    設定やプログラムで対処できるなどがあれば、ご教授ください。
    よろしくお願いします。
    2008年11月17日 13:36

回答

  • Response.TransmitFile について .NET Framework のソースをステップ実行してわかったことを書かせていただきます。

     

    .NET Framework としては Int32 を超えるファイルサイズに対応しているようですが、このエラーは Web サーバー側(IIS 5.1 や開発サーバー)の制限によるものなのかもしれません。

     

    内部では、HttpWorkerRequest の派生クラスが持つ SupportsLongTransmitFile プロパティによって Int32 を超えるファイルサイズをサポートしているかどうかを判断し、そのプロパティが false を返し、かつファイルが大きければ、例外をスローするようになっていました。

     

    基底の HttpWorkerRequest クラスではこのプロパティは virtual 宣言されており、常に false を返すようになっています。開発サーバー上で動作する際の HttpWorkerRequest の派生クラスは Microsoft.VisualStudio.WebHost.Request のようで、このクラスではこのプロパティを override しないために値は false となり、このために 2G を超えるファイルサイズのダウンロードでは例外が発生します。試しにデバッグ実行上でこの値を true に変更してみたのですが、エラーは発生しなかったものの、ダウンロードもできませんでした(ダウンロードしたファイルの中身がそのテストページの HTML ファイルになってしまいました)。

     

    SupportsLongTransmitFile プロパティが true を返すように override されているクラスを検索してみたところ、2つのクラス(ISAPIWorkerRequestInProcForIIS6 と IIS7WorkerRequest)が見つかりました。それらのソースにはどちらにもコメントが書かれており、IIS6 にて 64 ビットファイルサイズをサポートすると書かれていました。

    そこで IIS6 の環境にて 3G のファイルのダウンロードを TransmitFile で行ってみたところ、ダウンロードは正常に機能しました。

     

    実際に動作させる環境が Windows XP ということはないと思いますので、サーバーが IIS6.0 以降(Windows 2003 以降)であれば問題ないということになるかと思われます。

    KB913393 にて開発サーバーに対しても修正がなされているようですが、それがなぜ最新版に反映されていないのかについてはわかりません。フィードバックされてみられると仕様なのかどうかがわかるかもしれません。(http://www.microsoft.com/japan/msdn/vstudio/feedback/

    2008年12月1日 3:56

すべての返信

  • クライアントはIE6を使われているでしょうか?IE6では2GB以上のファイルがダウンロードできないですが…。

    2008年11月17日 16:20
  • クライアントは、IE7とFirefox3.0.4で実験しましたが失敗しました。

    クライアントの問題は考えていませんでした。

    クライアントの問題かもしれないと考え、試してみたいと思います。

    2008年11月18日 1:02
  • Firefox3.0.4で試しに、
    Abyss Web Server X1というサーバーを入れた結果、
    普通にASP.NETを使用しないでやった場合は、5GBのファイルもダウンロードできましたが、
    やはり、ASP.NETで
    Response.TransmitFileを使用した場合、同じエラーが発生してしまいました。
    なので、ASP.NET自身になにか問題があるのでは・・・と思います。
    2008年11月18日 4:03
  • .NET Framework 3.5 を使っていてもASP.NETのベースは、.NET Framework 2.0で動いています。

     

    試しに、http://code.msdn.microsoft.com/KB913393/Release/ProjectReleases.aspx?ReleaseId=777 から

    修正パッチを入手し、Webサーバーにインストールしてみてください。

    それでもダメなら、またご連絡頂けますか?

     

    もし上記でダメという話になると、HTTPヘッダのContent-Length を強制的に書き換えるものが必要ですね。

    (ただこれはあまりお勧めしたくないところですが・・・)

    宜しくお願いします。

     

     

     

    2008年11月20日 12:05
  • やってみましたが、修正パッチを自体をインストールしようとすると、
    「Windowsインストーラサービスでアップグレード修正プログラムをインストールできません。
    アップグレードするプログラムが存在しないか、またはアップグレード修正プログラムでアップグレードするプログラムのバージョンが違う可能性があります。アップグレードするプログラムがこのコンピュータにあり、アップグレード修正プログラムが正しいかどうかを確認してください。」と、
    出てしまってインストールできませんでした。
    試しにインストーラから直接ファイルを抜き出してコピーしてみましたが、
    それは今度は実行できなくなるエラーで失敗してしまいました。

    いろいろとご迷惑をおかけしてすみません。
    2008年11月20日 18:44
  •  みみたん さんからの引用
    やってみましたが、修正パッチを自体をインストールしようとすると、
    「Windowsインストーラサービスでアップグレード修正プログラムをインストールできません。

    そしたら、3.5 をアンインストールし、その後、

    http://code.msdn.microsoft.com/KB913393/Release/ProjectReleases.aspx?ReleaseId=777

    をインストール、その後、3.5 をインストールしてみてください。

    ご確認の程、宜しくお願いします。

    2008年11月21日 13:02
  • 3.5をアンインストールして、2.0SP2にしたのですが、2.0SP2ではパッチをあてることができませんでした。
    なので、いったん2.0SP2を削除してから、2.0SPなしをインストールしてからならばパッチをインストールできましたが、
    さらに3.5SP1をインストールすると2.0SPなしがアップグレードされ、
    http://support.microsoft.com/kb/913393/
    にあるファイルすべてがもすべてアップグレードされ、
    エラーが出てしまいます。
    2008年11月24日 16:38
  •  みみたん さんからの引用
    3.5をアンインストールして、2.0SP2にしたのですが、2.0SP2ではパッチをあてることができませんでした。
    なので、いったん2.0SP2を削除してから、2.0SPなしをインストールしてからならばパッチをインストールできましたが、
    さらに3.5SP1をインストールすると2.0SPなしがアップグレードされ、
    http://support.microsoft.com/kb/913393/
    にあるファイルすべてがもすべてアップグレードされ、
    エラーが出てしまいます。

     

    確認になりますが、エラーが出てしまいますというのは、.NET Framework のインストールでエラーになっているんでしょうか?

    それともパッチ当てても改善しないという意味でエラーが出ているといってますか?

     

    ちなみに、3.5 SP1 には、2.0 SP2 の更新プログラムの内容を含んでいるので、

    3.5SP1をインストールすると2.0SPなしがアップグレードされるのは正しいと思いますが・・・

     

    すいませんが、補足情報いただけると助かります。宜しくお願いします。
    2008年11月27日 10:03
  • すみません。説明不足でした。
    エラーが出ているというのは、改善しないという意味です。

    2.0SPなしが2.0SP2にアップグレードされてしまい、そのパッチをされたファイルも一緒に更新されているように思えます。
    容量が、2.0SPなしにパッチをインストールすると、
    http://support.microsoft.com/kb/913393/に書いてあるファイルが書いてある容量になりますが、
    けれども、3.5SP1をインストールすると、2.0SPなしがアップグレードされて2.0SP2になると、
    URLに書いてあるファイルの容量が変更されてしまいます。
    なので、パッチをインストールした意味がなくなっているということです。
    2008年11月27日 16:14
  • Response.TransmitFile について .NET Framework のソースをステップ実行してわかったことを書かせていただきます。

     

    .NET Framework としては Int32 を超えるファイルサイズに対応しているようですが、このエラーは Web サーバー側(IIS 5.1 や開発サーバー)の制限によるものなのかもしれません。

     

    内部では、HttpWorkerRequest の派生クラスが持つ SupportsLongTransmitFile プロパティによって Int32 を超えるファイルサイズをサポートしているかどうかを判断し、そのプロパティが false を返し、かつファイルが大きければ、例外をスローするようになっていました。

     

    基底の HttpWorkerRequest クラスではこのプロパティは virtual 宣言されており、常に false を返すようになっています。開発サーバー上で動作する際の HttpWorkerRequest の派生クラスは Microsoft.VisualStudio.WebHost.Request のようで、このクラスではこのプロパティを override しないために値は false となり、このために 2G を超えるファイルサイズのダウンロードでは例外が発生します。試しにデバッグ実行上でこの値を true に変更してみたのですが、エラーは発生しなかったものの、ダウンロードもできませんでした(ダウンロードしたファイルの中身がそのテストページの HTML ファイルになってしまいました)。

     

    SupportsLongTransmitFile プロパティが true を返すように override されているクラスを検索してみたところ、2つのクラス(ISAPIWorkerRequestInProcForIIS6 と IIS7WorkerRequest)が見つかりました。それらのソースにはどちらにもコメントが書かれており、IIS6 にて 64 ビットファイルサイズをサポートすると書かれていました。

    そこで IIS6 の環境にて 3G のファイルのダウンロードを TransmitFile で行ってみたところ、ダウンロードは正常に機能しました。

     

    実際に動作させる環境が Windows XP ということはないと思いますので、サーバーが IIS6.0 以降(Windows 2003 以降)であれば問題ないということになるかと思われます。

    KB913393 にて開発サーバーに対しても修正がなされているようですが、それがなぜ最新版に反映されていないのかについてはわかりません。フィードバックされてみられると仕様なのかどうかがわかるかもしれません。(http://www.microsoft.com/japan/msdn/vstudio/feedback/

    2008年12月1日 3:56
  • ありがとうございます。
    ステップ実行まではしてみませんでした。
    IIS6.0以降で試してみる機会があったら試してみます。
    2008年12月1日 12:26