Python CGIHTTPServer为动态页面和静态页面设置文件类型



这个问题(Python CGIHTTPServer默认目录)详细介绍了如何为Python CGIHTTPServer设置cgi-bin文件的位置路径。通过测试,您似乎无法将.py和.html文件混合在同一文件夹中:在cgi-bin中,它可以很好地处理.py文件,但要求提供静态html文件,我得到

127.0.0.1 - - [08/Jan/2017 10:51:22] "GET /dev.html HTTP/1.1" 200 -
Traceback (most recent call last):
File "/usr/lib/python2.7/CGIHTTPServer.py", line 248, in run_cgi
os.execve(scriptfile, args, env)
OSError: [Errno 8] Exec format error
127.0.0.1 - - [08/Jan/2017 10:51:22] CGI script exit status 0x7f00

这是真正的故意行为,还是我遗漏了什么?稀疏而不透明的文档中写道:"然而,如果类猜测它是CGI脚本,它将运行CGI脚本,而不是将其作为文件。只使用基于目录的CGI——另一种常见的服务器配置是将特殊扩展视为表示CGI脚本。">

如何"将特殊扩展视为表示CGI脚本"。我使用什么方法或设置,或者说什么神奇的话?还是这只是一个措辞拙劣的提示,我就是做不到?

我只是将其用于快速测试,虽然我可以重组以分离.py和.html文件,但我有其他限制,这将使这成为一项痛苦的工作。

我从CGIHTTPServer.py中取出原始is_cgi(),并添加两个元素

  • CGIHTTPServer._url_collapse_path(self.path)中的CGIHTTPServer.在文件CGIHTTPServer.py之外使用
  • 更重要的是:检查扩展

    if not tail.endswith('.html'):
    

    但它可以做得更好。

我没有使用

if tail.endswith('.py'):

因为如果您需要,服务器可能会执行其他语言的脚本,例如PerlPHPBash等。

代码:

import BaseHTTPServer
import CGIHTTPServer
class MyHandler(CGIHTTPServer.CGIHTTPRequestHandler):
# code from oryginal CGIHTTPServer.py
def is_cgi(self):
#                v added `CGIHTTPServer.`
collapsed_path = CGIHTTPServer._url_collapse_path(self.path) 
dir_sep = collapsed_path.find('/', 1)
head, tail = collapsed_path[:dir_sep], collapsed_path[dir_sep+1:]
if head in self.cgi_directories:
if not tail.endswith('.html'): # <-- new line
#if tail.endswith('.py'): # <-- new line
self.cgi_info = head, tail
return True
return False
# --- test ---
MyHandler.cgi_directories = ['/']
server = BaseHTTPServer.HTTPServer(('', 8000), MyHandler)
server.serve_forever()

您需要检测请求的文件类型(py/cgi或静态文件)。Mimetypes可能会有所帮助。当请求静态文件时,可以调用另一个cgi脚本来传递静态文件。顺便说一句,你应该使用wsgi,而不是过时的cgi。

我修改了我得到的一些旧代码(py2.7)——这很难看,我从来没有使用过它——但当你把一个静态文件"dev.html"放在"handler.cgi_directory"中时,它应该由static.py.提供

server.py:

#!/usr/bin/python2
import BaseHTTPServer
import CGIHTTPServer
from mimetypes import MimeTypes
import urllib 
class handler(CGIHTTPServer.CGIHTTPRequestHandler):  
def is_cgi(self):
mime = MimeTypes()
request = self.path.split('?')
if len(request) == 2:
path, args = request
else:
path, args = request, None
if isinstance(path, list):
path = path[0]
url = urllib.pathname2url(path)
mime_type = mime.guess_type(url)
if 'python' in mime_type[0]:
self.cgi_info = '', self.path[1:]
return True
else:
self.cgi_info = '', '/static.py?path=%s' % path[1:]
print self.cgi_info
return True
server = BaseHTTPServer.HTTPServer
server_address = ("", 8000)
handler.cgi_directories = ["/somedir/..."]
httpd = server(server_address, handler)
httpd.serve_forever()

static.py:

#!/usr/bin/python2
import cgi
import urllib
from mimetypes import MimeTypes
form = cgi.FieldStorage()
mime = MimeTypes()
path = form.getvalue('path')
url = urllib.pathname2url(path)
mime_type = mime.guess_type(url)
print """Content-type: %s""" % mime
print 
print open(path, 'r').read()

最新更新