Python CGI脚本IOError Broken Pipe

时间:2009-11-25 16:51:19

标签: python cgi gnupg

我有一个旧的基于Python的Web表单,我正在更新以使用GPG进行加密而不是不再支持的python包。当通过命令行调用脚本时它工作正常,但是通过Web浏览器和CGI会出现错误: IOError:[Errno 32]管道损坏。如果我使用gnupg包或者尝试通过子进程直接与gpg通信,则会发生此错误。

版本:

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中的管道?

2 个答案:

答案 0 :(得分:2)

我知道我的答案可能来得太晚,但我最近遇到了同样的问题,我想我可以解决它。

GPG似乎输出了一些东西(“你需要一个密码”blabla)到终端,无论stdout被重定向 - 不要问我怎么做:)

但是,破管似乎是因为gpg无法在cgi环境中输出这些消息(uwsgi发生在我身上)。如果--quiet通过,它甚至会打印出来。如果你另外通过--batch,它似乎真的很安静。

答案 1 :(得分:0)

好问题 - 我不确定它是python-gnupg问题还是gpg问题。这可能是subprocesscgi的问题或两者之间的某些互动。如果您使用非常小的脚本从stdin读取并将输出写入文件,会发生什么?这有用吗?

如果有的话,还可以启用日志记录以查看引发的内容。有关如何执行此操作的示例,请参阅test_gnupg.py脚本。