2014-12-04 45 views
1

這個Python3 CGI HTTPS服務器過去幾周(或幾個月)才工作,但現在不再適用於Linux(Ubuntu)。我在Ubuntu 10.04和Ubuntu 14.04上試過,行爲是一樣的。Unix3上的Python3 CGI HTTPS服務器失敗

現在,當我嘗試訪問任何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() 

服務器記錄以下錯誤:

​​

如果我禁用SSL,並且在使用SSL的Windows上正常工作,這將起作用。用Python 3.4測試。 奇怪的是,這個工作幾個月後 任何人都可以得到這個腳本(或任何python3 CGI HTTPS服務器)在更新的Linux系統上運行?

+0

我在Linux上發現了與Python 2.7相同的問題,所以這對Python 3來說並不是孤立的。 – Alecz 2014-12-04 20:45:53

回答

2

我找到了答案在:
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。

我仍然不知道爲什麼這用於工作!

1

雖然OP找到了解決辦法已經,這裏有一些細節,爲什麼它的行爲這樣:

  • 普通插座是內核而已,但sslwraped插座把一個額外的用戶空間層之上。
  • http.server在最後執行cgi程序之前做了一個fork(在支持fork的平臺上,不在windows上)並將文件描述符重新映射到stdin/stdout。通過這種方式,執行的程序在普通(僅內核,無ssl)文件描述符上工作
  • 程序的所有寫入操作都直接進入內核套接字,即純粹未加密的數據。
  • 由於它期望SSL幀,對等方會抨擊這些普通數據。它產生的錯誤類型取決於它獲得的數據,例如, ssl_error_rx_record_too_long或「錯誤的版本號」或類似的東西。