Example #1
0
def cookHeaders(clientAddress, remoteHost, headers, requestLine):
    """Process the headers into the request.headerMap"""
    cpg.request.headerMap = {}
    cpg.request.requestLine = requestLine
    cpg.request.simpleCookie = Cookie.SimpleCookie()

    # Build headerMap
    for item in headers.items():
        # Warning: if there is more than one header entry for cookies (AFAIK, only Konqueror does that)
        # only the last one will remain in headerMap (but they will be correctly stored in request.simpleCookie)
        insertIntoHeaderMap(item[0],item[1])

    # Handle cookies differently because on Konqueror, multiple cookies come on different lines with the same key
    cookieList = headers.getallmatchingheaders('cookie')
    for cookie in cookieList:
        cpg.request.simpleCookie.load(cookie)

    cpg.request.remoteAddr = clientAddress
    cpg.request.remoteHost = remoteHost

    # Set peer_certificate (in SSL mode) so the web app can examinate the client certificate
    try: cpg.request.peerCertificate = self.request.get_peer_certificate()
    except: pass

    _cputil.getSpecialFunction('_cpLogMessage')("%s - %s" % (cpg.request.remoteAddr, requestLine[:-2]), "HTTP")
Example #2
0
    def handle_error(self, request, client_address):
        """ Handle an error gracefully.  May be overridden.
            The default is to print a traceback and continue.
        """
        import traceback, StringIO

        bodyFile = StringIO.StringIO()
        traceback.print_exc(file=bodyFile)
        errorBody = bodyFile.getvalue()
        bodyFile.close()
        _cputil.getSpecialFunction("_cpLogMessage")(errorBody)
Example #3
0
def outputConfigOptions():
    _cpLogMessage = _cputil.getSpecialFunction("_cpLogMessage")
    _cpLogMessage("Server parameters:", "CONFIG")
    _cpLogMessage("  logToScreen: %s" % cpg.configOption.logToScreen, "CONFIG")
    _cpLogMessage("  logFile: %s" % cpg.configOption.logFile, "CONFIG")
    _cpLogMessage("  protocolVersion: %s" % cpg.configOption.protocolVersion, "CONFIG")
    _cpLogMessage("  socketHost: %s" % cpg.configOption.socketHost, "CONFIG")
    _cpLogMessage("  socketPort: %s" % cpg.configOption.socketPort, "CONFIG")
    _cpLogMessage("  socketFile: %s" % cpg.configOption.socketFile, "CONFIG")
    _cpLogMessage("  reverseDNS: %s" % cpg.configOption.reverseDNS, "CONFIG")
    _cpLogMessage("  socketQueueSize: %s" % cpg.configOption.socketQueueSize, "CONFIG")
    _cpLogMessage("  processPool: %s" % cpg.configOption.processPool, "CONFIG")
    _cpLogMessage("  threadPool: %s" % cpg.configOption.threadPool, "CONFIG")
    _cpLogMessage("  threading: %s" % cpg.configOption.threading, "CONFIG")
    _cpLogMessage("  forking: %s" % cpg.configOption.forking, "CONFIG")
    _cpLogMessage("  sslKeyFile: %s" % cpg.configOption.sslKeyFile, "CONFIG")
    if cpg.configOption.sslKeyFile:
        _cpLogMessage("  sslCertificateFile: %s" % cpg.configOption.sslCertificateFile, "CONFIG")
        _cpLogMessage(
            "  sslClientCertificateVerification: %s" % cpg.configOption.sslClientCertificateVerification, "CONFIG"
        )
        _cpLogMessage("  sslCACertificateFile: %s" % cpg.configOption.sslCACertificateFile, "CONFIG")
        _cpLogMessage("  sslVerifyDepth: %s" % cpg.configOption.sslVerifyDepth, "CONFIG")
        _cpLogMessage("  flushCacheDelay: %s min" % cpg.configOption.flushCacheDelay, "CONFIG")
    _cpLogMessage("  sessionStorageType: %s" % cpg.configOption.sessionStorageType, "CONFIG")
    if cpg.configOption.sessionStorageType:
        _cpLogMessage("  sessionTimeout: %s min" % cpg.configOption.sessionTimeout, "CONFIG")
        _cpLogMessage("  cleanUpDelay: %s min" % cpg.configOption.sessionCleanUpDelay, "CONFIG")
        _cpLogMessage("  sessionCookieName: %s" % cpg.configOption.sessionCookieName, "CONFIG")
        _cpLogMessage("  sessionStorageFileDir: %s" % cpg.configOption.sessionStorageFileDir, "CONFIG")
    _cpLogMessage("  staticContent: %s" % cpg.configOption.staticContentList, "CONFIG")
Example #4
0
def parseConfigFile(configFile=None, parsedConfigFile=None):
    """
        Parse the config file and set values in cpg.configOption
    """
    _cpLogMessage = _cputil.getSpecialFunction("_cpLogMessage")
    if configFile:
        cpg.parsedConfigFile = ConfigParser.ConfigParser()
        if hasattr(configFile, "read"):
            _cpLogMessage("Reading infos from configFile stream", "CONFIG")
            cpg.parsedConfigFile.readfp(configFile)
        else:
            _cpLogMessage("Reading infos from configFile: %s" % configFile, "CONFIG")
            cpg.parsedConfigFile.read(configFile)
    else:
        cpg.parsedConfigFile = parsedConfigFile

    # Read parameters from configFile
    for sectionName, optionName, valueType in [
        ("server", "logToScreen", "int"),
        ("server", "logFile", "str"),
        ("server", "socketHost", "str"),
        ("server", "protocolVersion", "str"),
        ("server", "socketPort", "int"),
        ("server", "socketFile", "str"),
        ("server", "reverseDNS", "int"),
        ("server", "processPool", "int"),
        ("server", "threadPool", "int"),
        ("server", "threading", "int"),
        ("server", "forking", "int"),
        ("server", "sslKeyFile", "str"),
        ("server", "sslCertificateFile", "str"),
        ("server", "sslClientCertificateVerification", "int"),
        ("server", "sslCACertificateFile", "str"),
        ("server", "sslVerifyDepth", "int"),
        ("session", "storageType", "str"),
        ("session", "timeout", "float"),
        ("session", "cleanUpDelay", "float"),
        ("session", "cookieName", "str"),
        ("session", "storageFileDir", "str"),
    ]:
        try:
            value = cpg.parsedConfigFile.get(sectionName, optionName)
            if valueType == "int":
                value = int(value)
            elif valueType == "float":
                value = float(value)
            if sectionName == "session":
                optionName = "session" + optionName[0].upper() + optionName[1:]
            setattr(cpg.configOption, optionName, value)
        except:
            pass

    try:
        staticDirList = cpg.parsedConfigFile.options("staticContent")
        for staticDir in staticDirList:
            staticDirTarget = cpg.parsedConfigFile.get("staticContent", staticDir)
            cpg.configOption.staticContentList.append((staticDir, staticDirTarget))
    except:
        pass
Example #5
0
def sendResponse(wfile):
    applyFilterList('beforeResponse')

    # Save session data
    if cpg.configOption.sessionStorageType and not cpg.request.isStatic:
        sessionId = cpg.response.simpleCookie[cpg.configOption.sessionCookieName].value
        expirationTime = time.time() + cpg.configOption.sessionTimeout * 60
        _cputil.getSpecialFunction('_cpSaveSessionData')(sessionId, cpg.request.sessionMap, expirationTime)

    # Set the content-length
    if (cpg.response.headerMap.has_key('Content-Length') and
            cpg.response.headerMap['Content-Length']==0):
        buf = StringIO.StringIO()
        [buf.write(x) for x in cpg.response.body]
        buf.seek(0)
        cpg.response.body = [buf.read()]
        cpg.response.headerMap['Content-Length'] = len(cpg.response.body[0])

    wfile.write('%s %s\r\n' % (cpg.response.headerMap['protocolVersion'], cpg.response.headerMap['Status']))
    for key, valueList in cpg.response.headerMap.items():
        if key not in ('Status', 'protocolVersion'):
            if type(valueList) != type([]): valueList = [valueList]
            for value in valueList:
                wfile.write('%s: %s\r\n'%(key, value))

    # Send response cookies
    cookie = cpg.response.simpleCookie.output()
    if cookie:
        wfile.write(cookie+'\r\n')
    wfile.write('\r\n')

    for line in cpg.response.body:
        wfile.write(line)
    
    # finalization hook for filter cleanup & logging purposes
    applyFilterList('afterResponse')
Example #6
0
def applyFilterList(methodName):
    try:
        filterList = _cputil.getSpecialFunction('_cpFilterList')
        for filter in filterList:
            method = getattr(filter, methodName, None)
            if method:
                method()
    except basefilter.InternalRedirect:
        # If we get an InternalRedirect, we start the filter list  
        #   from scratch. Is cpg.request.path or cpg.request.objectPath
        #   has been modified by the hook, then a new filter list
        #   will be applied.  
        # We use recursion so if there is an infinite loop, we'll  
        #   get the regular python "recursion limit exceeded" exception.  
        applyFilterList(methodName) 
Example #7
0
def run_server(HandlerClass, ServerClass, server_address, socketFile):
    """Run the HTTP request handler class."""

    if cpg.configOption.socketFile:
        try:
            os.unlink(cpg.configOption.socketFile)  # So we can reuse the socket
        except:
            pass
        server_address = cpg.configOption.socketFile
    if cpg.configOption.threadPool > 1:
        myCherryHTTPServer = ServerClass(server_address, cpg.configOption.threadPool, HandlerClass)
    else:
        myCherryHTTPServer = ServerClass(server_address, HandlerClass)
    cpg._server = myCherryHTTPServer
    if cpg.configOption.socketFile:
        try:
            os.chmod(socketFile, 0777)  # So everyone can access the socket
        except:
            pass
    global _cpLogMessage
    _cpLogMessage = _cputil.getSpecialFunction("_cpLogMessage")

    servingWhat = "HTTP"
    if cpg.configOption.socketPort:
        onWhat = "socket: ('%s', %s)" % (cpg.configOption.socketHost, cpg.configOption.socketPort)
    else:
        onWhat = "socket file: %s" % cpg.configOption.socketFile
    _cpLogMessage("Serving %s on %s" % (servingWhat, onWhat), "HTTP")

    try:
        # Call the functions from cpg.server.onStartServerList
        for func in cpg.server.onStartServerList:
            func()
        myCherryHTTPServer.serve_forever()
    except KeyboardInterrupt:
        _cpLogMessage("<Ctrl-C> hit: shutting down", "HTTP")
        myCherryHTTPServer.server_close()
    # Call the functions from cpg.server.onStartServerList
    for func in cpg.server.onStopServerList:
        func()
Example #8
0
def handleRequest(wfile):
    # Clean up expired sessions if needed:
    now = time.time()
    if cpg.configOption.sessionStorageType and cpg.configOption.sessionCleanUpDelay and cpg._lastSessionCleanUpTime + cpg.configOption.sessionCleanUpDelay * 60 <= now:
        cpg._lastSessionCleanUpTime = now
        _cputil.getSpecialFunction('_cpCleanUpOldSessions')()

    # Save original values (in case they get modified by filters)
    cpg.request.originalPath = cpg.request.path
    cpg.request.originalParamMap = cpg.request.paramMap
    cpg.request.originalParamList = cpg.request.paramList

    path = cpg.request.path
    if path.startswith('/'): path = path[1:] # Remove leading slash
    if path.endswith('/'): path = path[:-1] # Remove trailing slash

    # Handle static directories
    for urlDir, fsDir in cpg.configOption.staticContentList:
        if path == urlDir or path[:len(urlDir)+1]==urlDir+'/':

            cpg.request.isStatic = 1

            fname = fsDir + path[len(urlDir):]
            try:
                stat = os.stat(fname)
            except OSError:
                raise cperror.NotFound
            if type(stat) == type(()): # Python2.1
                modifTime = stat[9]
            else:
                modifTime = stat.st_mtime

            strModifTime = time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(modifTime))

            # Check if browser sent "if-modified-since" in request header
            if cpg.request.headerMap.has_key('If-Modified-Since'):
                # Check if if-modified-since date is the same as strModifTime
                if cpg.request.headerMap['If-Modified-Since'] == strModifTime:
                    cpg.response.headerMap = {'Status': 304, 'protocolVersion': cpg.configOption.protocolVersion, 'Date': cpg.response.headerMap['Date']}
                    cpg.response.body = ''
                    sendResponse(wfile)
                    return

            cpg.response.headerMap['Last-Modified'] = strModifTime
            f=open(fname, 'rb')
            cpg.response.body = f.read()
            f.close()
            # Set content-type based on filename extension
            i = path.rfind('.')
            if i != -1: ext = path[i:]
            else: ext = ""
            contentType = mimetypes.types_map.get(ext, "text/plain")
            cpg.response.headerMap['Content-Type'] = contentType
            sendResponse(wfile)
            return

    # Get session data
    if cpg.configOption.sessionStorageType and not cpg.request.isStatic:
        now = time.time()
        # First, get sessionId from cookie
        try: sessionId = cpg.request.simpleCookie[cpg.configOption.sessionCookieName].value
        except: sessionId=None
        if sessionId:
            # Load session data from wherever it was stored
            sessionData = _cputil.getSpecialFunction('_cpLoadSessionData')(sessionId)
            if sessionData == None:
                sessionId = None
            else:
                cpg.request.sessionMap, expirationTime = sessionData
                # Check that is hasn't expired
                if now > expirationTime:
                    # Session expired
                    sessionId = None

        # Create a new sessionId if needed
        if not sessionId:
            cpg.request.sessionMap = {}
            sessionId = generateSessionId()
            cpg.request.sessionMap['_sessionId'] = sessionId

        cpg.response.simpleCookie[cpg.configOption.sessionCookieName] = sessionId
        cpg.response.simpleCookie[cpg.configOption.sessionCookieName]['path'] = '/'
        cpg.response.simpleCookie[cpg.configOption.sessionCookieName]['version'] = 1

    try:
        func, objectPathList, virtualPathList = mapPathToObject()
    except IndexRedirect, inst:
        # For an IndexRedirect, we don't go through the regular
        #   mechanism: we return the redirect immediately
        newUrl = canonicalizeUrl(inst.args[0])
        wfile.write('%s 302\r\n' % (cpg.response.headerMap['protocolVersion']))
        cpg.response.headerMap['Location'] = newUrl
        for key, valueList in cpg.response.headerMap.items():
            if key not in ('Status', 'protocolVersion'):
                if type(valueList) != type([]): valueList = [valueList]
                for value in valueList:
                    wfile.write('%s: %s\r\n'%(key, value))
        wfile.write('\r\n')
        return
Example #9
0
def doRequest(clientAddress, remoteHost, requestLine, headers, rfile, wfile):
    initRequest(clientAddress, remoteHost, requestLine, headers, rfile, wfile)

    # Prepare response variables
    now = time.time()
    year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
    date = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (weekdayname[wd], day, monthname[month], year, hh, mm, ss)
    cpg.response.headerMap = {
        "protocolVersion": cpg.configOption.protocolVersion,
        "Status": "200 OK",
        "Content-Type": "text/html",
        "Server": "CherryPy/" + cpg.__version__,
        "Date": date,
        "Set-Cookie": [],
        "Content-Length": 0
    }
    cpg.response.simpleCookie = Cookie.SimpleCookie()
    cpg.response.wfile = wfile
    cpg.response.sendResponse = 1

    try:
        handleRequest(wfile)
    except:
        err = ""
        exc_info_1 = sys.exc_info()[1]
        if hasattr(exc_info_1, 'args') and len(exc_info_1.args) >= 1:
            err = exc_info_1.args[0]

        try:
            _cputil.getSpecialFunction('_cpOnError')()

            # Still save session data
            if cpg.configOption.sessionStorageType and not cpg.request.isStatic:
                sessionId = cpg.response.simpleCookie[cpg.configOption.sessionCookieName].value
                expirationTime = time.time() + cpg.configOption.sessionTimeout * 60
                _cputil.getSpecialFunction('_cpSaveSessionData')(sessionId, cpg.request.sessionMap, expirationTime)

            wfile.write('%s %s\r\n' % (cpg.response.headerMap['protocolVersion'], cpg.response.headerMap['Status']))

            if (cpg.response.headerMap.has_key('Content-Length') and
                    cpg.response.headerMap['Content-Length']==0):
  	 	        buf = StringIO.StringIO()
  	 	        [buf.write(x) for x in cpg.response.body]
  	 	        buf.seek(0)
  	 	        cpg.response.body = [buf.read()]
  	 	        cpg.response.headerMap['Content-Length'] = len(cpg.response.body[0])

            for key, valueList in cpg.response.headerMap.items():
                if key not in ('Status', 'protocolVersion'):
                    if type(valueList) != type([]): valueList = [valueList]
                    for value in valueList:
                        wfile.write('%s: %s\r\n'%(key, value))
            wfile.write('\r\n')
            for line in cpg.response.body:
                wfile.write(line)
        except:
            bodyFile = StringIO.StringIO()
            traceback.print_exc(file = bodyFile)
            body = bodyFile.getvalue()
            wfile.write('%s 200 OK\r\n' % cpg.configOption.protocolVersion)
            wfile.write('Content-Type: text/plain\r\n')
            wfile.write('Content-Length: %s\r\n' % len(body))
            wfile.write('\r\n')
            wfile.write(body)
Example #10
0
 def log_message(self, format, *args):
     """ We have to override this to use our own logging mechanism """
     _cputil.getSpecialFunction("_cpLogMessage")(format % args, "HTTP")