回答編集履歴

1 pythonの言語バージョンによる違いを追記

dodox86

dodox86 score 8775

2017/10/01 12:39  投稿

こんにちは。
サーバーがステータス501を返しているので、cgiスクリプトが正しく動作して
いないようです。ご提示のコードですと、何点か問題ありそうでした。
0. 1行目でシバン(Shebang)にてスクリプトが指定されていないので、
pythonスクリプトとして動作できない。
1. 日本語部分があるので、文字コードを指定しないと文字化けの恐れがある。
2. HTTPレスポンスとして返す時のContent-Type が指定されていない。
3. 'html' 変数に初期値が設定(宣言)されていない。未定義変数エラー。
プログラムを造ってサーバーに設置したときは、cgiとしてサーバーに
実行させる前に端末上で文法チェックしてみると良いです。
以下で簡単に文法チェックすることができます。
(もちろん、実行時のエラーはこれでは分かりません)
```
$ python -m py_compile test15.cgi
```
ご提示のコードですが、以下のように直すことで動作しました。
確認用のコードを残していますので、差分を取って比較してみてください。
尚、文字コードはutf-8で保存してください。
```python
```python2
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cgi
import os, sys
try:
   import msvcrt
   msvcrt.setmode(0, os.O_BINARY)
   msvcrt.setmode(1, os.O_BINARY)
except ImportError:
   pass
result = 'DUMMY'
form = cgi.FieldStorage()
if form.has_key('file'):
   item = form['file']
   if item.file:
       fout = file(os.path.join('/tmp', item.filename), 'wb')
       while True:
           chunk = item.file.read(1000000)
           if not chunk:
               break
           fout.write(chunk)
       fout.close()
       #result = 'upload is done'
       result = 'アップロード'
#print html % result
print "Content-Type: text/html"
print
html = "<html><body>%s</body><html>"
print html % result
```
```
###python3に関して追記
python3 でのご質問だったのかもしれませんので、すみませんが以下、追記させていただきます。
参考にされたサイト様のサンプルプロはpython2 のものです。
私が提示したコードもpython2 のものなので、サーバー上でpython3でcgiを
稼動させる場合、文法エラーで動作しません。
コードをpython3でほぼ等価なものに書き直し、動作確認したものを以下に示します。
※「アップロード」の部分はそのままだとエラーになり、
コードが煩雑になるのでASCII文字列に直させてもらいました。
今後pythonでcgiを造られる場合は、バージョンの違いに注意する必要があるかとは思います。
```python3
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import cgi
import os, sys
try:
 import msvcrt
 msvcrt.setmode(0, os.O_BINARY)
 msvcrt.setmode(1, os.O_BINARY)
except ImportError:
 pass
result = 'DUMMY'
form = cgi.FieldStorage()
#if form.has_key('file'):
if 'file' in form:
 item = form['file']
 if item.file:
#   fout = file(os.path.join('/tmp', item.filename), 'wb')
   fout = open(os.path.join('/tmp', item.filename), 'wb')
   while True:
       chunk = item.file.read(1000000)
       if not chunk:
         break
       fout.write(chunk)
       fout.close()
       result = 'upload is done'
       #result = "アップロード"
print("Content-Type: text/html")
print("")
html = "<html><body>{0}</body><html>"
print(html.format(result))
```

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る