WindowsでCGIスクリプトを書くと何かが変だ

結論から言うと、以下のような症状が出る場合について。

  • cgi.FieldStorageを使うと固まる
  • cgi.FieldStorageのformdataからデータの一部しか取得できない

ソースコードに以下を追加すると直るかもしれません。

try:
  import msvcrt
except ImportError:
  pass
else:
  for fd in (0, 1):
    msvcrt.setmode(fd, os.O_BINARY)

経緯

あるプログラムのプロトタイプを書いていた。実行環境はどこでもよかったのだが、Windows上で作業していたので、テストもWindowsですることにした。しばらくすると何かがおかしいことに気付く。どうもファイルが正常に送れていないようだ。何でだろうと、あちこち弄るが原因が分からない。cgiライブラリのソースを読むのは面倒くさい。だから先にサーバ側の問題が確かめるため、他の簡易ウェブサーバ(04WebServer)に切り替えてみる。ここで上手くいけば、使っているAN HTTPDの問題だ。結果、序盤の簡単なコードは上手く行っているように見えるが、本番のプロトタイプが固まってレスポンスが帰ってこない。面倒くさいことに、どうもPython側に問題がありそうだ。

しばらく、あーでもないこーでもないと考えていると、「POST→STDINから読む→Windowsは\r\nの変換をする→(!)→この流れ最近どこかで見たぞ」ということで、次のスレッドを思い出す。

http://pc11.2ch.net/test/read.cgi/tech/1187317688/851-852

851 :デフォルトの名無しさん:2007/10/14(日) 01:56:11
    標準出力で改行コード変換が行われてしまうのを防ぎたいのですが、可能でしょうか。
    WinXP + SP2, python 2.4です。
    import sys
    out = open('hoge.pdf', "rb").read()
    open('hogehoge.pdf', "wb").write(out)
    sys.stdout.write(out)
    などとして
    python del.py > fuga.pdf
    すると、hoge.pdfとhogehoge.pdfはもちろん同一ですが、fuga.pdfには余計なCRが混じります。
    fileではバイナリモードにできたが、stdoutでその方法がわからない、という状況です。
    方法など御存知の方、何卒御教示下さい

852 :デフォルトの名無しさん:2007/10/14(日) 01:57:52
    >>851
    # 標準入出力をバイナリモードに変更(Windowsのみ)
    try:
    import msvcrt
    except ImportError:
    pass
    else:
    for fd in (0, 1):
    msvcrt.setmode(fd, os.O_BINARY)

    これ?

入れてみると、正常に動く。

答えがわかれば、何かおかしかったのかは、すぐにわかる(google:cgi FieldStorage msvcrt)。