1. cherrypy
  2. CherryPy
Issue #2 resolved

Auto-redirect to canonical URLs

Anonymous created an issue

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

Comments (7)

  1. Anonymous

    After some discussion on cherrypy-devel, we're considering making this a configuration option.

  2. sja

    Should URIs with virtual path parameters have a trailing slash?

    My patch strips trailing slashes from such URLs, because I thought the most common case would be someting like /user/12, where "12" logically represents a file, or a leaf in the tree.

    But what should happen when we have urls such as /articles/2004/, which returns a list of articles from the given year? Is this an index/folder? Should it have a trailing slash? If so, how do we distinguish between the former and the latter case?

    Perhaps we could add a trailing slash when the list of parameters is incomplete. For example:

    class Articles:
        def default(self, year, month=None, day=None, number=None):

    Given the previous method definition, these are the possible valid urls:

  3. sja

    There are a couple open issues with my latest implementation.

    class A:
        def b(self, c=None):

    In this case, b is a method, hence it will not have a trailing slash in the url (/a/b). But b allows a virtual path parameter (/a/b/45), so it's logically not a leaf, but an index... should it have a trailing slash when the parameter is unspecified?

    class Articles:
        # colorScheme is meant as a query string parameter
        def default(self, year, month=None, day=None, number=None, colorScheme=1):

    If a method is defined as in this example, the URL of an article will have a trailing slash (/2004/12/5/3/), though it problably should not.

    A workaround is to define the method thus:

        def default(self, year, month=None, day=None, number=None, **parameters):

    Personally I like this better because it creates a cleaner distinction between normal parameters and query string arguments.

  4. Log in to comment