Giter Site home page Giter Site logo

cherrypy / cherrypy Goto Github PK

View Code? Open in Web Editor NEW
1.8K 54.0 358.0 27.64 MB

CherryPy is a pythonic, object-oriented HTTP framework. https://cherrypy.dev

Home Page: https://docs.cherrypy.dev

License: BSD 3-Clause "New" or "Revised" License

Python 99.95% HTML 0.05% CSS 0.01%
python python-3 python-2 idiomatic-python http http-server https http-streaming daemon-mode cross-platform

cherrypy's Introduction

SWUbanner CherryPy is available as part of the Tidelift Subscription https://readthedocs.org/projects/cherrypy/badge/?version=latest https://img.shields.io/travis/cherrypy/cherrypy/master.svg?label=Linux%20build%20%40%20Travis%20CI https://circleci.com/gh/cherrypy/cherrypy/tree/master.svg?style=svg https://img.shields.io/appveyor/ci/CherryPy/cherrypy/master.svg?label=Windows%20build%20%40%20Appveyor https://img.shields.io/badge/license-BSD-blue.svg?maxAge=3600 stable https://api.codacy.com/project/badge/Grade/48b11060b5d249dc86e52dac2be2c715 codecov

Welcome to the GitHub repository of CherryPy!

CherryPy is a pythonic, object-oriented HTTP framework.

  1. It allows building web applications in much the same way one would build any other object-oriented program.
  2. This design results in more concise and readable code developed faster. It's all just properties and methods.
  3. It is now more than ten years old and has proven fast and very stable.
  4. It is being used in production by many sites, from the simplest to the most demanding.
  5. And perhaps most importantly, it is fun to work with :-)

Here's how easy it is to write "Hello World" in CherryPy:

import cherrypy

class HelloWorld(object):
    @cherrypy.expose
    def index(self):
        return "Hello World!"

cherrypy.quickstart(HelloWorld())

And it continues to work that intuitively when systems grow, allowing for the Python object model to be dynamically presented as a website and/or API.

While CherryPy is one of the easiest and most intuitive frameworks out there, the prerequisite for understanding the CherryPy documentation is that you have a general understanding of Python and web development. Additionally:

If the docs are insufficient to address your needs, the CherryPy community has several avenues for support.

For Enterprise

CherryPy is available as part of the Tidelift Subscription.

The CherryPy maintainers and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.

Learn more.

Contributing

Please follow the contribution guidelines. And by all means, absorb the Zen of CherryPy.

cherrypy's People

Contributors

aminusfu avatar amosshapira avatar bluebirrrrd avatar bobbynewmark avatar cclauss avatar coady avatar cyraxjoe avatar daveschaefer avatar eneldoserrata avatar flamableconcrete avatar hexaclock avatar jaraco avatar jb26 avatar josephtate avatar jrxpert avatar krysros avatar lawouach avatar lbolla avatar mar10 avatar motoom avatar nicklasb avatar poofeg avatar pre-commit-ci[bot] avatar radez avatar rp- avatar spagno avatar tabo avatar webknjaz avatar whiteinge avatar wolph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cherrypy's Issues

allow xmlrpc parameters to be used using paramTuple

Originally reported by: Remco Wendt (Bitbucket: remco, GitHub: remco)


Index: _cphttptools.py

--- _cphttptools.py (revision 11)
+++ _cphttptools.py (working copy)
@@ -296,7 +296,7 @@
return

 cpg.request.objectPath = '/'.join(objectPathList)
  • cpg.response.body = func(virtualPathList, *(cpg.request.paramMap))
  • cpg.response.body = func((virtualPathList+list(cpg.request.paramTuple)), *(cpg.request.paramMap))

if cpg.response.sendResponse:
sendResponse(wfile)


svn checkout is not working

Originally reported by: Anonymous


svn co svn://svn.cherrypy.org/home/cherrypy/svn/CherryPy

svn: Berkeley DB error while opening environment for filesystem /home/cherrypy/svn/CherryPy/db:
DB_RUNRECOVERY: Fatal error, run database recovery
svn: bdb: fatal region error detected; run recovery

Reported by slate


Addition to _cpconfig.py so user options are available in cpg.configOption, addition is set off with comments

Originally reported by: Anonymous


"""
Copyright (c) 2004, CherryPy Team ([email protected])
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the CherryPy Team nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""

import _cputil, ConfigParser, cpg

def setDefaultConfigOption():
""" Return an EmptyClass instance with the default config options """

cpg.configOption = _cputil.EmptyClass()

# Set default values for all options

# Parameters used for logging
cpg.configOption.logToScreen = 1
cpg.configOption.logFile = ''

# Parameters used to tell which socket the server should listen on
# Note that socketPort and socketFile conflict wich each
# other: if one has a non-null value, the other one should be null
cpg.configOption.socketHost = ''
cpg.configOption.socketPort = 8080
cpg.configOption.socketFile = '' # Used if server should listen on
                             # AF_UNIX socket
cpg.configOption.reverseDNS = 0
cpg.configOption.socketQueueSize = 5 # Size of the socket queue
cpg.configOption.protocolVersion = "HTTP/1.0"

# Parameters used to tell what kind of server we want
# Note that numberOfProcesses, threading and forking conflict
# wich each other: if one has a non-null value, the other
# ones should be null (for numberOfProcesses, null means equal to one)
cpg.configOption.processPool = 0 # Used if we want to fork n processes
                             # at the beginning. In this case, all
                             # processes will listen on the same
                             # socket (this only works on unix)
cpg.configOption.threading = 0 # Used if we want to create a new
                           # thread for each request
cpg.configOption.forking = 0 # Used if we want to create a new process
                         # for each request
cpg.configOption.threadPool = 0 # Used if we want to create a pool
                            # of threads at the beginning

# Variables used to tell if this is an SSL server
cpg.configOption.sslKeyFile = ""
cpg.configOption.sslCertificateFile = ""
cpg.configOption.sslClientCertificateVerification = 0
cpg.configOption.sslCACertificateFile = ""
cpg.configOption.sslVerifyDepth = 1

# Variable used to determine what types of request to accept
cpg.configOption.typeOfRequests = ('web', )

# Variable used to flush cache
cpg.configOption.flushCacheDelay=0

# Variable used for enabling debugging
cpg.configOption.debugMode=0

# Variable used to serve static content
cpg.configOption.staticContentList = []

# Variable used for session handling
cpg.configOption.sessionStorageType = ""
cpg.configOption.sessionTimeout = 60 # In minutes
cpg.configOption.sessionCleanUpDelay = 60 # In minutes
cpg.configOption.sessionCookieName = "CherryPySession"
cpg.configOption.sessionStorageFileDir = ""

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'),
        ('server', 'typeOfRequests', 'str'),
        ('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))
    # added by bmctigue so configOption also contains user options
    configSections = cpg.parsedConfigFile.sections()
    try:
        configSections.remove("server")
        configSections.remove("session")
        configSections.remove("staticContent")
    except:
        pass
    for sectionName in configSections:
        sectionOptions = cpg.parsedConfigFile.options(sectionName)
        for optionName in sectionOptions:
            value = cpg.parsedConfigFile.get(sectionName, optionName)
            setattr(cpg.configOption, optionName, value)
    # end section by bmctigue
except: pass

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(" typeOfRequests: %s"%str(cpg.configOption.typeOfRequests), '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')

def dummy():
# Check that parameters are correct and that they don't conflict with each other
if _protocolVersion not in ("HTTP/1.1", "HTTP/1.0"):
raise "CherryError: protocolVersion must be 'HTTP/1.1' or 'HTTP/1.0'"
if _reverseDNS not in (0,1): raise "CherryError: reverseDNS must be '0' or '1'"
if _socketFile and not hasattr(socket, 'AF_UNIX'): raise "CherryError: Configuration file has socketFile, but this is only available on Unix machines"
if _processPool!=1 and not hasattr(os, 'fork'): raise "CherryError: Configuration file has processPool, but forking is not available on this operating system"
if _forking and not hasattr(os, 'fork'): raise "CherryError: Configuration file has forking, but forking is not available on this operating system"
if _sslKeyFile:
try:
global SSL
from OpenSSL import SSL
except: raise "CherryError: PyOpenSSL 0.5.1 or later must be installed to use SSL. You can get it from http://pyopenssl.sourceforge.net"
if 'xmlRpc' in _typeOfRequests:
try:
global xmlrpclib
import xmlrpclib
except: raise "CherryError: xmlrpclib must be installed to use XML-RPC. It is included in Python-2.2 and higher, or else you can get it from http://www.pythonware.com"
if _socketPort and _socketFile: raise "CherryError: In configuration file: socketPort and socketFile conflict with each other"
if not _socketFile and not _socketPort: _socketPort=8000 # Default port
if _processPool==1: severalProcs=0
else: severalProcs=1
if _threadPool==1: severalThreads=0
else: severalThreads=1
if severalThreads+severalProcs+_threading+_forking>1: raise "CherryError: In configuration file: threadPool, processPool, threading and forking conflict with each other"
if _sslKeyFile and not _sslCertificateFile: raise "CherryError: Configuration file has sslKeyFile but no sslCertificateFile"
if _sslCertificateFile and not _sslKeyFile: raise "CherryError: Configuration file has sslCertificateFile but no sslKeyFile"
try: sys.stdout.flush()
except: pass

for typeOfRequest in _typeOfRequests:
    if typeOfRequest not in ('xmlRpc', 'web'): raise "CherryError: Configuration file an invalid typeOfRequest: '%s'"%typeOfRequest

if _sessionStorageType not in ('', 'custom', 'ram', 'file', 'cookie'): raise "CherryError: Configuration file an invalid sessionStorageType: '%s'"%_sessionStorageType
if _sessionStorageType in ('custom', 'ram', 'cookie') and _sessionStorageFileDir!='': raise "CherryError: Configuration file has sessionStorageType set to 'custom, 'ram' or 'cookie' but a sessionStorageFileDir is specified"
if _sessionStorageType=='file' and _sessionStorageFileDir=='': raise "CherryError: Configuration file has sessionStorageType set to 'file' but no sessionStorageFileDir"
if _sessionStorageType=='ram' and (_forking or severalProcs):
    print "CherryWarning: 'ram' sessions might be buggy when using several processes"

Reported by [email protected]


Pass virtual path as parameters

Originally reported by: sja (Bitbucket: sja, GitHub: sja)


Map the unused bits of the url into parameters of the method call.

For example, a request to the url /article/2004/09/21/01 would result in a call to the method of class Article defined as follows:

    def default(self, year, month, day, number): ...

Query string arguments, if present, should be passed to the method as keyword arguments following the regular ones.

See [http://sourceforge.net/mailarchive/forum.php?thread_id=5611850&forum_id=13146 the original discussion].


Define the filter API

Originally reported by: Anonymous


We need to define the full api for the filters. [[br]]
There are two seperate baseobjects, but there is still '''one''' list.

We wanted to change it if i'm not mistaken into two lists.

  • One for incoming, (BaseInputFilters)
  • and one for outgoing. (BaseOutputFilters)

This would allow for more advanced (but in no case rare) setups.

Futhermore we need to have our api ready to convert all the filters (the longer we wait, the more difficult it will get to change the filters), and to move several other items to filters as well:

  • Sessions (it's an option, i know :) )
  • CSAuthenticate (as this interferes with any generator based templating filter)
  • Caching ?

Moving more features to filters allows the end programmer to have more control, and to decrease the need to patch the server directly. This will make it easier for developers to migrate to CherryPy.

Reported by [email protected]


static file can't find

Originally reported by: Anonymous


I put gif file into path(testdata)

and visit http://127.0.0.1:8080/testdata/logo_tlq.gif:
Traceback (most recent call last):
File "C:\Python23\Lib\site-packages\cherrypy_cphttptools.py", line 113, in doRequest
handleRequest(wfile)
File "C:\Python23\Lib\site-packages\cherrypy_cphttptools.py", line 283, in handleRequest
func, objectPathList, virtualPathList = mapPathToObject()
File "C:\Python23\Lib\site-packages\cherrypy_cphttptools.py", line 372, in mapPathToObject
raise cperror.NotFound # We didn't find anything
NotFound

log:
2004/11/23 00:58:20 CONFIG INFO Server parameters:
2004/11/23 00:58:20 CONFIG INFO logToScreen: 1
2004/11/23 00:58:20 CONFIG INFO logFile:
2004/11/23 00:58:20 CONFIG INFO protocolVersion: HTTP/1.0
2004/11/23 00:58:20 CONFIG INFO socketHost:
2004/11/23 00:58:20 CONFIG INFO socketPort: 8080
2004/11/23 00:58:20 CONFIG INFO socketFile:
2004/11/23 00:58:20 CONFIG INFO reverseDNS: 0
2004/11/23 00:58:20 CONFIG INFO socketQueueSize: 5
2004/11/23 00:58:20 CONFIG INFO processPool: 0
2004/11/23 00:58:20 CONFIG INFO threadPool: 2
2004/11/23 00:58:20 CONFIG INFO threading: 0
2004/11/23 00:58:20 CONFIG INFO forking: 0
2004/11/23 00:58:20 CONFIG INFO sslKeyFile:
2004/11/23 00:58:20 CONFIG INFO sessionStorageType: ram
2004/11/23 00:58:20 CONFIG INFO sessionTimeout: 60 min
2004/11/23 00:58:20 CONFIG INFO cleanUpDelay: 60 min
2004/11/23 00:58:20 CONFIG INFO sessionCookieName: CherryPySession
2004/11/23 00:58:20 CONFIG INFO sessionStorageFileDir:
2004/11/23 00:58:20 CONFIG INFO staticContent: [('testdata', 'testdata'), ('
go_tlq.gif', 'testdata/logo_tlq.gif')]
2004/11/23 00:58:20 HTTP INFO Serving HTTP on socket: ('', 8080)
2004/11/23 00:58:25 HTTP INFO 127.0.0.1 - GET /testdata/logo_tlq.gif HTTP/1.1
2004/11/23 00:58:30 HTTP INFO 127.0.0.1 - GET /logo_tlq.gif HTTP/1.1
2004/11/23 00:58:33 HTTP INFO 127.0.0.1 - GET /logo_tlq.gif HTTP/1.1
2004/11/23 00:59:33 HTTP INFO 127.0.0.1 - GET /logo_tlq.gif HTTP/1.1
2004/11/23 00:59:34 HTTP INFO 127.0.0.1 - GET /logo_tlq.gif HTTP/1.1
2004/11/23 00:59:35 HTTP INFO 127.0.0.1 - GET /logo_tlq.gif HTTP/1.1

Reported by [email protected]


Unicode error in CherryTemplate

Originally reported by: Anonymous


==problem:
if there is chinese code returned from template,it will raise exception like:

Traceback (most recent call last):
File "D:\Python23\lib\site-packages\CherryPy_cpHTTPTools.py", line 138, in doRequest
handleRequest(wfile)
File "D:\Python23\lib\site-packages\CherryPy_cpHTTPTools.py", line 419, in handleRequest
cpg.response.body = func(**(cpg.request.paramMap))
File "D:\Python23\testcherry.py", line 32, in index
return renderTemplate(locals(), globals(),open("./formview.html","rb").read())
File "D:\Python23\lib\site-packages\CherryTemplate\CherryTemplate.py", line 442, in renderTemplate
exec(template, locals, globals)
File "", line 25, in ?
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc8 in position 0: ordinal not in range(128)

==solution:
remove unicode function seems ok, I dont know if it works for other languages.
change
f.write(tab+'_page.write(unicode(%s))\n' % evalStr)
to
f.write(tab+'_page.write(%s)\n' % evalStr)

and

change
return _page.getvalue().encode(encoding, encodingErrors)
to
return _page.getvalue()

==reason
it seems that StringIO cause this problem, we can reproduce the exception in:
f = StringIO.StringIO()
f.write('\xd6\xd0\xce\xc4')
f.write('abcd')
f.getvalue() #OK
f.write(unicode('abcd'))
f.getvalue() #exception raised.

Reported by [email protected]


_cpInitRequest can't work

Originally reported by: Anonymous


I hope the visited url is http://xxx.com/index.html

in 2.0a is woked fine

but in current developable version can't work

this is my code:

import string

from cherrypy import cpg

class WebIndex:
def _cpInitRequest(self):
if cpg.request.path.endswith('.html'):
cpg.request.path=cpg.request.path[:-5]
def index(self):
return 'Hello world!!!'
index=cpg.expose(index)
cpg.root = WebIndex()
cpg.server.start(configFile = 'main.conf')

this is error in IE:
Traceback (most recent call last):
File
"/usr/local/lib/python2.3/site-packages/cherrypy/_cphttptools.py", line
149, in doRequest
handleRequest(wfile)
File
"/usr/local/lib/python2.3/site-packages/cherrypy/_cphttptools.py", line
397, in handleRequest
raise cperror.NotFound
NotFound

Reported by [email protected]


Remove static directories from the core

Originally reported by: Anonymous


In my opinion, static directories should be removed from the core of CP2 and replaced by a utility module. Here are a few of the benifits I see:

  • Smaller, more maintainable core.
  • Ability to choose whether a directory should be static or dynamic at runtime.
  • Ability to do in-place redirection on static files.
  • Ability to apply filters to static files.
    I've already done a quick implementation which I'll attach in a minute.

Reported by [email protected]


unittest error about gzipfile

Originally reported by: Anonymous


C:\cherry\cherrypy2\cherrypy\unittest>python unittest.py
Checking that port 8000 is free... OK

Examining your system...

Python version used to run this test script: 2.3.2

Checking which python versions are installed...
Found python version 2.3.2 with CherryPy version 2.0.0a1
Version 2.4 not found (or CherryPy not installed for this version)

Finding out what modules are installed for these versions...
Checking modules for python2.3.2...
os.fork not available
thread available
pyOpenSSL available
xmlrpclib available

Checking CherryPy version...
Found version 2.0.0a1

Testing CherryPy...

Running tests for python 2.3.2...
Testing tutorial 01... r... tp... passed
Testing tutorial 02... r... tp... passed
Testing tutorial 03... r... tp... passed
Testing tutorial 04... r... tp... passed
Testing tutorial 05... r... tp... passed
Testing tutorial 06... r... tp... passed
Testing tutorial 07... r... tp... passed
Testing tutorial 08... r... tp... passed
Testing tutorial 09... r... tp... passed
Testing object mapping... r... tp... passed
Testing Gzip Filter... *** FAILED ***

TEST RESULT

*** THE FOLLOWING TESTS FAILED:
Object mapping for python2.3.2 in r mode failed: expected result was:
'\x1f\x8b\x08', actual result was:
'Hello, world'
**** THE ABOVE TESTS FAILED

**** Some errors occured: please add a ticket in our Trac system (http://trac.ch
errypy.org/cgi-bin/trac.cgi/newticket) with the output of this test script

Reported by [email protected]


Memory DoS caused by very long URL

Originally reported by: jvargas (Bitbucket: jvargas, GitHub: jvargas)


When cp2 receives a very long URL (thousands of path elements), memory usage raises quickly and, eventually, a

RuntimeError: maximum recursion limit exceeded

occurs, compromising cp2-application and system stability.

The problem seems to be the '''cherrypy._cphttptools.getObjFromPath()''' recursive function, and the order it handles path elements.

An ''iterative'' version which handles URL's in the ''opposite direction'' (i.e., from left to right)
is proposed below. It may hopefully help solve this issue.

#------------------ PATCH STARTS AFTER THIS LINE --------------------------------#
332a333,403
> def getObjFromPathIterative(objPathList, objCache):

>     """ For a given objectPathList (like ['root', 'a', 'b', 'index']),

>         return the object (or None if it doesn't exist).

>         Also keep a cache for maximum efficiency

> 

>         *** Notes about this implementation ***

>         

>             [1] It avoids the

>             

>                     RuntimeError: maximum recursion depth exceeded

> 

>                 raised by the recursive implementation upon being requested

>                 a (possibly malicious) very long URL.

> 

>             [2] It scans the URL (here represented by the objPathList) from

>                 left to right (from 'root' to 'index' instead of the opposite).  

>                 

>                 It stops once an object is not valid.

> 

>             [3] It (hopefully) avoids a main-memory DoS vulnerability suffered 

>                 by the recursive implementation (related to [1]).

>                 

>             [4] It passes all (current) unit tests.

>     """

>     # Let cpg be the first valid object.

>     validObjects = ["cpg"]

>     

>     # Scan the objPathList in order from left to right

>     for index, obj in enumerate(objPathList):

>         # currentObjStr holds something like 'cpg.root.something.else'

>         currentObjStr = ".".join(validObjects)

> 

>         #---------------

>         #   Cache check

>         #---------------

>         # Generate a cacheKey from the first 'index' elements of objPathList

>         cacheKey = tuple(objPathList[:index+1])

>         # Is this cacheKey in the objCache?

>         if cacheKey in objCache: 

>             # And is its value not None?

>             if objCache[cacheKey]:

>                 # Yes, then add it to the list of validObjects

>                 validObjects.append(obj)

>                 # OK, go to the next iteration

>                 continue

>             # Its value is None, so we stop

>             # (This means it is not a valid object)

>             break

>         

>         #-----------------

>         # Attribute check

>         #-----------------

>         if getattr(eval(currentObjStr), obj, None):

>             #  obj is a valid attribute of the current object

>             validObjects.append(obj)

>             #  Store it in the cache

>             objCache[cacheKey] = eval(".".join(validObjects))

>         else:

>             # obj is not a valid attribute

>             # Store None in the cache

>             objCache[cacheKey] = None

>             # Stop, we won't process the remaining objPathList

>             break

> 

>     # Return the last cached object (even if its None)

>     return objCache[cacheKey]

> 

> #   *** If accepted, remove these lines of code too please. ***

> #   For testing we do this.

> getObjFromPath = getObjFromPathIterative

> 

#------------------ PATCH ENDS BEFORE THIS LINE --------------------------------#

BaseUrlFilter should also give the option of using X-Forwarded-Host

Originally reported by: Anonymous


Well, I've been thinking about the mod_rewrite with CP2, and there's a
simple solution for any redirects that the server does (using
cpg.request.headerMap['Host'] as the host name). When a rewrite is
made, Apache sets it to the host I rewrite to (for example,
localhost:8000), but also sets "X-Forwarded-Host" header line for the
original host.

So, the solution would be to use X-Forwarded-Host
header, if exists, and if not, then fallback to the Host header line.
So, replace the lines when
cpg.request.headerMap['Host']}}} appears with
{{{cpg.request.headerMap['Host']
the lines with:
cpg.request.headerMap.get("X-Forwarded-Host", cpg.request.headerMap['Host'])}}}. That gives us the true hostname in both cases.
{{{cpg.request.headerMap.get("X-Forwarded-Host", cpg.request.headerMap['Host'])


Auto-redirect to canonical URLs

Originally reported by: Anonymous


The canonical URL scheme looks like this:

  • / -> cpg.root.index()
  • /index -> cpg.root.index()
  • /a/ -> cpg.root.a.index()
  • /a/b -> cpg.root.a.b()

In other words, objects always have trailing slashes, methods never have trailing slashes.

CP2 should enforce this scheme by automatically doing an external redirect if the incoming request URI isn't "correct". For example, if the user requests /a, CP2 should redirect to /a/ before actually calling cpg.root.a.index().

If we do this, request handler classes can safely use relative HTML links to refer to their own (or their parent/child objects') methods.

See: http://sourceforge.net/mailarchive/message.php?msg_id=9558209

Reported by hmans


Test broken when CherryPy installed in a dir with spaces in the name on windows

Originally reported by: Anonymous


My CP tree is under a directory with spaces in the name (on windows), and I get this when I try to run the test:

Checking CherryPy version...
Found version 2.0.0a2

Testing CherryPy...

Running tests for python 2.3.4...
Testing tutorial 01...c:\Personal: can't open file 'Stuff\CherryPy\trunk\che
rrypy\test'

Reported by rdelon


Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.