2013-07-12 118 views
4

我有一個CGI處理HTTP服務器下面最少的代碼,從幾個例子在內部管導出:Python的CGIHTTPServer默認目錄

#!/usr/bin/env python 

import BaseHTTPServer 
import CGIHTTPServer 
import cgitb; 

cgitb.enable() # Error reporting 

server = BaseHTTPServer.HTTPServer 
handler = CGIHTTPServer.CGIHTTPRequestHandler 
server_address = ("", 8000) 
handler.cgi_directories = [""] 

httpd = server(server_address, handler) 
httpd.serve_forever() 

然而,當我執行腳本,並嘗試使用http://localhost:8000/test.py通過CGI在同一目錄中運行測試腳本,我看到腳本的文本而不是執行結果。

權限全部設置正確,並且測試腳本本身不是問題(因爲我可以在腳本駐留在cgi-bin中時使用python -m CGIHTTPServer正常運行)。我懷疑這個問題與默認的CGI目錄有關。

我怎樣才能讓腳本執行?

+2

感謝您的回答!這幫助我整理了一個我一直想要做的很長時間的Python專用服務器。值得指出的是,規範的「正確的」shebang是「#!/ usr/bin/env python」 - 之前我已經被抓到了! – scubbo

+1

@scubbo - 很高興與此鬥爭可以爲您提供一些清晰。我已經按照你的建議更新了shebang。謝謝! – charleslparker

回答

4

我的懷疑是正確的。從中派生此代碼的示例顯示了將缺省目錄設置爲服務器腳本所在的同一目錄的錯誤方法。要設置默認目錄以這種方式,使用方法:

handler.cgi_directories = ["/"] 

注意:這開闢了潛在的巨大安全漏洞,如果你沒有任何防火牆後面。這只是一個有益的例子。使用時要格外小心。

3

如果.cgi_directories需要多層子目錄(例如['/db/cgi-bin']),該解決方案似乎不起作用(至少對我而言)。子類化服務器並更改is_cgi def似乎工作。下面是我添加/在你的腳本取代什麼:

from CGIHTTPServer import _url_collapse_path 
class MyCGIHTTPServer(CGIHTTPServer.CGIHTTPRequestHandler): 
    def is_cgi(self): 
    collapsed_path = _url_collapse_path(self.path) 
    for path in self.cgi_directories: 
     if path in collapsed_path: 
      dir_sep_index = collapsed_path.rfind(path) + len(path) 
      head, tail = collapsed_path[:dir_sep_index], collapsed_path[dir_sep_index + 1:] 
      self.cgi_info = head, tail 
      return True 
    return False 

server = BaseHTTPServer.HTTPServer 
handler = MyCGIHTTPServer 
0

這裏是你將如何讓每一個.py文件服務器上的文件的CGI(你可能不希望生產/公共服務器):

import BaseHTTPServer 
import CGIHTTPServer 
import cgitb; cgitb.enable() 

server = BaseHTTPServer.HTTPServer 

# Treat everything as a cgi file, i.e. 
# `handler.cgi_directories = ["*"]` but that is not defined, so we need 
class Handler(CGIHTTPServer.CGIHTTPRequestHandler): 
    def is_cgi(self): 
    self.cgi_info = '', self.path[1:] 
    return True 

httpd = server(("", 9006), Handler) 
httpd.serve_forever()