ファイルのアップロードで改行コードが付加される?

ファイルのアップロードで改行コードが付加される?

by Tomohiro Tanikawa -
Number of replies: 30

いつもお世話になっております。

さて、例のごとくトラブルに見舞われてしまいましたので、是非皆様方のお力をお借りできればと思います。要約すると以下のようになります。

  • 以前にLinux上で動作させている三重大版Mooldleを1.6.4+→1.9.0へバージョンアップ、画像が表示できなくなったと最近報告を受けた
  • 最新版1.9.2+にアップしても同様の症状、1.6.4+では問題がない
  • 最新版を新規にいれ、jpg、gif、txt、css、pptなど様々なファイルをアップ
  • テキスト系ファイルは表示でき、そのほかは表示できず、あるいは開けず
  • Moodle上でダウンロードし、バイナリエディタで確認したところすべてのファイルの先頭に0Aのコード(改行)付加。テキスト系は1行目に改行がたしかに挿入
  • FTPでアップロードしたところ問題なく表示
  • 別のLinux上の三重大版1.9.0ではとくに問題ない

というような状況です。まとめると

  • 先頭に改行コードがはいるためテキスト以外はダメっぽい
  • 該当サーバの1.9.0以上では問題があり、1.6.4では問題ない
  • 該当サーバ以外の1.9.0では問題ない

となりますが、どこに問題があると考えればよいのかわかりません。もし、このような状況に遭遇され解決なさった方がいらっしゃいましたら、お力をお貸し願えれば幸いです。

環境
CentOS5(問題ないのはFedora8)、Apache2、MySQL5、PHP5、三重大版1.9.2+

Average of ratings: -
In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 一つ確認したいのは,ファイルのアップロードをどのような操作で行なったのか.

  1. ファイルエディタ(と私は勝手に呼んでいる):たとえば[サイト管理]-[フロントページ]-[サイトファイル]のように,画面左端のコラムの中にある機能を使ってアップロードする.
  2. HTMLエディタのリンクの作成で表示されるポップアップウィンドウの”閲覧”で表示されるHTMLエディタのファイルエディタからアップロードする.

分かりにくくてすみません.Moodle上でも,大きく分けて二つのファイルアップロード方法があるということが言いたいのです.最終的には同じメカニズムを使っている可能性もありますが,もしかしたらアップロードする手続きの違いによって現象に違いが現れる可能性があります.

 もし現在,ファイルをアップロードするのに1の方法を用いているならば,2の方法でもアップロードして見てください.もし2の方法でアップロードしているならば1の方法で.


 1の方法の場合,files/index.phpが action='upload'で呼ばれます.呼ばれた側では,

    switch ($action) {

        case "upload":
            html_header($course, $wdir);
            require_once($CFG->dirroot.'/lib/uploadlib.php');

            if ($save and confirm_sesskey()) {
                $course->maxbytes = 0;  // We are ignoring course limits
                $um = new upload_manager('userfile',false,false,$course,false,0);
                $dir = "$basedir$wdir";
                if ($um->process_file_uploads($dir)) {
                    notify(get_string('uploadedfile'));
                }
                // um will take care of error reporting.
                displaydir($wdir);
            } else {

 緑で示したヘッダーの出力から,青で示したファイルアップロード用の関数の間で,もし改行コードが送られているならば...とも考えたのですが,HTTP手順でのファイルアップロードはそこまで脆弱なものではない?(エンコードされている?)

 process_file_uploads()はlib/uploadlib.php中にあります.

    function process_file_uploads($destination) {
        if ($this->preprocess_files()) {
            return $this->save_files($destination);
        }
        return false;
    }

これだけですね.$destinationはサーバ側のファイルを保存する場所です.function save_files()の中では,基本的にはmove_uploaded_file()を使用して,$destinationにコピーしているだけです.

 中途半端ですが,ソースコードを追っていくと,サーバが違うと挙動が変わる点が見付かるかな?と思ったのですが,いまのところ不発です.なんででしょうねぇ.

In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Haruhiko Okumura -
たまたま今日また最新版をリリースしました。^^;

でも改行コードが付加されるというトラブルは聞いたことがないので,この最新版にアップデートされてもたぶん変化はないと思います。おかしいですね。OSの問題か,それとも問題があるものは1.6.*からアップデートされたということなのでアップデートのときに何か問題が起きたということもあるのでしょうか。
In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 ファイルの送信画面のソースを見て頂いて,その「送信」ボタンのフォームが<form enctype="multipart/form-data" method="post" action="index.php">のようにenctype="multipart/form-data"であるならば,

http://www.kanzaki.com/docs/html/htminfo32.html#enctype

こちらにあるように,MIME形式で送信され,特にバイナリの場合はuuencodeだかBASE64だか(詳しくありません^^;)でエンコードされるのだとすると,改行コードがこの段階で紛れ込むのは難しいでしょうし,紛れ込んだとしても無視されるでしょうからねぇ.


サーバからクライアント側のファイル送信の場合は呆気なくゴミが混入できてしまうことは体験済みですが,クライアントからサーバへのアップロード時に改行コードなどをファイル本体紛れ込ませるのはPHPやHTMLのソースレベルで可能なことなのでしょうか?

#実はバイナリデータもエンコードされずにテキストデータで送られていて,その場合は改行コードが紛れ込むのも技術的には難しくないとか?(すみません,憶測ばかりです)

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 enctype="multipart/form-data"の場合,HTTP手順ではエンコードしない生のままで送られている可能性が高そうですね.メールの場合は7bitで送信される可能性があるのでBASE64を勧めていますが.

http://www.bekkoame.ne.jp/~poetlabo/WWW/rfc2388J.html

ちなみに,改行コードが化けるといった事例は多いようですが,それ以外にもこのようなページも見付かりました.何か参考になりますでしょうか?

http://d.hatena.ne.jp/shimooka/20070208/1170902577

Moodle1.6ではOKで,Moodle1.9ではNGという根拠には結びつきませんが,サーバの違いには関係しそうです.PHPの設定ファイルです.違いがありませんか?

でも,<form></form>で受信しているのですから,Webサーバの側の方が怪しい気がするのですけれどもね.


PHP5.2.0はバグが多いので,アップグレードした方が良いとmoodle.orgのどこかで読んだ気もします.(当方は5.2.0です^^; ただしWindowsXPです)


とりあえずこちらも.

ttp://d.hatena.ne.jp/shimooka/20080526/1211792488

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Mitsuhiro Yoshida -
Picture of Developers Picture of Particularly helpful Moodlers Picture of Translators
> PHP5.2.0はバグが多いので,アップグレードした方が良いとmoodle.orgのどこかで読んだ気もします.(当方は5.2.0です^^; ただしWindowsXPです)

Moodle TrackerにPHP 5.2.0に関する投稿がありますね。笑顔

[Require PHP 5.2.4 instead of 5.2.0 in HEAD]
http://tracker.moodle.org/browse/MDL-15410
In reply to Mitsuhiro Yoshida

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

情報ありがとうございます.

やはり暇を見てアップデートしないと,Moodle2.0には対応できなさそうですね.


PUTメソッドによるファイルのアップロードはPHP側の機能のような気がしてきましたね.

http://loglog.jp/~php/man/features.file-upload.html

しかし頭に1byteだけ改行コードが入るというのも変な話です.Moodle側でそんな器用なことができるものなのでしょうか.やはり正常に動作するサーバと異常な動作をするサーバとで,PHPのバージョンやphp.iniの記述の違いが無いかどうかが気に掛かるところですね.

(Moodle1.6だとOKで,Moodle1.9だとNGの件については回答になりませんね)

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 もう既に試されているかと思いますが,PUTメソッドを使ったシンプルなHTML+PHPによる基礎実験を試して見ませんか?

 もしこのHTMLとPHPのソースでうまくファイルがアップロードできない(頭に改行が入ってしまう)ならばMoodleではなく環境に問題があるということになります.

 upload.phpとtest.htmlは同じディレクトリに置いて下さい.upload.phpの$destはご利用の環境に合わせて修正して下さい.

In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Haruhiko Okumura -
もし可能なら,同じサーバにもう一つMoodeをインストールしてみれば,サーバの問題か,アップデートの際のトラブルかがわかるかもしれませんね。
In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 Moodle1.6ではOKでMoodle1.9ではNGという現象の原因を推定すると,思い付くのはphp.iniで設定されているPHPの設定をMoodleが変更している可能性です.Moodle1.6では変更していないのに,Moodle1.9では書き換えているなど.

 だとしたら,地道に[サイト管理]-[サーバ]-[PHP情報]を,Moodle1.6上とMoodle1.9上で表示し,それを比較するしか無いでしょう.

 では,なぜ別のサーバのMoodle1.9は正常に動作するのか? これはPHPのバージョンが違う可能性が無いでしょうか.php.iniの設定をMoodle上で書き換える際に,PHPのバージョンによって書き換えたり,書き換えなかったりしている可能性もゼロではありません.あるいは書き換えられた設定によって発生するバグが特定のバージョンのPHPにのみ存在する可能性です.

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

http://sb.xrea.com/archive/index.php/t-11379.html

.htaccessのphp_flag output_bufferingなどの設定がMoodle1.6とMoodle1.9のディレクトリとで異なっているという可能性も無くはない?

 いまMoodle1.6が存在していたフォルダの中身をMoodle1.9で上書きした訳ではなく,新たにMoodle1.9のフォルダを作成してそこにMoodle1.9を展開したわけですよね..htaccessの設定か,apacheのhttpd.confのディレクティブの設定が,Moodle1.6のディレクトリとMoodle1.9のディレクトリで異なる,という可能性です.

In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Tomohiro Tanikawa -
皆様、いろいろとご助言ありがとうございました。
確認事項については以下のようになります。
  • ファイルのアップロードは各コースにあるファイルメニューか、トップのサイトファイル
  • CentOS,Fedora上のPHPのバージョンはどちらも5.2.4
  • アップグレードではなく、1.9.2+新規でも状況は変わらず
で早速、白井先生のアップロードプログラムを試して見ました。アップ先はMooldeのデータフォルダ内のコースIDに変更しました。
  • Moodleのファイルからアップロードされていることは確認できる
  • クリックして表示してみると、はやり表示されない
その後FTPクライアントでアップロードしたファイルを確認するとともに追加でいくつか確認してみました。
  • Moodle、FTPクライアント、白井先生プログラムでアップした同一画像ファイルのサイズは一致
  • Moodle上でクリックして表示してみるが、IEでは赤い×マーク、Firefoxではjpgは画像のパスが、gifは壊れているため表示できない旨のメッセージ表示
  • FTPクライアントでどれをダウンロードしても0Aは付加されない
  • ブラウザ(IE,Firefox)で右クリックからファイルを保存すると0Aが付加
という結果になりました。
つまりはアップロード時点では問題なく、表示、あるいはダウンロード時に問題発生ということでしょうか。
引き続きphp設定ファイルあたりを比較してみたいと思います。
In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Haruhiko Okumura -
不思議ですね。php.iniをまったく同じにしたらどうなるか気になるところです。

Moodleソースのサーバへのアップロード時に行末が化けるなんてこともありえないですよね。
In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

なるほど,ではPUTメソッドによるアップロード自体には問題は無さそうだということですね.<FORM>によるPUTのメソッドは自動化されているのでMoodleのソースレベルでは悪いことは何もできないので不思議でした.ですのでMoodle上でfile.phpを介して表示またはダウンロードした際に改行文字が1文字だけ頭に付く方が理解はし易いです.

 でもMoodle1.9かMoodle1.6か,ではなく,同じMoodle1.9.2+でもサーバによって異なるという点は気になります.正常なサーバはhttpであり,正常でないサーバはフルhttpsである,といった違いがあったりはしませんか?

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 file.phpを介してファイルをダウンロードしている場合で,なぜ頭に改行文字が一文字だけ送られるのか,について少しだけ考えます.あくまで可能性の検討です.

 ファイルの送信は,file.phpが入口になりますが,実際にはlib/filelib.phpのfunction send_file()がヘッダーおよびファイル本体を送信します.

 まずフィルタを使うかどうかで処理が大きく二つに分けられています.主にテキストファイルのための手続きでしょう.テキストファイルはHTMLか否かで処理が分けられていますが.それ以外のMIMEタイプのファイルはfunction readfile_chunkced()で一定サイズごとにファイルを読み出しては送出します.さて,どの形式にしても共通しているのが,ヘッダーの送出後に,

        } else {    // Just send it out raw
            @header('Content-Length: '.$filesize);
            @header('Content-Type: '.$mimetype);
            while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
            if ($pathisstring) {
                echo $path;
            }else {
                readfile_chunked($path);
            }
        }

このようにob_start()で出力を抑制していたバッファを吐き出させます.ob_start()による出力のバッファは入れ子状にできるので,このようにwhile()で全て吐き出させているのでしょう.

 ヘッダーを送出後に,出力を抑制していたバッファを吐き出す? これがムチャクチャ怪しくないですか? テキストデータの場合ならばいざしらず,バイナリデータの場合はヘッダーの後は直ぐに生のデータを送出しないといけないでしょう.もしob_start()で標準出力の送出が抑制されていたとして,どこかで改行コードを誤って出力していたとします.その文字はこのタイミングでクライアントPCへ送り出されるでしょう.生のデータが送られる直前に.つまりファイルの頭に改行文字が追加されてしまうメカニズムとしては,かなり怪しい候補です.

 試しに上に示した箇所の@ob_end_fhush()を@ob_end_clean()に変えて試してみて頂けませんか? バイナリデータの頭に改行が付いてしまうのを抑止できる可能性があります.そもそもなんでここがob_end_flush()なのか私には理解できません.

#テキストファイルにはテキストファイルなりの事情があるのかも知れませんので,現状ではob_end_clean()に変えない方が良いでしょう.

もしこれで症状が治まるならば,次は”誰が改行コードを出力したか”ですね.


 function send_file()がfile.phpから呼ばれた場合,パッと見た感じではob_start()している箇所は見当たりませんでした.いっそのこと,(これこそ本当に一時的にですが)

//          while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite

このようにコメントアウトした方が実験としては効果的です.ob_start()していないのにob_end_flush()すると改行コードが送られるというバグ(仮定です)があったとしたら,ob_end_clean()も安全とは言い切れませんので.なお,コメントアウトした場合,もし私の見落として,実際にはob_start()が行なわれたとするとファイルの送信自体が始まらないでしょう.また,file.phpを介さずにsend_file()が呼ばれる場合もあります.その際に副作用が発生するかも知れませんので,あくまで原因究明のための実験という点をよく理解して試して下さい.

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

示す場所を間違えました.あれはフィルタありの場合です.

フィルタなしの場合でしょうから,

     if (empty($filter)) {

のブロックの中の最後の方,

         @header('Content-Length: '.$filesize);
        while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
        if ($pathisstring) {
            echo $path;
        } else {
            readfile_chunked($path);
        }
    } else {     // Try to put the file through filters

こちらです.このreadfile_chunked($path)がバイナリデータを送信する箇所です.試しにこのreadfile_chunked()をコメントアウトするか,echo 'ここ!'; などを追加してここで正しいことを確認してから,その上のob_end_flush()をob_end_clean()に変えてみたり,// while(... のようにコメントアウトして見て下さい.

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tomohiro Tanikawa -
ひきつづきありがとうございました。

まずphp.iniについて確認しました。数値的なものはサーバのスペックに合わせて設定してあるかもしれませんのでそのままに、オンオフレベルのものについては大体同じ状態にして試してみましたが、特に変化はありませんでした。三重大版を利用させていただくときは、直接サーバにダウンロードして展開しますし、ソースも直接サーバ上で修正なども行なっていますので、途中でなにか起こることは考えにくいですね。
白井先生のsend_file()中のwhile (@ob_end_flush())のコメントアウトも試してみたのですが、とくに変化ありませんでした。
で、ひとまずは利用できないと困りますので、1.6に戻しました。問題なく画像も表示されるようにはなりました。ただ、このままでは将来的にアップグレードができないということになりますので引き続き調べてみたいと思います。

ちなみに問題のでるサーバ、問題のないサーバともに常時httpsで動作しております。
In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Haruhiko Okumura -
そうですね。問題が起きたらまずは元に戻すのがいいと思います。

あとは,最新の三重大版と,最新のオリジナル版を同時にインストールして,違いがあるかどうか調べることとか,いろいろ原因の切り分け法はあると思いますので,何かわかりましたらお知らせください。
In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tomohiro Tanikawa -

本家版をインストールして確認してみようかと思っておりましたが、Window Serverのほうで利用させていただいております白井先生のfs_moodle最新版を試しにいれてみました。

新規にインストールした場合と1.6.5のDBをアップグレードした場合の2つを試してみました。結論から申し上げあげますと、画像ファイルが問題なく見れるようになりました。画像ファイルをダウンロードしてみましたが、0Aコードが入ることもなくなりました。

サーバ自体の変更はphp.iniを問題のないサーバのものに合わせた程度です。現在問題が生じるサーバには奥村先生の三重大版と白井先生のfs_moodleの双方が稼働しておりますが、三重大版のほうではやはり画像が見えていません。

ひとまず当面の問題は解決しましたが、次に本家版をいれて確認してみようと思います。


本家の最新版を新規にいれたもので確認してみました。

サイトファイルから画像をアップロードして表示させてみましたが、ダメでした。ダウンロードするとやはり先頭に0Aコードが付加されていました。

白井先生の行なわれた修正がどこかで効いているということでしょうか。

ちなみに1.6.5からのアップグレードで別の問題が発生していることが発見されました。解決できない場合には、また別トピックとして質問させていただこう思います。


In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

>白井先生の行なわれた修正がどこかで効いているということでしょうか。

 ファイル名の関係はかなり修正を行ないましたが,ファイルの中身(特にバイナリ)をどうこうする部分はほとんど触っていないですねぇ.ただやはり気になるのはhttpsですね.https関係はそれこそ何も(課題の一括ダウンロードに関するローカルな関数の修正を除いて)なにも行なっていませんから一層心当たりはないのですが,皆さんの環境と比較的異なる点はフルhttpsであるという点ですので.

 試しにローカルなLAN環境で,httpsではなくhttpで本家・三重大版を試してみることはできませんか?

 あと確認ですが,フォルダ名やファイル名に日本語は使っていないですよね? これも無関係だとは思うのですが,ほんの少しだけ気になりました.


 function send_file() in lib/filelib.phpでは,確かにヘッダーを出力する箇所に少しだけ手を入れています.でも,副作用が出ないように気を付けて同じ挙動になるようにしたつもりです.テキストファイルを送出する際に,元のファイルがシフトJISかUTF-8かを判断して,

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

もう一つ重要なことを忘れていました.

 ヘッダーの前に改行文字が送られる場合があります.
 それはinclude()やrequire()したファイルに余計な改行がある場合です!

 <?php と ?>の間に含まれるコードはPHPのプログラムと解釈されるのでいくら改行があっても良いのですが,この外側にある文字(改行含む)はそのままサーバからクライアントに(HTMLソースコード同様に)送信されてしまいます.よくある問題は,config.phpの最後の行に(親切心から?)改行コードを追加してしまう場合です!

?>の後も改行は入れてはいけません.(添付した図の通り) もしかして,無意識のうちに「気持ち悪い!」(私はそう思うタイプ)と考えて改行を入れていませんか?

 本来ですと,”ヘッダーの前に文字を出力したらワーニング”なのですが,PHPの設定か,Moodleの設定で,ワーニングも含めてエラーメッセージを一切表示しない設定になっていると,警告の文字列は出力されず,改行文字だけが出力されると思います.

 これ,ビンゴではないですか?
 フルhttpsを使われていることから,かなりセキュリティを重視されているのではないでしょうか.ですのでサイトの情報が漏れる恐れのある警告は一切出力しない設定になっていると予想されます(私のサイトはfs_moodle開発も兼用するという野蛮な状態ですのでDEVELOPER,全てエラーを出力します).

Attachment configphp.jpg
In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 実験してみました.改行1個を?>の後に追加しただけならば特に問題は発生しませんでした.改行を2個(つまり28行目が空行)にすると,JPEG画像を表示したところ生データがそのまま画面にダーッと表示されました.名前を付けて保存したところ,頭に改行コードが入っていることを確認できました.ただし,デフォルトのファイル名は拡張子が.htm(IE7の場合)です.ヘッダーが送られず,JPEG画像だと認識できなかったのでしょう.

 微妙に現象は違ってしまいました.でも,この手の問題の可能性が高いです.

 もしサーバのデバッグの”デバッグ情報”を"NONE"に設定しているのならば,試しにNORMALでも結構ですので,変更してみては如何でしょう?

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Haruhiko Okumura -
今のPHPは改行だけの場合は無視するようにできているはずです:

<?php
echo "hoge"
?>
hoge

でもこれが何らかの理由でうまくいっていないか,改行コードが違うといったことがあるのかもしれません。

あ,微妙に先を越されてしまいました。改行が二つ入ったのかもしれませんね。
In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

先を越しましたウインク.

>今のPHPは改行だけの場合は無視するようにできているはずです:

確かに,改行1つだけならば問題なかったです.これは私の間違いでした.

ついでに.
「28行目が空行」と書きましたが「29行目が空行」の間違いです.

In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 実は意外とポピュラーなFAQですよね.

 Moodle本家の方に,config.phpの <?php の前と ?>の後に余計な文字が一切存在しないことを確認する機能の実装を要望した方が良いかも知れませんね.

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tomohiro Tanikawa -

白井先生

返信が遅くなり申し訳ございません。

早速config.phpの末尾を確認してみたところ「?>」のあとに1行ほど空行が空いていることが確認できました。問題のないサーバのconfig.php、問題のでたサーバのfs_moodleのconfig.phpについては空行が見あたりませんでした。

その空行を除去したところ問題なく画像が表示されることが確認できました。今回もこちらの単純な記述ミスにより多大なるお時間を頂くようになってしまいました。申し訳ございません。

白井先生がおっしゃるようにそのあたりの記述のチェック機能があるとよいのかもしれませんね。

現在は旧バージョンですが、折を見て最新バージョンにアップしたいと思います。白井先生、奥村先生、吉田様、お力添えありがとうございました。

In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Haruhiko Okumura -
やっぱ,そうでしたか!
それにしても,白井先生の推理力はすごい!
当然といえば当然なのですが,確かにうちの学生たちも,スクリプトにBOM付けちゃって動かない動かないと言っているのがいます(Windowsのメモ帳が悪いのですが)。
In reply to Haruhiko Okumura

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

いやぁ,良かった,良かった!

#半端な推理小説よりスリリングですね.

 設定関係のトラブルは多いですよね.
 実は今日も,本校のMoodleで,シフトJIS形式の小テストをロードした際に,自動的にUTF-8に変換する機能が正常に働かない,という問い合わせがありました.結論としては,サーバのmbstring関係の設定が一切行われていなかった(全てコメントアウト)というオチでした.うーむ,いままでよく問題なく動いていた.mb_convert_encoding($string, 'UTF-8', 'auto')が全てエラーを発生していたはずなのに.($stringがシフトJISの場合)

 こういう小さなトラブルが発生するたびに,fs_moodleの動作環境チェック用のメニュー([サイト管理]-[サーバ]に[fs_moodleの設定表示]という項目を追加)でチェックを行なえるようにしています.少しずつスキルがこのコードに蓄積されていきます.

Attachment config_check.jpg
In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 とりあえず,以下のような関数を作ることで,config.php(とfsconfig.phpの)頭とお尻のゴミのチェックができるようになりました.

function check_config_head_and_tail($configpath)
{
    if (!file_exists($configpath))       return false;
    if (!($farray = file($configpath)))  return false;
    // チェック
    if (strncmp($farray[0], "<?php", 5) != 0)               return false;
    $tail = rtrim($farray[count($farray) - 1], "\n");
    $tail = rtrim($tail, "\r");
    $tail = rtrim($tail, "\n");
    if ($tail != "?>") return false;
    return true;
}

rtrim()で行末の改行コードを取り除いている部分ですが,改行コードがCR+LF, CR, LFの全てに対応しようとしたらこうなりました.少なくともWindows版PHPはfile()関数で配列に読み込んだテキストファイルの末尾に改行コードが残っています.これを取り除いています.正規表現を使うべきなのかも知れませんが...

In reply to Tatsuya Shirai

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

>テキスト系ファイルは表示でき、そのほかは表示できず、あるいは開けず

もしかして,そのほか(JPEG画像など)が表示できない,という現象は添付した図のような状態ですか?

 config.phpの?> 後に完全な空行を入れると,ユーザ画像(アイコン)は「×」になりました.

どうでしょう,現象は一致しています?

Attachment brokenjpeg.jpg
In reply to Tomohiro Tanikawa

Re: ファイルのアップロードで改行コードが付加される?

by Tatsuya Shirai -

 ob_end_flush()の件ですが,手元で試してみたところ,やはりob_start()が行なわれていないせいでしょう,function send_file()の頭のところで,echo "\n"; を実行すると「ヘッダーの前に余計なデータを出力するな!」というワーニングが出力されます(ダウンロードされるファイルの頭に!).

 ただ,不思議なことに

        @header('Content-Type: '.$mimetype);
        @header('Content-Length: '.$filesize);
        while (@ob_end_flush()); //flush the buffers - save memory and disable sid rewrite
        readfile_chunked($path);

(見やすくするために余計なif文等を取り除いてあります)"Content-Type"を出力する前にecho "\n";を実行するとワーニングが出ますが,"Content-Type"を出力した後ならば"Content-Length"の前であってもワーニングは発生しません.つまり,

        @header('Content-Type: '.$mimetype);

        readfile_chunked($path);

の間ならばどこでもecho "\n";を出力して,Tanikawaさんの仰るような現象を再現することができます.でも,function readfile_chunked()も含め,どこにも"\n"を出力しそうな場所が見当たらないので,PHPに何かバグでも無い限りは今回のような問題は発生しなさそうです.やはり不思議だ.

#ちなみに,IEで実験する場合は,その度ごとに”インターネット一時ファイル”を削除する必要があります.動的なWebページなのに.

 なにはともあれ,お暇なときに色々と差異を調べるなどして原因を究明して頂けると助かります.もしかしたらフルhttpsの環境と特定のOS環境の組み合わせで発生する問題かも知れませんので.