简体   繁体   English

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

[英]Python CGIHTTPServer set file types for dynamic vs static pages

This question ( Python CGIHTTPServer Default Directories ) details how to set paths for location of cgi-bin files for Python CGIHTTPServer. 这个问题( Python CGIHTTPServer默认目录 )详细说明了如何为Python CGIHTTPServer设置cgi-bin文件的位置路径。 From testing this, it seems that you cannot mix .py and .html files in the same folder: in cgi-bin it processes .py files fine, but asked to serve a static html file I get 通过测试,似乎您无法在同一文件夹中混合使用.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

Is this the real intended behaviour, or am I missing something? 这是真正的预期行为,还是我缺少某些东西? The sparse and opaque documentation says "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." 稀疏且不透明的文档说:“但是,如果类认为它是CGI脚本,它将运行CGI脚本,而不是将其作为文件提供。仅使用基于目录的CGI,另一种常见的服务器配置是将特殊扩展视为表示CGI脚本。”

How do I do "treat special extensions as denoting CGI scripts". 我该怎么做“将特殊扩展视为CGI脚本”。 What method or setting do I use, or which magic words do I utter? 我使用什么方法或设置,或者说出哪些魔术字? Or is this just an ineptly worded tip-off that I just can't do it? 还是这只是我做不到的无用的小费?

I'm only using this for quick tests, and while I could restructure to separate .py and .html files I have other constraints that would make this a painful exercise. 我仅将其用于快速测试,尽管我可以重组以分离.py和.html文件,但我还有其他限制条件,这将使这一工作很痛苦。

I took oryginal is_cgi() from CGIHTTPServer.py and add two elements 我把oryginal is_cgi()CGIHTTPServer.py并添加两个元素

  • CGIHTTPServer. in CGIHTTPServer._url_collapse_path(self.path) to use it outside file CGIHTTPServer.py CGIHTTPServer._url_collapse_path(self.path)以在文件CGIHTTPServer.py之外使用它
  • and more important: checking extension 更重要的是:检查扩展名

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

    but it could be done better. 但可以做得更好。

I didn't use 我没用

    if tail.endswith('.py'):

because server may execute scripts in other languages if you need - ie. 因为服务器可以根据需要执行其他语言的脚本-即 Perl , PHP , Bash , etc. PerlPHPBash

Code: 码:

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()

You need to detect, what kind of file type is requested (py/cgi or a static file). 您需要检测所请求的文件类型(py / cgi或静态文件)。 Mimetypes may help. 模仿类型可能会有所帮助。 When a static file is requested, you could call another cgi script that delivers your static file. 当请求静态文件时,您可以调用另一个提供静态文件的cgi脚本。 Btw. 顺便说一句。 you should use wsgi instead of outdated cgi. 您应该使用wsgi而不是过时的cgi。

I modified some old code (py2.7) i got - that's very ugly and i never used it - but when you put a static file 'dev.html' in the 'handler.cgi_directory' it should be served by static.py. 我修改了我得到的一些旧代码(py2.7)-这很丑陋,我从未使用过-但是,当您将静态文件'dev.html'放入'handler.cgi_directory'中时,应该由static.py提供服务。

server.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: 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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM