Pberndt V4

Direkt zum Inhalt springen


Quellcode httpd.py

Sourcecode

#!/usr/bin/python
# encoding: iso-8859-1
"""
    A simple CGI webserver with basic mod_rewrite support
    written in Python.

    Copyright (c) Phillip Berndt, 2006

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    To view the whole GPL, go to http://www.gnu.org/licenses/gpl.txt
"""
import BaseHTTPServer, SimpleHTTPServer, CGIHTTPServer, signal, sys, os, re, urllib, shutil

"""
    Settings
"""

"The htdocs directory."
htdocs = "./"

"File extensions associated with CGI executables"
extensions = {
    "php": "/usr/bin/php-cgi",
    "pl": "/usr/bin/perl"
}

"""
    End of settings
"""

class RequestHandler(CGIHTTPServer.CGIHTTPRequestHandler):
    """
        This is a customized CGIHTTPRequestHandler, which
        is able to execute CGI Scripts based upon file
        extensions.

        You'll have to set the class attributes "rewriteRules"
        and "extensions" before using this class.
    """
    rewriteRules = []
    extensions = {}
       
    def is_cgi(self):
        self.orginalPath = urllib.unquote(self.path)
        orginalURL = self.path
        url = self.path.split("?", 2)

        # Rewrite URL if a rule is matched
        for rewriteRule in self.rewriteRules:
            match = re.search(rewriteRule[0], url[0])
            if match == None: continue
            url[0] = re.sub("(%s)" % rewriteRule[0], re.sub(r"\$([0-9])", lambda val: r"\%d" % (int(val.group(1)) + 1), rewriteRule[1]), url[0])

            newUrl = url[0].split("?", 2)
            if len(newUrl) < 2 and len(url) == 2:
                newUrl.append(url[1])
            elif len(newUrl) == 2 and len(url) == 2:
                newUrl[1] = "%s&%s" % (url[1], newUrl[1])
            self.path = "?".join(newUrl)
            print "Rewrite from %s to %s" % (orginalURL, self.path)

            if len(rewriteRule) == 3 and rewriteRule[2].find("L"):
                break
       
        # Search for CGI executable
        if self.path.find("?") != -1:
            workPath = self.path[0:self.path.find("?")]
        else:
            workPath = self.path
        for extension in self.extensions:
            if workPath[-len(extension):].lower() == extension.lower():
                self.cgiExecutable = self.extensions[extension]
                return True
        return False

    def run_cgi(self):
        try:
            # Set CGI environment variables
            env = {
                "GATEWAY_INTERFACE": "CGI/1.1",
                "SERVER_NAME": "Simple HTTP Server",
                "SERVER_SOFTWARE": "Simple HTTP Server",
                "SERVER_PROTOCOL": self.protocol_version,
                "REQUEST_METHOD": self.command,
                "PATH_INFO": self.path,
                "QUERY_STRING": self.path[self.path.find("?") + 1:],
                "REQUEST_URI": self.orginalPath,
                "REMOTE_ADDR": self.client_address[0]
            }
            if self.path.find("?") != -1:
                env["PATH_INFO"] = self.path[0:self.path.find("?")]
            else:
                env["QUERY_STRING"] = ""
            env["SCRIPT_NAME"] = env["PATH_INFO"]
            env["PATH_TRANSLATED"] = "./" + env["PATH_INFO"]
            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
            for header in self.headers:
                env['HTTP_' + header.upper()] = self.headers[header]
            os.environ.update(env)

            # Execute CGI
            prog = os.popen2(self.cgiExecutable + " " + env["PATH_TRANSLATED"], 'b')
            if self.command.lower() == "post" and int(length) > 0:
                prog[0].write(self.rfile.read(int(length)))
            prog[0].close()
            firstLine = prog[1].readline()
            if firstLine[0:6] == "Status":
                self.wfile.write(self.protocol_version + firstLine[7:-1] + "\r\n")
            elif firstLine[0:3] != "HTTP":
                self.wfile.write(self.protocol_version + " 200 Ok\r\n")
            self.wfile.write(firstLine)
            shutil.copyfileobj(prog[1], self.wfile)
        except:
            self.wfile.write("HTTP/1.1 500 Internal Server Error\r\nContent-Type: text/plain\r\n\r\nCGI Error")

if __name__ == "__main__":
    "Use default port 13000 or port given in cmd"
    if len(sys.argv) == 1:
        port = 13000
    else:
        port = int(sys.argv[1])

    "Change into the htdocs directory"
    os.chdir(htdocs)

    "Signal handler for save exit"
    def onSignal(sign, stack):
        sys.exit(0)
    signal.signal(signal.SIGINT, onSignal)

    "Load htaccess"
    if os.access(".htaccess", os.R_OK):
        print "Using htaccess"
        htaccessFile = open(".htaccess", "r").read()
        if re.search("RewriteEngine On", htaccessFile, re.IGNORECASE):
            rewriteRules = re.findall("^RewriteRule ([^ ]+) ([^ ]+)(?: (.*))?$", htaccessFile, re.MULTILINE)
        else:
            rewriteRules = []
    else:
        rewriteRules = []
           
    "Save settings"
    RequestHandler.rewriteRules = rewriteRules
    RequestHandler.extensions = extensions
   
    "Start httpd"
    httpd = BaseHTTPServer.HTTPServer(('', port), RequestHandler)
    httpd.serve_forever()

Download

Dateiname
httpd.py
Größe
4.84kb