Python CGIHTTPServer 为动态页面和静态页面设置文件类型
Python CGIHTTPServer set file types for dynamic vs static pages
这个问题 () 详细说明了如何为 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
这是真正的预期行为,还是我遗漏了什么?稀疏和不透明的文档说 "The class will however, run the CGI script, instead of serving it as a file, if it guesses it to be a CGI script. Only directory-based CGI are used — the other common server configuration is to treat special extensions as denoting CGI scripts."
我该怎么做"treat special extensions as denoting CGI scripts"。我使用什么方法或设置,或者说出哪些神奇的词?或者这只是一个措辞不当的提示,我就是做不到?
我只是将它用于快速测试,虽然我可以重组以分离 .py 和 .html 文件,但我还有其他限制条件,这会使它成为一个痛苦的练习。
您需要检测请求的文件类型(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()
我从 CGIHTTPServer.py
中提取了原始 is_cgi()
并添加了两个元素
CGIHTTPServer.
in CGIHTTPServer._url_collapse_path(self.path)
在文件外使用它 CGIHTTPServer.py
更重要的是:检查扩展
if not tail.endswith('.html'):
但可以做得更好。
我没用过
if tail.endswith('.py'):
因为如果您需要,服务器可能会执行其他语言的脚本 - 即。 Perl
、PHP
、Bash
等
代码:
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()
这个问题 () 详细说明了如何为 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
这是真正的预期行为,还是我遗漏了什么?稀疏和不透明的文档说 "The class will however, run the CGI script, instead of serving it as a file, if it guesses it to be a CGI script. Only directory-based CGI are used — the other common server configuration is to treat special extensions as denoting CGI scripts."
我该怎么做"treat special extensions as denoting CGI scripts"。我使用什么方法或设置,或者说出哪些神奇的词?或者这只是一个措辞不当的提示,我就是做不到?
我只是将它用于快速测试,虽然我可以重组以分离 .py 和 .html 文件,但我还有其他限制条件,这会使它成为一个痛苦的练习。
您需要检测请求的文件类型(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()
我从 CGIHTTPServer.py
中提取了原始 is_cgi()
并添加了两个元素
CGIHTTPServer.
inCGIHTTPServer._url_collapse_path(self.path)
在文件外使用它CGIHTTPServer.py
更重要的是:检查扩展
if not tail.endswith('.html'):
但可以做得更好。
我没用过
if tail.endswith('.py'):
因为如果您需要,服务器可能会执行其他语言的脚本 - 即。 Perl
、PHP
、Bash
等
代码:
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()