⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgihttps.py

📁 minimal python variant for small footprint apps like embedded apps
💻 PY
字号:
"""CGI-savvy HTTP Server.This module builds on SimpleHTTPServer by implementing GET and POSTrequests to cgi-bin scripts."""__version__ = "0.3"import osimport sysimport timeimport socketimport stringimport urllibimport BaseHTTPServerimport SimpleHTTPServerclass CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):    """Complete HTTP server with GET, HEAD and POST commands.    GET and HEAD also support running CGI scripts.    The POST command is *only* implemented for CGI scripts.    """    def do_POST(self):        """Serve a POST request.        This is only implemented for CGI scripts.        """        if self.is_cgi():            self.run_cgi()        else:            self.send_error(501, "Can only POST to CGI scripts")    def send_head(self):        """Version of send_head that support CGI scripts"""        if self.is_cgi():            return self.run_cgi()        else:            return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)    def is_cgi(self):        """test whether PATH corresponds to a CGI script.        Return a tuple (dir, rest) if PATH requires running a        CGI script, None if not.  Note that rest begins with a        slash if it is not empty.        The default implementation tests whether the path        begins with one of the strings in the list        self.cgi_directories (and the next character is a '/'        or the end of the string).        """        path = self.path        for x in self.cgi_directories:            i = len(x)            if path[:i] == x and (not path[i:] or path[i] == '/'):                self.cgi_info = path[:i], path[i+1:]                return 1        return 0    cgi_directories = ['/cgi-bin', '/htbin']    def run_cgi(self):        """Execute a CGI script."""        dir, rest = self.cgi_info        i = string.rfind(rest, '?')        if i >= 0:            rest, query = rest[:i], rest[i+1:]        else:            query = ''        i = string.find(rest, '/')        if i >= 0:            script, rest = rest[:i], rest[i:]        else:            script, rest = rest, ''        scriptname = dir + '/' + script        scriptfile = self.translate_path(scriptname)        if not os.path.exists(scriptfile):            self.send_error(404, "No such CGI script (%s)" % `scriptname`)            return        if not os.path.isfile(scriptfile):            self.send_error(403, "CGI script is not a plain file (%s)" %                            `scriptname`)            return        if not executable(scriptfile):            self.send_error(403, "CGI script is not executable (%s)" %                            `scriptname`)            return        nobody = nobody_uid()        self.send_response(200, "Script output follows")        self.wfile.flush() # Always flush before forking        pid = os.fork()        if pid != 0:            # Parent            pid, sts = os.waitpid(pid, 0)            if sts:                self.log_error("CGI script exit status x%x" % sts)            return        # Child        try:            # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html            # XXX Much of the following could be prepared ahead of time!            env = {}            env['SERVER_SOFTWARE'] = self.version_string()            env['SERVER_NAME'] = self.server.server_name            env['GATEWAY_INTERFACE'] = 'CGI/1.1'            env['SERVER_PROTOCOL'] = self.protocol_version            env['SERVER_PORT'] = str(self.server.server_port)            env['REQUEST_METHOD'] = self.command            uqrest = urllib.unquote(rest)            env['PATH_INFO'] = uqrest            env['PATH_TRANSLATED'] = self.translate_path(uqrest)            env['SCRIPT_NAME'] = scriptname            if query:                env['QUERY_STRING'] = query            host = self.address_string()            if host != self.client_address[0]:                env['REMOTE_HOST'] = host            env['REMOTE_ADDR'] = self.client_address[0]            # AUTH_TYPE            # REMOTE_USER            # REMOTE_IDENT            if self.headers.typeheader is None:                env['CONTENT_TYPE'] = self.headers.type            else:                env['CONTENT_TYPE'] = self.headers.typeheader            length = self.headers.getheader('content-length')            if length:                env['CONTENT_LENGTH'] = length            accept = []            for line in self.headers.getallmatchingheaders('accept'):                if line[:1] in string.whitespace:                    accept.append(string.strip(line))                else:                    accept = accept + string.split(line[7:], ',')            env['HTTP_ACCEPT'] = string.joinfields(accept, ',')            ua = self.headers.getheader('user-agent')            if ua:                env['HTTP_USER_AGENT'] = ua            # XXX Other HTTP_* headers            decoded_query = string.replace(query, '+', ' ')            try:                os.setuid(nobody)            except os.error:                pass            os.dup2(self.rfile.fileno(), 0)            os.dup2(self.wfile.fileno(), 1)            print scriptfile, script, decoded_query            os.execve(scriptfile,                      [script, decoded_query],                      env)        except:            self.server.handle_error(self.request, self.client_address)            os._exit(127)nobody = Nonedef nobody_uid():    """Internal routine to get nobody's uid"""    global nobody    if nobody:        return nobody    import pwd    try:        nobody = pwd.getpwnam('nobody')[2]    except pwd.error:        nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))    return nobodydef executable(path):    """Test for executable file."""    try:        st = os.stat(path)    except os.error:        return 0    return st[0] & 0111 != 0def test(HandlerClass = CGIHTTPRequestHandler,         ServerClass = BaseHTTPServer.HTTPServer):    SimpleHTTPServer.test(HandlerClass, ServerClass)if __name__ == '__main__':    test()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -