Python3 CGI HTTPS 服务器在 Unix 上失败

标签 python linux ubuntu ssl cgi

这个 Python3 CGI HTTPS 服务器曾经在几周(或几个月)前工作,但现在在 Linux (Ubuntu) 下不再工作。我在 Ubuntu 10.04 和 Ubuntu 14.04 上试过,行为是一样的。

现在,当我尝试访问我得到的任何 CGI 脚本时:

Secure Connection Failed

An error occurred during a connection to 127.0.0.1:4443. SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long) 

服务器代码如下:

import http.server
import ssl
import os

server_address = ('', 4443)
cert = os.path.abspath('./server.pem')

handler = http.server.CGIHTTPRequestHandler
handler.cgi_directories = ['/cgi-bin']

httpd = http.server.HTTPServer(server_address, handler)
httpd.socket = ssl.wrap_socket(httpd.socket, server_side=True, 
                                certfile=cert)

print ("Server started...")
httpd.serve_forever()

服务器记录以下错误:

File "/usr/lib/python3.4/ssl.py", line 618, in read
v = self._sslobj.read(len, buffer)
ssl.SSLError: [SSL: SSLV3_ALERT_UNEXPECTED_MESSAGE] sslv3 alert unexpected message (_ssl.c:1767)

如果我禁用 SSL 并且在带有 SSL 的 Windows 上工作正常,这会起作用。使用 Python 3.4 测试。 奇怪的是,这在几个月前就奏效了 谁能让这个脚本(或任何 python3 CGI HTTPS 服务器)在更新的 Linux 系统上运行?

最佳答案

我在以下位置找到了答案:
http://www.castro.aus.net/~maurice/OddsAndEnds/blog/files/d2baf24c48b972f18836cac7a27734e2-35.html

解决方案是添加:

http.server.CGIHTTPRequestHandler.have_fork=False # Force the use of a subprocess

在启动服务器之前。

这是 Mac 和 Unix 实现所必需的,因为出于效率原因,它们使用 fork 来启动执行 CGI 的进程,而不是创建其他实现(即 Windows)所使用的子进程。在非包装的 CGI 实现中,fork 工作正常并且输出被正确发送到套接字,但是,当套接字是 SSL 包装时,事情就会变得非常错误。

解决方案是强制 Unix 和 Mac 实现使用一个子进程,让 SSL 套接字愉快地工作,并让 Python 服务器将 CGI 脚本的输出传输到客户端,同时将输出转换为 SSL。

我仍然不知道为什么这曾经有效!

关于Python3 CGI HTTPS 服务器在 Unix 上失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27303343/

相关文章:

python - Django:使用 form=MyForm(instance=MyID) 更新现有记录不起作用

linux - 如何grep多个匹配一行?

python textblob和文本分类

python - setItemDelegateForColumn() 在没有堆栈跟踪的情况下使应用程序崩溃

c - 使用 dup2 和 execv 在 C 中获取文件夹内容

c++ - 为什么我在尝试此 OpenGL 教程时得到 "r300 FP: Compiler Error:"?

linux - 安装 NPM 和 NodeJS 的正确方法是什么?

python - Python 在 Mac OS X 10.8 和 Ubuntu 10.04 上表现不同的tell()

python - 如何在 Python 中并行化列表元素

linux - 如何在 Ubuntu 12.04 中更改 Jenkins 安装的端口号