Ejemplo n.º 1
0
    def setup_server():
        class Root:
            def index(self):
                return "hello"

            index.exposed = True

            favicon_ico = tools.staticfile.handler(filename=favicon_path)

            def defct(self, newct):
                newct = "text/%s" % newct
                cherrypy.config.update({
                    'tools.response_headers.on':
                    True,
                    'tools.response_headers.headers': [('Content-Type', newct)]
                })

            defct.exposed = True

            def baseurl(self, path_info, relative=None):
                return cherrypy.url(path_info, relative=bool(relative))

            baseurl.exposed = True

        root = Root()

        if sys.version_info >= (2, 5):
            from cherrypy.test._test_decorators import ExposeExamples
            root.expose_dec = ExposeExamples()

        class TestType(type):
            """Metaclass which automatically exposes all functions in each subclass,
            and adds an instance of the subclass as an attribute of root.
            """
            def __init__(cls, name, bases, dct):
                type.__init__(cls, name, bases, dct)
                for value in itervalues(dct):
                    if isinstance(value, types.FunctionType):
                        value.exposed = True
                setattr(root, name.lower(), cls())

        Test = TestType('Test', (object, ), {})

        class URL(Test):

            _cp_config = {'tools.trailing_slash.on': False}

            def index(self, path_info, relative=None):
                if relative != 'server':
                    relative = bool(relative)
                return cherrypy.url(path_info, relative=relative)

            def leaf(self, path_info, relative=None):
                if relative != 'server':
                    relative = bool(relative)
                return cherrypy.url(path_info, relative=relative)

        def log_status():
            Status.statuses.append(cherrypy.response.status)

        cherrypy.tools.log_status = cherrypy.Tool('on_end_resource',
                                                  log_status)

        class Status(Test):
            def index(self):
                return "normal"

            def blank(self):
                cherrypy.response.status = ""

            # According to RFC 2616, new status codes are OK as long as they
            # are between 100 and 599.

            # Here is an illegal code...
            def illegal(self):
                cherrypy.response.status = 781
                return "oops"

            # ...and here is an unknown but legal code.
            def unknown(self):
                cherrypy.response.status = "431 My custom error"
                return "funky"

            # Non-numeric code
            def bad(self):
                cherrypy.response.status = "error"
                return "bad news"

            statuses = []

            def on_end_resource_stage(self):
                return repr(self.statuses)

            on_end_resource_stage._cp_config = {'tools.log_status.on': True}

        class Redirect(Test):
            class Error:
                _cp_config = {
                    "tools.err_redirect.on": True,
                    "tools.err_redirect.url": "/errpage",
                    "tools.err_redirect.internal": False,
                }

                def index(self):
                    raise NameError("redirect_test")

                index.exposed = True

            error = Error()

            def index(self):
                return "child"

            def custom(self, url, code):
                raise cherrypy.HTTPRedirect(url, code)

            def by_code(self, code):
                raise cherrypy.HTTPRedirect("somewhere%20else", code)

            by_code._cp_config = {'tools.trailing_slash.extra': True}

            def nomodify(self):
                raise cherrypy.HTTPRedirect("", 304)

            def proxy(self):
                raise cherrypy.HTTPRedirect("proxy", 305)

            def stringify(self):
                return str(cherrypy.HTTPRedirect("/"))

            def fragment(self, frag):
                raise cherrypy.HTTPRedirect("/some/url#%s" % frag)

        def login_redir():
            if not getattr(cherrypy.request, "login", None):
                raise cherrypy.InternalRedirect("/internalredirect/login")

        tools.login_redir = _cptools.Tool('before_handler', login_redir)

        def redir_custom():
            raise cherrypy.InternalRedirect("/internalredirect/custom_err")

        class InternalRedirect(Test):
            def index(self):
                raise cherrypy.InternalRedirect("/")

            def choke(self):
                return 3 / 0

            choke.exposed = True
            choke._cp_config = {'hooks.before_error_response': redir_custom}

            def relative(self, a, b):
                raise cherrypy.InternalRedirect("cousin?t=6")

            def cousin(self, t):
                assert cherrypy.request.prev.closed
                return cherrypy.request.prev.query_string

            def petshop(self, user_id):
                if user_id == "parrot":
                    # Trade it for a slug when redirecting
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=slug')
                elif user_id == "terrier":
                    # Trade it for a fish when redirecting
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=fish')
                else:
                    # This should pass the user_id through to getImagesByUser
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=%s' % str(user_id))

            # We support Python 2.3, but the @-deco syntax would look like this:
            # @tools.login_redir()
            def secure(self):
                return "Welcome!"

            secure = tools.login_redir()(secure)

            # Since calling the tool returns the same function you pass in,
            # you could skip binding the return value, and just write:
            # tools.login_redir()(secure)

            def login(self):
                return "Please log in"

            def custom_err(self):
                return "Something went horribly wrong."

            def early_ir(self, arg):
                return "whatever"

            early_ir._cp_config = {'hooks.before_request_body': redir_custom}

        class Image(Test):
            def getImagesByUser(self, user_id):
                return "0 images for %s" % user_id

        class Flatten(Test):
            def as_string(self):
                return "content"

            def as_list(self):
                return ["con", "tent"]

            def as_yield(self):
                yield ntob("content")

            def as_dblyield(self):
                yield self.as_yield()

            as_dblyield._cp_config = {'tools.flatten.on': True}

            def as_refyield(self):
                for chunk in self.as_yield():
                    yield chunk

        class Ranges(Test):
            def get_ranges(self, bytes):
                return repr(httputil.get_ranges('bytes=%s' % bytes, 8))

            def slice_file(self):
                path = os.path.join(os.getcwd(), os.path.dirname(__file__))
                return static.serve_file(
                    os.path.join(path, "static/index.html"))

        class Cookies(Test):
            def single(self, name):
                cookie = cherrypy.request.cookie[name]
                # Python2's SimpleCookie.__setitem__ won't take unicode keys.
                cherrypy.response.cookie[str(name)] = cookie.value

            def multiple(self, names):
                for name in names:
                    cookie = cherrypy.request.cookie[name]
                    # Python2's SimpleCookie.__setitem__ won't take unicode keys.
                    cherrypy.response.cookie[str(name)] = cookie.value

        def append_headers(header_list, debug=False):
            if debug:
                cherrypy.log(
                    "Extending response headers with %s" % repr(header_list),
                    "TOOLS.APPEND_HEADERS")
            cherrypy.serving.response.header_list.extend(header_list)

        cherrypy.tools.append_headers = cherrypy.Tool('on_end_resource',
                                                      append_headers)

        class MultiHeader(Test):
            def header_list(self):
                pass

            header_list = cherrypy.tools.append_headers(header_list=[
                (ntob('WWW-Authenticate'), ntob('Negotiate')),
                (ntob('WWW-Authenticate'), ntob('Basic realm="foo"')),
            ])(header_list)

            def commas(self):
                cherrypy.response.headers[
                    'WWW-Authenticate'] = 'Negotiate,Basic realm="foo"'

        cherrypy.tree.mount(root)
Ejemplo n.º 2
0
def setup_server():
    class Root:
        def index(self):
            return "hello"

        index.exposed = True

        favicon_ico = tools.staticfile.handler(filename=favicon_path)

        def andnow(self):
            return "the larch"

        andnow.exposed = True

        def global_(self):
            pass

        global_.exposed = True

        def delglobal(self):
            del self.__class__.__dict__['global_']

        delglobal.exposed = True

        def defct(self, newct):
            newct = "text/%s" % newct
            cherrypy.config.update({
                'tools.response_headers.on':
                True,
                'tools.response_headers.headers': [('Content-Type', newct)]
            })

        defct.exposed = True

        def upload(self, file):
            return "Size: %s" % len(file.file.read())

        upload.exposed = True

    root = Root()

    class TestType(type):
        """Metaclass which automatically exposes all functions in each subclass,
        and adds an instance of the subclass as an attribute of root.
        """
        def __init__(cls, name, bases, dct):
            type.__init__(name, bases, dct)
            for value in dct.itervalues():
                if isinstance(value, types.FunctionType):
                    value.exposed = True
            setattr(root, name.lower(), cls())

    class Test(object):
        __metaclass__ = TestType

    class URL(Test):

        _cp_config = {'tools.trailing_slash.on': False}

        def index(self, path_info, relative=None):
            return cherrypy.url(path_info, relative=bool(relative))

        def leaf(self, path_info, relative=None):
            return cherrypy.url(path_info, relative=bool(relative))

    class Params(Test):
        def index(self, thing):
            return repr(thing)

        def ismap(self, x, y):
            return "Coordinates: %s, %s" % (x, y)

        def default(self, *args, **kwargs):
            return "args: %s kwargs: %s" % (args, kwargs)

    class Status(Test):
        def index(self):
            return "normal"

        def blank(self):
            cherrypy.response.status = ""

        # According to RFC 2616, new status codes are OK as long as they
        # are between 100 and 599.

        # Here is an illegal code...
        def illegal(self):
            cherrypy.response.status = 781
            return "oops"

        # ...and here is an unknown but legal code.
        def unknown(self):
            cherrypy.response.status = "431 My custom error"
            return "funky"

        # Non-numeric code
        def bad(self):
            cherrypy.response.status = "error"
            return "bad news"

    class Redirect(Test):
        class Error:
            _cp_config = {
                "tools.err_redirect.on": True,
                "tools.err_redirect.url": "/errpage",
                "tools.err_redirect.internal": False,
            }

            def index(self):
                raise NameError("redirect_test")

            index.exposed = True

        error = Error()

        def index(self):
            return "child"

        def by_code(self, code):
            raise cherrypy.HTTPRedirect("somewhere else", code)

        by_code._cp_config = {'tools.trailing_slash.extra': True}

        def nomodify(self):
            raise cherrypy.HTTPRedirect("", 304)

        def proxy(self):
            raise cherrypy.HTTPRedirect("proxy", 305)

        def stringify(self):
            return str(cherrypy.HTTPRedirect("/"))

        def fragment(self, frag):
            raise cherrypy.HTTPRedirect("/some/url#%s" % frag)

    def login_redir():
        if not getattr(cherrypy.request, "login", None):
            raise cherrypy.InternalRedirect("/internalredirect/login")

    tools.login_redir = _cptools.Tool('before_handler', login_redir)

    def redir_custom():
        raise cherrypy.InternalRedirect("/internalredirect/custom_err")

    class InternalRedirect(Test):
        def index(self):
            raise cherrypy.InternalRedirect("/")

        def relative(self, a, b):
            raise cherrypy.InternalRedirect("cousin?t=6")

        def cousin(self, t):
            assert cherrypy.request.prev.closed
            return cherrypy.request.prev.query_string

        def petshop(self, user_id):
            if user_id == "parrot":
                # Trade it for a slug when redirecting
                raise cherrypy.InternalRedirect(
                    '/image/getImagesByUser?user_id=slug')
            elif user_id == "terrier":
                # Trade it for a fish when redirecting
                raise cherrypy.InternalRedirect(
                    '/image/getImagesByUser?user_id=fish')
            else:
                # This should pass the user_id through to getImagesByUser
                raise cherrypy.InternalRedirect(
                    '/image/getImagesByUser?user_id=%s' % user_id)

        # We support Python 2.3, but the @-deco syntax would look like this:
        # @tools.login_redir()
        def secure(self):
            return "Welcome!"

        secure = tools.login_redir()(secure)

        # Since calling the tool returns the same function you pass in,
        # you could skip binding the return value, and just write:
        # tools.login_redir()(secure)

        def login(self):
            return "Please log in"

        login._cp_config = {'hooks.before_error_response': redir_custom}

        def custom_err(self):
            return "Something went horribly wrong."

        def early_ir(self, arg):
            return "whatever"

        early_ir._cp_config = {'hooks.before_request_body': redir_custom}

    class Image(Test):
        def getImagesByUser(self, user_id):
            return "0 images for %s" % user_id

    class Flatten(Test):
        def as_string(self):
            return "content"

        def as_list(self):
            return ["con", "tent"]

        def as_yield(self):
            yield "content"

        def as_dblyield(self):
            yield self.as_yield()

        as_dblyield._cp_config = {'tools.flatten.on': True}

        def as_refyield(self):
            for chunk in self.as_yield():
                yield chunk

    class Error(Test):

        _cp_config = {
            'tools.log_tracebacks.on': True,
        }

        def custom(self):
            raise cherrypy.HTTPError(404, "No, <b>really</b>, not found!")

        custom._cp_config = {
            'error_page.404': os.path.join(localDir, "static/index.html")
        }

        def noexist(self):
            raise cherrypy.HTTPError(404, "No, <b>really</b>, not found!")

        noexist._cp_config = {'error_page.404': "nonexistent.html"}

        def page_method(self):
            raise ValueError()

        def page_yield(self):
            yield "howdy"
            raise ValueError()

        def page_streamed(self):
            yield "word up"
            raise ValueError()
            yield "very oops"

        page_streamed._cp_config = {"response.stream": True}

        def cause_err_in_finalize(self):
            # Since status must start with an int, this should error.
            cherrypy.response.status = "ZOO OK"

        cause_err_in_finalize._cp_config = {'request.show_tracebacks': False}

        def rethrow(self):
            """Test that an error raised here will be thrown out to the server."""
            raise ValueError()

        rethrow._cp_config = {'request.throw_errors': True}

    class Ranges(Test):
        def get_ranges(self, bytes):
            return repr(http.get_ranges('bytes=%s' % bytes, 8))

        def slice_file(self):
            path = os.path.join(os.getcwd(), os.path.dirname(__file__))
            return static.serve_file(os.path.join(path, "static/index.html"))

    class Expect(Test):
        def expectation_failed(self):
            expect = cherrypy.request.headers.elements("Expect")
            if expect and expect[0].value != '100-continue':
                raise cherrypy.HTTPError(400)
            raise cherrypy.HTTPError(417, 'Expectation Failed')

    class Headers(Test):
        def default(self, headername):
            """Spit back out the value for the requested header."""
            return cherrypy.request.headers[headername]

        def doubledheaders(self):
            # From http://www.cherrypy.org/ticket/165:
            # "header field names should not be case sensitive sayes the rfc.
            # if i set a headerfield in complete lowercase i end up with two
            # header fields, one in lowercase, the other in mixed-case."

            # Set the most common headers
            hMap = cherrypy.response.headers
            hMap['content-type'] = "text/html"
            hMap['content-length'] = 18
            hMap['server'] = 'CherryPy headertest'
            hMap['location'] = (
                '%s://%s:%s/headers/' %
                (cherrypy.request.local.ip, cherrypy.request.local.port,
                 cherrypy.request.scheme))

            # Set a rare header for fun
            hMap['Expires'] = 'Thu, 01 Dec 2194 16:00:00 GMT'

            return "double header test"

        def ifmatch(self):
            val = cherrypy.request.headers['If-Match']
            cherrypy.response.headers['ETag'] = val
            return repr(val)

    class HeaderElements(Test):
        def get_elements(self, headername):
            e = cherrypy.request.headers.elements(headername)
            return "\n".join([unicode(x) for x in e])

    class Method(Test):
        def index(self):
            m = cherrypy.request.method
            if m in defined_http_methods:
                return m

            if m == "LINK":
                raise cherrypy.HTTPError(405)
            else:
                raise cherrypy.HTTPError(501)

        def parameterized(self, data):
            return data

        def request_body(self):
            # This should be a file object (temp file),
            # which CP will just pipe back out if we tell it to.
            return cherrypy.request.body

        def reachable(self):
            return "success"

    class Divorce:
        """HTTP Method handlers shouldn't collide with normal method names.
        For example, a GET-handler shouldn't collide with a method named 'get'.
        
        If you build HTTP method dispatching into CherryPy, rewrite this class
        to use your new dispatch mechanism and make sure that:
            "GET /divorce HTTP/1.1" maps to divorce.index() and
            "GET /divorce/get?ID=13 HTTP/1.1" maps to divorce.get()
        """

        documents = {}

        def index(self):
            yield "<h1>Choose your document</h1>\n"
            yield "<ul>\n"
            for id, contents in self.documents.iteritems():
                yield (
                    "    <li><a href='/divorce/get?ID=%s'>%s</a>: %s</li>\n" %
                    (id, id, contents))
            yield "</ul>"

        index.exposed = True

        def get(self, ID):
            return ("Divorce document %s: %s" %
                    (ID, self.documents.get(ID, "empty")))

        get.exposed = True

    root.divorce = Divorce()

    class Cookies(Test):
        def single(self, name):
            cookie = cherrypy.request.cookie[name]
            cherrypy.response.cookie[name] = cookie.value

        def multiple(self, names):
            for name in names:
                cookie = cherrypy.request.cookie[name]
                cherrypy.response.cookie[name] = cookie.value

    class ThreadLocal(Test):
        def index(self):
            existing = repr(getattr(cherrypy.request, "asdf", None))
            cherrypy.request.asdf = "rassfrassin"
            return existing

    cherrypy.config.update({
        'log.error_file': log_file,
        'environment': 'test_suite',
        'server.max_request_body_size': 200,
        'server.max_request_header_size': 500,
    })
    appconf = {
        '/': {
            'log.access_file': log_access_file
        },
        '/method': {
            'request.methods_with_bodies': ("POST", "PUT", "PROPFIND")
        },
    }
    cherrypy.tree.mount(root, config=appconf)
Ejemplo n.º 3
0
    def setup_server():
        class Root:

            @cherrypy.expose
            def index(self):
                return 'hello'

            favicon_ico = tools.staticfile.handler(filename=favicon_path)

            @cherrypy.expose
            def defct(self, newct):
                newct = 'text/%s' % newct
                cherrypy.config.update({'tools.response_headers.on': True,
                                        'tools.response_headers.headers':
                                        [('Content-Type', newct)]})

            @cherrypy.expose
            def baseurl(self, path_info, relative=None):
                return cherrypy.url(path_info, relative=bool(relative))

        root = Root()
        root.expose_dec = ExposeExamples()

        class TestType(type):

            """Metaclass which automatically exposes all functions in each
            subclass, and adds an instance of the subclass as an attribute
            of root.
            """
            def __init__(cls, name, bases, dct):
                type.__init__(cls, name, bases, dct)
                for value in itervalues(dct):
                    if isinstance(value, types.FunctionType):
                        value.exposed = True
                setattr(root, name.lower(), cls())
        Test = TestType('Test', (object, ), {})

        @cherrypy.config(**{'tools.trailing_slash.on': False})
        class URL(Test):

            def index(self, path_info, relative=None):
                if relative != 'server':
                    relative = bool(relative)
                return cherrypy.url(path_info, relative=relative)

            def leaf(self, path_info, relative=None):
                if relative != 'server':
                    relative = bool(relative)
                return cherrypy.url(path_info, relative=relative)

        def log_status():
            Status.statuses.append(cherrypy.response.status)
        cherrypy.tools.log_status = cherrypy.Tool(
            'on_end_resource', log_status)

        class Status(Test):

            def index(self):
                return 'normal'

            def blank(self):
                cherrypy.response.status = ''

            # According to RFC 2616, new status codes are OK as long as they
            # are between 100 and 599.

            # Here is an illegal code...
            def illegal(self):
                cherrypy.response.status = 781
                return 'oops'

            # ...and here is an unknown but legal code.
            def unknown(self):
                cherrypy.response.status = '431 My custom error'
                return 'funky'

            # Non-numeric code
            def bad(self):
                cherrypy.response.status = 'error'
                return 'bad news'

            statuses = []

            @cherrypy.config(**{'tools.log_status.on': True})
            def on_end_resource_stage(self):
                return repr(self.statuses)

        class Redirect(Test):

            @cherrypy.config(**{
                'tools.err_redirect.on': True,
                'tools.err_redirect.url': '/errpage',
                'tools.err_redirect.internal': False,
            })
            class Error:
                @cherrypy.expose
                def index(self):
                    raise NameError('redirect_test')

            error = Error()

            def index(self):
                return 'child'

            def custom(self, url, code):
                raise cherrypy.HTTPRedirect(url, code)

            @cherrypy.config(**{'tools.trailing_slash.extra': True})
            def by_code(self, code):
                raise cherrypy.HTTPRedirect('somewhere%20else', code)

            def nomodify(self):
                raise cherrypy.HTTPRedirect('', 304)

            def proxy(self):
                raise cherrypy.HTTPRedirect('proxy', 305)

            def stringify(self):
                return str(cherrypy.HTTPRedirect('/'))

            def fragment(self, frag):
                raise cherrypy.HTTPRedirect('/some/url#%s' % frag)

            def url_with_quote(self):
                raise cherrypy.HTTPRedirect("/some\"url/that'we/want")

            def url_with_xss(self):
                raise cherrypy.HTTPRedirect("/some<script>alert(1);</script>url/that'we/want")

            def url_with_unicode(self):
                raise cherrypy.HTTPRedirect(ntou('тест', 'utf-8'))

        def login_redir():
            if not getattr(cherrypy.request, 'login', None):
                raise cherrypy.InternalRedirect('/internalredirect/login')
        tools.login_redir = _cptools.Tool('before_handler', login_redir)

        def redir_custom():
            raise cherrypy.InternalRedirect('/internalredirect/custom_err')

        class InternalRedirect(Test):

            def index(self):
                raise cherrypy.InternalRedirect('/')

            @cherrypy.expose
            @cherrypy.config(**{'hooks.before_error_response': redir_custom})
            def choke(self):
                return 3 / 0

            def relative(self, a, b):
                raise cherrypy.InternalRedirect('cousin?t=6')

            def cousin(self, t):
                assert cherrypy.request.prev.closed
                return cherrypy.request.prev.query_string

            def petshop(self, user_id):
                if user_id == 'parrot':
                    # Trade it for a slug when redirecting
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=slug')
                elif user_id == 'terrier':
                    # Trade it for a fish when redirecting
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=fish')
                else:
                    # This should pass the user_id through to getImagesByUser
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=%s' % str(user_id))

            # We support Python 2.3, but the @-deco syntax would look like
            # this:
            # @tools.login_redir()
            def secure(self):
                return 'Welcome!'
            secure = tools.login_redir()(secure)
            # Since calling the tool returns the same function you pass in,
            # you could skip binding the return value, and just write:
            # tools.login_redir()(secure)

            def login(self):
                return 'Please log in'

            def custom_err(self):
                return 'Something went horribly wrong.'

            @cherrypy.config(**{'hooks.before_request_body': redir_custom})
            def early_ir(self, arg):
                return 'whatever'

        class Image(Test):

            def getImagesByUser(self, user_id):
                return '0 images for %s' % user_id

        class Flatten(Test):

            def as_string(self):
                return 'content'

            def as_list(self):
                return ['con', 'tent']

            def as_yield(self):
                yield ntob('content')

            @cherrypy.config(**{'tools.flatten.on': True})
            def as_dblyield(self):
                yield self.as_yield()

            def as_refyield(self):
                for chunk in self.as_yield():
                    yield chunk

        class Ranges(Test):

            def get_ranges(self, bytes):
                return repr(httputil.get_ranges('bytes=%s' % bytes, 8))

            def slice_file(self):
                path = os.path.join(os.getcwd(), os.path.dirname(__file__))
                return static.serve_file(
                    os.path.join(path, 'static/index.html'))

        class Cookies(Test):

            def single(self, name):
                cookie = cherrypy.request.cookie[name]
                # Python2's SimpleCookie.__setitem__ won't take unicode keys.
                cherrypy.response.cookie[str(name)] = cookie.value

            def multiple(self, names):
                list(map(self.single, names))

        def append_headers(header_list, debug=False):
            if debug:
                cherrypy.log(
                    'Extending response headers with %s' % repr(header_list),
                    'TOOLS.APPEND_HEADERS')
            cherrypy.serving.response.header_list.extend(header_list)
        cherrypy.tools.append_headers = cherrypy.Tool(
            'on_end_resource', append_headers)

        class MultiHeader(Test):

            def header_list(self):
                pass
            header_list = cherrypy.tools.append_headers(header_list=[
                (ntob('WWW-Authenticate'), ntob('Negotiate')),
                (ntob('WWW-Authenticate'), ntob('Basic realm="foo"')),
            ])(header_list)

            def commas(self):
                cherrypy.response.headers[
                    'WWW-Authenticate'] = 'Negotiate,Basic realm="foo"'

        cherrypy.tree.mount(root)
Ejemplo n.º 4
0
    def setup_server():
        class Root:
            def index(self):
                return 'hello'

            index.exposed = True
            favicon_ico = tools.staticfile.handler(filename=favicon_path)

            def defct(self, newct):
                newct = 'text/%s' % newct
                cherrypy.config.update({
                    'tools.response_headers.on':
                    True,
                    'tools.response_headers.headers': [('Content-Type', newct)]
                })

            defct.exposed = True

            def baseurl(self, path_info, relative=None):
                return cherrypy.url(path_info, relative=bool(relative))

            baseurl.exposed = True

        root = Root()
        if sys.version_info >= (2, 5):
            from cherrypy.test._test_decorators import ExposeExamples
            root.expose_dec = ExposeExamples()

        class TestType(type):
            """Metaclass which automatically exposes all functions in each subclass,
            and adds an instance of the subclass as an attribute of root.
            """
            def __init__(cls, name, bases, dct):
                type.__init__(cls, name, bases, dct)
                for value in itervalues(dct):
                    if isinstance(value, types.FunctionType):
                        value.exposed = True

                setattr(root, name.lower(), cls())

        class Test(object):
            __metaclass__ = TestType

        class URL(Test):
            _cp_config = {'tools.trailing_slash.on': False}

            def index(self, path_info, relative=None):
                if relative != 'server':
                    relative = bool(relative)
                return cherrypy.url(path_info, relative=relative)

            def leaf(self, path_info, relative=None):
                if relative != 'server':
                    relative = bool(relative)
                return cherrypy.url(path_info, relative=relative)

        class Status(Test):
            def index(self):
                return 'normal'

            def blank(self):
                cherrypy.response.status = ''

            def illegal(self):
                cherrypy.response.status = 781
                return 'oops'

            def unknown(self):
                cherrypy.response.status = '431 My custom error'
                return 'funky'

            def bad(self):
                cherrypy.response.status = 'error'
                return 'bad news'

        class Redirect(Test):
            class Error:
                _cp_config = {
                    'tools.err_redirect.on': True,
                    'tools.err_redirect.url': '/errpage',
                    'tools.err_redirect.internal': False
                }

                def index(self):
                    raise NameError('redirect_test')

                index.exposed = True

            error = Error()

            def index(self):
                return 'child'

            def custom(self, url, code):
                raise cherrypy.HTTPRedirect(url, code)

            def by_code(self, code):
                raise cherrypy.HTTPRedirect('somewhere%20else', code)

            by_code._cp_config = {'tools.trailing_slash.extra': True}

            def nomodify(self):
                raise cherrypy.HTTPRedirect('', 304)

            def proxy(self):
                raise cherrypy.HTTPRedirect('proxy', 305)

            def stringify(self):
                return str(cherrypy.HTTPRedirect('/'))

            def fragment(self, frag):
                raise cherrypy.HTTPRedirect('/some/url#%s' % frag)

        def login_redir():
            if not getattr(cherrypy.request, 'login', None):
                raise cherrypy.InternalRedirect('/internalredirect/login')

        tools.login_redir = _cptools.Tool('before_handler', login_redir)

        def redir_custom():
            raise cherrypy.InternalRedirect('/internalredirect/custom_err')

        class InternalRedirect(Test):
            def index(self):
                raise cherrypy.InternalRedirect('/')

            def choke(self):
                return 3 / 0

            choke.exposed = True
            choke._cp_config = {'hooks.before_error_response': redir_custom}

            def relative(self, a, b):
                raise cherrypy.InternalRedirect('cousin?t=6')

            def cousin(self, t):
                return cherrypy.request.prev.query_string

            def petshop(self, user_id):
                if user_id == 'parrot':
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=slug')
                elif user_id == 'terrier':
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=fish')
                else:
                    raise cherrypy.InternalRedirect(
                        '/image/getImagesByUser?user_id=%s' % str(user_id))

            def secure(self):
                return 'Welcome!'

            secure = tools.login_redir()(secure)

            def login(self):
                return 'Please log in'

            def custom_err(self):
                return 'Something went horribly wrong.'

            def early_ir(self, arg):
                return 'whatever'

            early_ir._cp_config = {'hooks.before_request_body': redir_custom}

        class Image(Test):
            def getImagesByUser(self, user_id):
                return '0 images for %s' % user_id

        class Flatten(Test):
            def as_string(self):
                return 'content'

            def as_list(self):
                return ['con', 'tent']

            def as_yield(self):
                yield ntob('content')

            def as_dblyield(self):
                yield self.as_yield()

            as_dblyield._cp_config = {'tools.flatten.on': True}

            def as_refyield(self):
                for chunk in self.as_yield():
                    yield chunk

        class Ranges(Test):
            def get_ranges(self, bytes):
                return repr(httputil.get_ranges('bytes=%s' % bytes, 8))

            def slice_file(self):
                path = os.path.join(os.getcwd(), os.path.dirname(__file__))
                return static.serve_file(
                    os.path.join(path, 'static/index.html'))

        class Cookies(Test):
            def single(self, name):
                cookie = cherrypy.request.cookie[name]
                cherrypy.response.cookie[str(name)] = cookie.value

            def multiple(self, names):
                for name in names:
                    cookie = cherrypy.request.cookie[name]
                    cherrypy.response.cookie[str(name)] = cookie.value

        cherrypy.tree.mount(root)