none
Content-Disposition: inline; filename="attachment.html" を出力してもファイルをダウンロードしてしまう RRS feed

  • 質問

  • eラーニングシステムMoodleの改良を行っている白井と申します.

    今回,Moodle上のWiki (eWiki) で半角アルファベットattachment(大文字,小文字,混在関係なく)を含むページを作成すると,IE8では編集も閲覧もできず,ページがテキストファイルとしてダウンロードされてしまう現象に遭遇しました.色々と調べてみた結果,PHPでheader()関数によりヘッダーを送信する箇所に現象の間接的原因があることが分かってきました.それがタイトルの通り,Content-Dispositionに関わる箇所です.

    Content-Disposition: inline; filename="attachment.html"

    たとえばfilename="ほにゃらら.html"の箇所が,aaaaaaattachmenttttt であっても,AttAchmentであっても,IE8はインライン表示しないでダウンロードしようとします.Moodleの関係するソースリストを強制的に書き換えて,この箇所のみファイル名を変更していますが,ダウンロード時のファイル名はaaaaaaattachmenttttt.htmlなり,AttAchment.htmlなりのヘッダー部だけ強制的に書き換えたファイル名でダウンロードされますので,filename=""自体は正常に処理されているようです.
    ただ,この送出されるコンテンツが inline なのか,attachment なのかの判断を行うのに,Content-Disposition: の右側も文字列全てを対象としてattachmentが含まれているのかどうかを調べているのではないでしょうか? filename=""の中は除外せずに.

    filename="atachment.html"(tを一つ抜く)などのように,attachmentさえ含まれて居なければ,正しくWebブラウザ上に表示されます.

    対象となる文字列が半角英字ですのでurlencode()などの手段では逃げられません.
    一応,このContent-Dispositionのヘッダーを送出しないでも,現在の所,MoodleのeWikiの動作には影響が無いように見えますので,当面はこの対策(ブラウザの種別がIEの場合はContent-Dispositionを送出しない)で乗り切る予定ですが,何かもっと良い方法は無いでしょうか.

    他にもこの現象に気付いた方,対策された方,いやいやそれはバグではないなど,御意見頂けると助かります.
    また,これがもしIEのバグ(RFC1806に正式対応しないのが仕様ならばそれも仕様上のバグと考えます)ならば,どこにこの報告を行えば良いのでしょうか.
    2009年12月15日 7:30

回答

  • IE6&XP、IE7&XP、IE8&Win7でも再現することを確認しました(`・ω・´)
    # Aタグでリンク先を押下したときの話ですよね?
    FF3.5.、Safari4、Opera10では再現しませんでした。

    私もバグだと思いました。

    HTTPレスポンスでinlineでfilenameを付与するケースが現実世界でほとんどなかったということなんでしょうかね。

    >一応,このContent-Dispositionのヘッダーを送出しないでも
    確かにあんまり聞いたことがない>レスポンスのトップレベルヘッダにContent-Disposition: inline
    (RFCに有る無いは別にして)

    以前から思っていたのですが、HTTPヘッダごとの説明をMSDNに欲しいのですが、探しても解説が見つかりませんね。
    inlineでfilenameを付与したときにIEでどのような効果になるか確認したい!(そこまでの説明はなくともある程度で)
    今回のような字句解析?部は書けなくても意味としてどのようにとらえるかという部分。(X-系のヘッダもポコポコ増えていますし)
    • 回答としてマーク 白井達也 2009年12月15日 23:45
    2009年12月15日 15:33

すべての返信

  • IE6&XP、IE7&XP、IE8&Win7でも再現することを確認しました(`・ω・´)
    # Aタグでリンク先を押下したときの話ですよね?
    FF3.5.、Safari4、Opera10では再現しませんでした。

    私もバグだと思いました。

    HTTPレスポンスでinlineでfilenameを付与するケースが現実世界でほとんどなかったということなんでしょうかね。

    >一応,このContent-Dispositionのヘッダーを送出しないでも
    確かにあんまり聞いたことがない>レスポンスのトップレベルヘッダにContent-Disposition: inline
    (RFCに有る無いは別にして)

    以前から思っていたのですが、HTTPヘッダごとの説明をMSDNに欲しいのですが、探しても解説が見つかりませんね。
    inlineでfilenameを付与したときにIEでどのような効果になるか確認したい!(そこまでの説明はなくともある程度で)
    今回のような字句解析?部は書けなくても意味としてどのようにとらえるかという部分。(X-系のヘッダもポコポコ増えていますし)
    • 回答としてマーク 白井達也 2009年12月15日 23:45
    2009年12月15日 15:33
  • 一応、仕様上は

    ・ inline が指定されている場合はインライン表示を行う
    ・ inline 以外が指定されている場合は、コンテンツプロデューサーが inline ではない拡張を期待しているため、インライン表示以外を行う。この典型的な例は attachment として定義され、filename パラメータによってファイル名を提案できる

    ということになっていますので、たとえファイル名ではなくても inline 以外の文字列が Content-Disposition ヘッダに現れた場合には、ブラウザは添付ファイルとして処理しても仕様的には問題ありません。パラメータ部の文脈でブラウザの挙動がかわってしまうのは、期待しない挙動であるのはもっともですが、inline にファイル名が指定されることを想定していないと受け止めるべきでしょうね。
    2009年12月15日 23:51
  • 返信ありがとうございます.
    私も実際上の立場からinlineに対するfilenameのパラメータは不要であると考えていました.

    ただ,RFC1806の以下の和訳を読む限りでは,

    「ファイル名パラメータの存在は実装で別のファイルにエンティティを書   き込むことを強いていない。さもなければ、ユーザの要求しなければ普   通のメールストリームの一部としてエンティティを残しておくことは、   実装に対してまったく適切である。結果として、パラメータはどんな   MIME エンティティ (`inline' も) にも使うことができる。これらは通   常ファイルに保存されないだろう。しかし、もし受信側のユーザーが   ファイルに part を書き込むことを決めたなら、パラメータはファイル   名を供給するために使われることができる。 」(2.4節最終段落)
    http://lab.moyo.biz/translations/rfc/rfc1806-ja.xsp

    inlineであってもfilenameパラメータを指定する可能性があることと,その拡張的な価値を明記しています.ここまでIEが倣う必要は確かにありませんが,inline; filename="" の形式が有り得ることは考慮して頂けると助かりますね.

    とりあえず当方で改良・配布しているMoodle(fs_moodle)のeWikiでは,クライアントのブラウザがIEの場合はこのヘッダー自体を送出しないように対策を行いました.
    2009年12月16日 5:20
  • 素早い返信,および検証,どうもありがとうございます.

    PHPファイルを指定してフレームにHTMLを流し込む箇所のコードだったと思いますので,Aタグによるハイパーリンクとは微妙に異なります.もしそのフレーム内のコンテンツのファイル名をURIから取得されると拡張子は.phpとなってしまいますので,inlineで流し込む(という表現が適切かどうか?)コンテンツにfilenameでファイル名を動的に生成して渡すことには,いくらかの意味があると考えました.ブラウザやFireBugなどのプラグインがそのfilenameの情報をどのように扱うのか/扱うべきなのかは私にも分かりません.”名前を付けてページを保存”などで動的に生成されたHTMLファイルを保存する際のファイル名として意味があるのではないか,程度の認識です.

    #お手数でなければ,その検証に利用したソースをこちらに上げて頂けないでしょうか.

    2009年12月16日 5:29
  • >いくらかの意味があると考えました.
    意味あり!です。

    ご指摘を受けこちらで確認した所、フレームにおいてはお察しの通りFireFox(とSafari)では
    「右クリック」→「このフレーム」→「名前を付けてこのフレームを保存」
    とするとContent-Disposition: inline; filename="hoge.htm"としておくと、
    filename属性の値でファイル保存ダイアログに表示されました(FRAMEタグのsrc属性の方は適用されずに)。
    逆に、filenameを指定しない場合はFRAMEタグのsrcの方が採用されました。
    IE、Chrome、Operaではそもそもこの機能を見つけられませんでした。

    また、IEであっても、画像表示(imgタグ)で画像返却時のレスポンスヘッダとして
    Content-Disposition: inline; filename="hoge.gif"を指定すると、
    「名前を付けて画像を保存」時に出てくるファイル保存ダイアログに投入されるファイル名は
    filenameで指定した方が使われていました(imgタグのsrc属性で示されるURLの方は適用されずに)。
    imgタグ時ではたとえfilename=attachment.gifであっても画像を表示しただけではファイル保存ダイアログは表示されませんでした。
    このように、IEでもinline; filename=""が考慮されるケースがあるようです。
    ついでにalt属性の代用としても使用される可能性があると思って調べてみましたが、そんなことはないようでした。

    話は変わりますが、思いついたのですが、
    ①IEがContent-Dispositionのfilenameの値をshift-jis前提で読み取る理由
    ②IEがimgのsrc属性に日本語ファイル名を指定したときに「名前をつけて保存する」とするとindex.datにutf8で保存されているにも関わらずshift-jis前提で取得しに行く理由
      http://social.technet.microsoft.com/Forums/ja-JP/internetexplorerja/thread/5bbc7cd7-8efe-411a-b7b0-7d49c882da49
    にそれぞれ相関関係があるように見えてきました!
    もしかして今回調査したケースを救いたかったかもです。



    >お手数でなければ,その検証に利用したソースをこちらに上げて頂けないでしょうか.
    ?目的がよく分かりませんが、貼り付けておきます。どこぞのコピペですが。

    phpとか

    <?php
     header("Content-Disposition: inline; filename=\"attachment.htm\"");
     print("hoge");
    ?>

    画像の返却とか

    #!c:\apps\perl\bin\perl
    use warnings;
    my $MY_FILE_NAME = 'hoge.GIF';
    my $CHUNK_SIZE = 4096;
    open( MY_FILE, "<$MY_FILE_NAME" )
        or die( "Can't open $MY_FILE_NAME: $!\n" );
    print "Content-type: image/gif;\r\n";
    print "Content-Disposition: inline; filename=\"attachment.gif\"\r\n";
    print "\r\n";
    binmode( MY_FILE ); # These are crucial!
    binmode( STDOUT );
    while ( my $cb = read( MY_FILE, $data, $CHUNK_SIZE ) ) {
        print $data;
    }
    close( MY_FILE );
    2009年12月16日 14:13
  • >ご指摘を受けこちらで確認した所、フレームにおいてはお察しの通りFireFox(とSafari)では
    >「右クリック」→「このフレーム」→「名前を付けてこのフレームを保存」
    >とするとContent-Disposition: inline; filename="hoge.htm"としておくと、
    >filename属性の値でファイル保存ダイアログに表示されました(FRAMEタグのsrc属性の方は適用されずに)。
    >逆に、filenameを指定しない場合はFRAMEタグのsrcの方が採用されました。

    ありがとうございます.確かにFirefoxではこの機能が有効ですね.
    Moodleでも動的に生成されて読み込まれたフレームの箇所をFirefoxで右クリックしてファイルに保存する際のダイアログボックスにはfilename=""で指定したファイル名が採用されました!
    仰るとおり,IEにはこのフレーム(Moodleの該当箇所は少し違うようですが)を保存することができませんでしたが(attachmentにした時はダウンロードできたのに^^;).

    特にIMGタグに関するIEの挙動に関してはとても素晴らしい情報です.ありがとうございます.
    だとすればattachmentの判別はもっとしっかりと行って欲しいですね.
    IMGタグで読み込んだ画像のファイル名が文字化けする問題(右クリックで画像を保存時)はこちらでもペンディングにしていた要解決課題でした.
    今回の件が解決の糸口になりそうです.
    2009年12月17日 0:04