【问题标题】:Python CGIHTTPServer set file types for dynamic vs static pagesPython CGIHTTPServer 为动态和静态页面设置文件类型
【发布时间】:2017-05-22 18:33:05
【问题描述】:

这个问题 (Python CGIHTTPServer Default Directories) 详细介绍了如何为 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 文件,但我还有其他限制会使这成为一个痛苦的练习。

【问题讨论】:

  • 您可以使用import CGIHTTPServer ; print CGIHTTPServer.__file__ 查找源代码并查看其工作原理。但是请参阅您的链接-它们会覆盖方法is_cgi()-也许您也必须这样做。

标签: python cgihttpserver


【解决方案1】:

我从CGIHTTPServer.py 中提取了原始的is_cgi() 并添加了两个元素

  • CGIHTTPServer.CGIHTTPServer._url_collapse_path(self.path) 中使用它在文件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()

【讨论】:

    【解决方案2】:

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

    我修改了我得到的一些旧代码 (py2.7) - 这非常难看,我从未使用过它 - 但是当你将静态文件 'dev.html' 放在 'handler.cgi_directory' 中时,它应该由静态提供.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()
    

    静态.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()
    

    【讨论】:

    • 很好的答案,谢谢。仅将 firas 的答案标记为正确,而不是这个,因为它更简单
    猜你喜欢
    • 2015-08-12
    • 2013-01-30
    • 2012-09-03
    • 2010-11-19
    • 2017-11-01
    • 2012-07-11
    • 2017-04-07
    • 2017-11-04
    • 1970-01-01
    相关资源
    最近更新 更多