2009-11-25 53 views
2

我有一箇舊的基於Python的Web窗體,我正在更新使用GPG進行加密,而不是不再支持的Python包。當通過命令行調用腳本時,它工作得很好,但是通過Web瀏覽器和CGI,出現錯誤:IOError:[Errno 32]損壞的管道。如果我使用gnupg軟件包,或者如果我嘗試通過子進程直接與gpg對話,則會發生此錯誤。Python的CGI腳本IOError斷開的管道

版本:

Python 2.4.1 
gnupg 0.2.2 (python GPG wrapper) 
Apache/2.2.9 
gpg 1.4.9 

下面是一個簡化的腳本:

#!/usr/bin/python 

import sys 
# send python tracebacks out to the web browser 
sys.stderr = sys.stdout 
import gnupg 
gpg = gnupg.GPG() 
gpgkey = 'np' 
message = 'Our secret message!' 
print "Content-type: text/html\r\n" 
print '''<html><head><title>Test GPG access via cgi</title> 
      </head><body><pre>''' 
print 'message in the clear:' 
print message 
encrypted = str(gpg.encrypt(message, 'np')) 
print 'message encrypted:' 
print encrypted 
print '''</pre></body></html>'''sf 

當上述腳本經由命令行調用,它運行得很好,但是當通過CGI調用它生成的以下錯誤:

message in the clear: 
Our secret message! 
Traceback (most recent call last): 
    File "/home/dkmaster/www/nickads/secure-cgi/gpgtest.py", line 23, in 
    encrypted = str(gpg.encrypt(message, 'np')) 
    File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 517, in encrypt 
    return self.encrypt_file(StringIO(data), recipients, **kwargs) 
    File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 467, in encrypt_file 
    self._handle_io(args, file, result, passphrase=passphrase) 
    File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 201, in _handle_io 
    _copy_data(file, stdin) 
    File "/home/dkmaster/www/nickads/secure-cgi/gnupg.py", line 75, in _copy_data 
    outstream.write(data) 
IOError: [Errno 32] Broken pipe 

我也試圖說服直接通過子,而不是GPG gnupg模塊。

#!/usr/bin/python 

import sys 
import subprocess 
sys.stderr = sys.stdout 
print "Content-type: text/html\r\n" 
print '''<html><head><title>Test subprocess via cgi</title> 
      </head><body><pre>''' 

plain_text = 'the quick fox ' * 10 
print plain_text 
gpgCommand = "/usr/bin/gpg --quiet -a -e -r 'np' " 
gpgProcess = subprocess.Popen(
         gpgCommand, 
         stdin=subprocess.PIPE, 
         stdout=subprocess.PIPE, 
         stderr=subprocess.PIPE, 
         shell=True 
        ) 
encrypted_text = gpgProcess.communicate(plain_text)[0] 
print encrypted_text 

同樣能正常工作的命令行,而不是通過CGI生成一個類似的錯誤:

Traceback (most recent call last): 
    File "/home/dkmaster/www/nickads/secure-cgi/subprocesstest.py", line 20, in 
    encrypted_text = gpgProcess.communicate(plain_text)[0] 
    File "/usr/lib/python2.5/subprocess.py", line 670, in communicate 
    return self._communicate(input) 
    File "/usr/lib/python2.5/subprocess.py", line 1220, in _communicate 
    bytes_written = self._write_no_intr(self.stdin.fileno(), buffer(input, input_offset, 512)) 
    File "/usr/lib/python2.5/subprocess.py", line 999, in _write_no_intr 
    return os.write(fd, s) 
OSError: [Errno 32] Broken pipe 

那麼,如何解決在CGI管道?

回答

0

好問題 - 我不確定它是python-gnupg問題還是gpg問題。這可能是subprocesscgi或兩者之間的一些相互作用的問題。如果使用從stdin讀取並將輸出寫入文件的非常小的腳本嘗試此操作,會發生什麼情況?那樣有用嗎?

它也值得啓用日誌記錄來查看拋出什麼,如果有的話。有關如何執行此操作的示例,請參閱test_gnupg.py腳本。

1

我知道我的答案可能來得太晚,但我最近有同樣的問題,我想我可以解決它。

GPG似乎輸出一些東西(「你需要一個密碼」布拉布拉)到終端,無論被重定向標準輸出 - 不要問我怎麼:)

然而,破裂的管道似乎發生,因爲GPG不能在cgi環境中輸出這些消息(使用uwsgi發生)。它甚至打印出來,如果--quiet通過。如果您另外通過--batch,它似乎真的很安靜。