Python CGI 脚本 IOError Broken Pipe
我有一个旧的基于 Python 的 Web 表单,我正在更新它以使用 GPG 进行加密,而不是不再支持的 python 包。当通过命令行调用脚本时,它工作得很好,但通过网络浏览器和 CGI 会出现错误:IOError: [Errno 32] Broken pipeline。如果我使用 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
我还尝试通过子进程而不是 gnupg 模块直接与 GPG 对话。
#!/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 中的管道?
I have an old Python based web form that I am updating to use a GPG for encyption instead of a no longer supported python package. When call the script via the command line it works just fine, but via the web brower and CGI there is a error: IOError: [Errno 32] Broken pipe. This error occurs if I use the gnupg package or if I try to talk to gpg directly via subprocess.
Versions:
Python 2.4.1
gnupg 0.2.2 (python GPG wrapper)
Apache/2.2.9
gpg 1.4.9
Here is a simplified script:
#!/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
When the the above script is called via the command line, it runs just fine but when called via CGI it generates the following errors:
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
I also tried to talk to GPG directly via subprocess and not the gnupg module.
#!/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
Again this works fine from the command line, but not via CGI which generates a similar error:
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
So how do I fix the pipes in CGI?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我知道我的答案可能来得太晚了,但我最近遇到了同样的问题,我想我可以解决它。
GPG 似乎会向终端输出一些内容(“你需要密码”blabla),无论 stdout 是否被重定向 - 不要问我如何:)
但是,管道损坏似乎是因为 gpg 无法在 a 中输出这些消息而发生的。 cgi环境(对于我来说是uwsgi)。如果通过了
--quiet
,它甚至会将它们打印出来。只有当你另外传递--batch
时,它才会显得非常安静。I know my answer might come too late, but I recently had the same problem and I think I could solve it.
GPG seems to output some stuff ("You need a passphrase" blabla) to the terminal regardless of stdout being redirected - don't ask me how :)
However, the Broken Pipe seems to occur because gpg can't output these messages in a cgi environment (happens for me with uwsgi). It even prints them out if
--quiet
was passed. It only seems to be really really quiet if you pass--batch
additionally.好问题 - 我不确定这是
python-gnupg
问题还是gpg
问题。这可能是subprocess
或cgi
或两者之间的某些交互的问题。如果您使用一个非常小的脚本来尝试此操作,该脚本从 stdin 读取并将输出写入文件,会发生什么?那有用吗?还值得启用日志记录以查看抛出的内容(如果有的话)。有关如何执行此操作的示例,请参阅
test_gnupg.py
脚本。Good question - I'm not sure that it's either a
python-gnupg
issue or even agpg
issue. It might be an issue withsubprocess
orcgi
or some interaction between the two. What happens if you try this with a very minimal script which reads from stdin and writes the output to a file? Does that work?It's also worth enabling logging to see what that throws up, if anything. See the
test_gnupg.py
script for an example on how to do that.