Moodle開発者フォーラム

eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう

 
1997年の頃の写真です
eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

 クライアントのWebブラウザがIEの場合のみ発生する現象です.

 当方のeWikiはかなり標準に対して修正を加えていますので,もしかしたら当方だけの問題かも知れません.できましたら検証して頂けると助かります.また,IEのバージョンは日本版IE8でのみ確認しています.海外用IE,他のバージョンでは挙動が異なるかも知れません.


現象: eWiki上で文字列"attachment"(半角アルファベット.大文字小文字関係なし)を含むページを新規作成し,そのページを編集しようとしてもページがダウンロードされてしまう(添付の図を参照).ブラウザがIEの場合のみ発生し,Firefox3.5では発生しなかった.Firefox3.5で当該ページを編集し,IEにより閲覧しようとしても同じくページがダウンロードされてしまう.

 つまりeWikiのなんらかのページの編集画面で [attachment] と記述し,このページを保存すると,(まだattachmentというページが存在しないならば) attachment? と表示されます.末尾の?をクリックするとattachmentというページ名のWikiページの編集画面に遷移するはずが,このページ(attachment.html)をIEは画面に描画せずにダウンロードしてしまいます.

 ページ名にattachmentを含んでいれば,[aaaaaaaattachmenttttttttt]でも本現象は発生します.[aTTachment]のように大文字と小文字を混在させても発生します.


原因: おおよそ判明しています.多分,IEのバグでしょう.ページを閲覧あるいは編集するには,mod/wiki/view.phpが呼ばれます.さらにmod/wiki/ewiki/ewiki.phpがインクルードされます.この中にあるfunction ewiki_http_headers()でブラウザに送出するヘッダーを生成しています.

      if (!empty($data)) {
         if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
         if ($uu = @$data["version"]) @header('Content-Version: ' . $uu);
         if ($uu = @$data["lastmodified"]) @header('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
      }

青字で示したContent-DispositionのヘッダーをIEが正しく解釈していないものと思われます.inline展開かattachmentでダウンロードかの判断を行うのに,Content-Disposition:の右側の文字列全体を検索して"attachment"が含まれているか,inlineが含まれているか(後者は現象を検証していませんので,attachmentが含まれているかだけでTrue or not Trueと判断している疑惑もあります)で挙動を切り替えている可能性が大です.filename=の後にダブルクオートで括っている部分を検索から除外していないのではないか,と.

対策: いまのところ二つ考えられます.全て,クライアントのブラウザがIEと判断した時のみの対策です.

  1. Content-Dispositionのヘッダー自体を送出しない: 一応,ページの編集/閲覧は可能になりましたが,副作用(添付ファイルのダウンロードなど)が発生する恐れがあります.
  2. filename(つまり$uu)に"attachment"が含まれる場合は"_ttachment"などに置換してしまう.

日本語文字化けの問題とは異なりますので,urlencode(), rawurlencode()では乗り切れませんねぇ.これからUsing moodleの方も検索してみようと思います.


 
最大評点: -
1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

Using moodleの検索は諦めました.あまりにも沢山のページがヒットしてしまいます.

とりあえず急場しのぎで1の対策を行いました.

#-- HTTP meta headers
function ewiki_http_headers(&$o, $id, &$data, $action) {
   global $ewiki_t;
   if (EWIKI_HTTP_HEADERS && !headers_sent()) {
      if (!empty($data)) {
// (IE_Problem027): ここから修正
//
       if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
         if (!check_browser_version('MSIE') and ($uu = @$data["id"])) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
// (IE_Problem027): ここまで修正
         if ($uu = @$data["version"]) @header('Content-Version: ' . $uu);
         if ($uu = @$data["lastmodified"]) @header('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
      }

なんらかの副作用を恐れるのであれば,IEかつ$uuに"attachment"を含むならばヘッダーを送出しない,とするべきかも知れません.パフォーマンスの低下を防ぐことと論理のミスを恐れてこのようにしました.どうでしょうね?

画像 Haruhiko Okumura
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators
あほなバグですね!

別解として

urlencode($uu)



urlencode(egegi_replace("attachment", "%61ttachment", $uu))

にするとか。
1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

 なるほど,UTF-8の1byte,a = 0x060に置き換えるのですね.

 なお,まだ完全に裏を取れたわけではありません.たとえば,Moodle本体も同じヘッダー形式を使っているとすれば,attachment.jpgという画像ファイルをフォーラム投稿に添付すればインライン表示されずにダウンロードされるはずです.もしMoodle本体側ではこれが生じないならば何か違いがあるということですね.


おや,インライン表示されましたね.send_file()を使っていませんでしたか.もう少し調べてみます.

ああ,フォーラム添付の画像はインライン展開ではなくて<img>タグですね.

1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

ちなみに,RFC1806の和訳はこちらです.

http://lab.moyo.biz/translations/rfc/rfc1806-ja.xsp

1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

 こちらのMicrosoftの情報が今でも生きているならば,inlineだろうがattachmentだろうがお構い無しにContent-Dispositionヘッダーが送られてきたらダウンロードするし,filenameパラメータがあったら利用する,というように受け取れますね.

http://support.microsoft.com/default.aspx/kb/436616/

 attachmentをfilenameパラメータに含まれない場合はダウンロードしないでinlineして頂ける,ということでしたら,やはりこのヘッダーを送らない方が無難そうですね.

#四の五の言わずに,RFCに従ってコーディングしてくれれば世の中丸く収まるものなのですけれども.

MSDNのフォーラムに投稿しました.
http://social.msdn.microsoft.com/Forums/ja-JP/internetexplorerja/thread/8bad403f-de11-4b3c-bc79-6180508ddd4a

誰が読んで,誰が対応してくれるのかが不透明というのは困りますね.開発チームに情報を上げることはできないのでしょうか.

#改めて,オープンソースの有り難さを痛感しましたね.

1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

 他に検証して頂いた方と,仕様上は仕方がないという回答の方が現れました.

 仕様に関してはRFCの和訳を読む限りで,inlineであってもfilenameのパラメータが与えられる可能性があることを明記されているようですので,やはりきちんと判別して(実装上は無視して)欲しいところです.

1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

 ほぼIEのバグという結論になりました.この現象を確認するには,mod/wiki/ewiki/ewiki.phpのfunction ewiki_http_headers()の,

      if (!empty($data)) {
         if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
         if ($uu = @$data["version"]) @header('Content-Version: ' . $uu);
         if ($uu = @$data["lastmodified"]) @header('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
      }

この部分を

      if (!empty($data)) {
//       if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uu) . '.html"');
         $uua = 'aaaattachmenttttt';
         if ($uu = @$data["id"]) @header('Content-Disposition: inline; filename="' . urlencode($uua) . '.html"');
         if ($uu = @$data["version"]) @header('Content-Version: ' . $uu);
         if ($uu = @$data["lastmodified"]) @header('Last-Modified: ' . gmstrftime($ewiki_t["C"]["DATE"], $uu));
      }

このように変更してみて下さい(あとで元に戻すのを忘れないように!).その上で,どのWikiでも結構ですので表示すると(トップページは別かも知れません),全てのページが$uuaに指定したファイル名でダウンロードされる(=ダイアログボックスが表示される)現象を体験できます.色々と$uuaのファイル名を変えてみて下さい.

 この現象が日本版IEのみの問題なのか,それとも英語版WindowsのIEでも発生するのか興味のあるところです.もし自由に試すことのできるMoodleサイトと英語版Windowsをお持ちの方がいましたらお試し下さい.その上でバグ報告を頂ければ,Using Moodleへ報告します(IEのバグですが).

1997年の頃の写真です
Re: eWikiでページ名に"attachment"を含むとページがダウンロードされてしまう
Translators

別解として

urlencode($uu)



urlencode(egegi_replace("attachment", "%61ttachment", $uu))

にするとか。

こちらも検証してみました.IE8限定ですので,逆にFirefoxなどで副作用が出るかも知れませんが,それはまた後日に.egegi->eregiとしまして^^).なるほど,素晴らしい.うまく画面が表示されました.ただ,これですと%61がそのままファイル名に含まれてしまいます(filenameパラメータが正しく渡されたかどうかを確認するために,inlineを意図的にattachmentに変更して確認).

順番を入れ替えて,

eregi_replace("attachment", "%61ttachment", urlencode($uu))

で,一応,OKでした(日本語は確認していません).なお,このままですと常に小文字のattachmentに置換されてしまうので,大文字小文字を無視してattachmentが含まれたら頭一文字を%61に変える,といったcallback関数?を使うように改良すればIEの尻拭いはできそうですね!

 なお,MSDNで得た情報にしたがって確認したところ,inlineにfilenameのパラメータをつけることは,FirefoxとSafariにおいては意味がありそうです.出力されたWikiのページをFirefox等ではマウスの右クリックでファイルに保存することができます.その際に,filenameで指定されたファイル名が採用されます.IEですと,そのページ全体を保存することはできても,Wikiのページ部分のみを保存することはできませんでした(右クリックに選択肢が現れない).ですので,「IEの場合はこのヘッダーを送ってあげない」が現状ではバランスの良い改善だと思います.ただ,挙動に興味はありますので時間ができ次第,実験は続けます.