8

この質問はこれに関連しています。Python 2 で CGI スクリプトから生のバイナリ データを出力している間、問題はありませんでした。たとえば、次のようになります。

#!/usr/bin/env python2

import os

if __name__ == '__main__':
    with open(os.path.abspath('test.png'), 'rb') as f:
        print "Content-Type: image/png\n"
        print f.read()

関連する応答ヘッダーは次のとおりです。

> GET /cgi-bin/plot_string2.py HTTP/1.1
> User-Agent: curl/7.32.0
> Host: 0.0.0.0:8888
> Accept: */*
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 Script output follows
< Server: SimpleHTTP/0.6 Python/3.3.2
< Date: Fri, 13 Sep 2013 16:21:25 GMT
< Content-Type: image/png

期待どおり、結果は画像として解釈されます。ただし、Python 3 に変換しようとすると、次のようになります。

#!/usr/bin/env python

import os
import sys

if __name__ == '__main__':
    with open(os.path.abspath('test.png'), 'rb') as f:
        print("Content-Type: image/png\n")
        sys.stdout.buffer.write(f.read())

何も返されません。ヘッダーは次のとおりです。

> GET /cgi-bin/plot_string3.py HTTP/1.1
> User-Agent: curl/7.32.0
> Host: 0.0.0.0:8888
> Accept: */*
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 Script output follows
< Server: SimpleHTTP/0.6 Python/3.3.2
< Date: Fri, 13 Sep 2013 16:22:13 GMT
< �PNG
< 

print(f.read())のようなものが出力されるため、もうできませんb'\x89PNG\r\n\x1a\n\x00...。私がリンクした質問は解決策を提供しますが、明らかにこの環境では機能しません。

考え?

追加将来のための注意

これはまたprint、もはや CGI には適していないことを意味します。

4

1 に答える 1

19

sys.stdout.flush本文の前にヘッダーを強制的に印刷するために使用します。

import os
import sys

if __name__ == '__main__':
    with open(os.path.abspath('test.png'), 'rb') as f:
        print("Content-Type: image/png\n")
        sys.stdout.flush() # <---
        sys.stdout.buffer.write(f.read())

または、印刷を削除して、次のものsys.stdout.buffer.writeのみを使用します。

import os
import sys

if __name__ == '__main__':
    with open(os.path.abspath('test.png'), 'rb') as f:
        sys.stdout.buffer.write(b"Content-Type: image/png\n\n") # <---
        sys.stdout.buffer.write(f.read())

ノート

f.read()ファイルが巨大な場合、問題が発生する可能性があります。それを防ぐには、次を使用しますshutil.copyfileobj

import os
import shutil
import sys

if __name__ == '__main__':
    with open(os.path.abspath('test.png'), 'rb') as f:
        sys.stdout.buffer.write(b"Content-Type: image/png\n\n")
        shutil.copyfileobj(f, sys.stdout.buffer)
于 2013-09-13T16:41:12.610 に答える