Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Ticket #4: #2-#4b.patch

  • Test/test.py

    old new  
    9292        # display a list of links to random, made-up users. In a real 
    9393        # application, this could be generated from a database result set. 
    9494        return renderTemplate(locals(), globals(), ''' 
    95             <a href="<py-eval="cpg.request.myPath">/remi">Remi Delon</a><br/> 
    96             <a href="<py-eval="cpg.request.myPath">/hendrik">Hendrik Mans</a><br/> 
    97             <a href="<py-eval="cpg.request.myPath">/lorenzo">Lorenzo Lamas</a><br/> 
     95            <a href="<py-eval="cpg.request.objectPath">remi">Remi Delon</a><br/> 
     96            <a href="<py-eval="cpg.request.objectPath">hendrik">Hendrik Mans</a><br/> 
     97            <a href="<py-eval="cpg.request.objectPath">lorenzo">Lorenzo Lamas</a><br/> 
    9898        ''') 
    9999 
    100100    index.exposed = True 
    101101 
    102102 
    103     def default(self): 
     103    def default(self, person): 
    104104        # Here we react depending on the virtualPath -- the part of the 
    105105        # path that could not be mapped to an object method. In a real 
    106106        # application, we would probably do some database lookups here 
    107107        # instead of the silly if/elif/else construct. 
    108         if cpg.request.virtualPath == 'remi': 
     108        if person == 'remi': 
    109109            out = "Remi Delon, CherryPy lead developer" 
    110         elif cpg.request.virtualPath == 'hendrik': 
     110        elif person == 'hendrik': 
    111111            out = "Hendrik Mans, CherryPy fanboi" 
    112         elif cpg.request.virtualPath == 'lorenzo': 
     112        elif person == 'lorenzo': 
    113113            out = "Lorenzo Lamas, famous actor and singer!" 
    114114        else: 
    115115            out = "Unknown user. :-(" 
    116116 
    117         return '%s (<a href="%s">back</a>)' % (out, cpg.request.myPath) 
     117        return '%s (<a href="%s">back</a>)' % (out, cpg.request.objectPath) 
    118118 
    119119    default.exposed = True 
    120120 
  • Tutorial/tutorial07.py

    old new  
    3232    index = cpg.expose(index) 
    3333 
    3434 
    35     def default(self): 
     35    def default(self, person): 
    3636        # Here we react depending on the virtualPath -- the part of the 
    3737        # path that could not be mapped to an object method. In a real 
    3838        # application, we would probably do some database lookups here 
    3939        # instead of the silly if/elif/else construct. 
    40         if cpg.request.virtualPath == 'remi': 
     40        if person == 'remi': 
    4141            out = "Remi Delon, CherryPy lead developer" 
    42         elif cpg.request.virtualPath == 'hendrik': 
     42        elif person == 'hendrik': 
    4343            out = "Hendrik Mans, CherryPy co-developer & crazy German" 
    44         elif cpg.request.virtualPath == 'lorenzo': 
     44        elif person == 'lorenzo': 
    4545            out = "Lorenzo Lamas, famous actor and singer!" 
    4646        else: 
    4747            out = "Unknown user. :-(" 
  • CherryPy/_cpHTTPTools.py

    old new  
    1111THIS 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. 
    1212""" 
    1313 
    14 import cpg, urllib, sys, time, traceback, types, StringIO, cgi, os 
     14import cpg, urllib, sys, time, traceback, types, StringIO, cgi, os, inspect 
    1515import mimetypes, sha, whrandom, string, _cpUtil, cpError 
    1616 
    1717""" 
     
    6565                        cpg.request.paramMap[key] = value 
    6666        cpg.request.path = cpg.request.path[:i] 
    6767 
     68    cpg.request.trailingSlash = False 
    6869    if cpg.request.path and cpg.request.path[-1] == '/': 
    6970        cpg.request.path = cpg.request.path[:-1] # Remove trailing '/' if any 
     71        cpg.request.trailingSlash = True 
    7072 
    7173def parsePostData(rfile): 
    7274    # Read request body and put it in data 
     
    353355    searchedPathList = [] 
    354356    myPath = '' 
    355357    bestKnownDefaultMethod = None 
     358    trailingSlash = True 
    356359    # Successively get objects from the path: 'root', then 'a' then 'b' 
    357360    for pathItem in pathList: 
    358361        previousObj = obj 
     
    366369 
    367370            # if found object has a default method, remember it for later 
    368371            default = getattr(obj, 'default', None) 
    369             if default: 
    370                 # TODO: check if default is callable? 
     372            if default and callable(default) and getattr(default, 'exposed', None): 
    371373                bestKnownDefaultMethod = default 
    372374                bestKnownDefaultMethodMyPath = '/'.join(searchedPathList[1:]) 
    373375 
     
    375377            break 
    376378 
    377379    # TODO: the following code could probably be KISSed somewhat. 
    378  
     380     
     381    # root_a_b exists 
     382    root_a_b = objList[-1] 
     383     
    379384    if len(objList) == len(pathList): 
    380         # root_a_b exists 
    381         root_a_b = objList[-1] 
    382  
    383385        # Try root.a.b.index() 
    384386        root_a_b_dot_index = getattr(root_a_b, 'index', None) 
    385387        if root_a_b_dot_index and getattr(root_a_b_dot_index, 'exposed', None): 
    386             myPath = '/'.join(pathList[1:]) 
     388            myPath = '/'.join(searchedPathList[1:]) 
    387389            func = root_a_b_dot_index 
    388         else: 
    389             # Try root.a.b.default() 
    390             root_a_b_dot_default = getattr(root_a_b, 'default', None) 
    391             if root_a_b_dot_default and getattr(root_a_b_dot_default, 'exposed', None): 
    392                 # XXX: I don't think this ever gets called? 
    393                 myPath = 'root_a_b_dot_default' 
    394                 func = root_a_b_dot_default 
    395             elif callable(root_a_b) and getattr(root_a_b, 'exposed', None): 
    396                 # We use root.a.b() 
    397                 myPath = '/'.join(pathList[1:-1]) 
    398                 func = root_a_b 
     390             
     391    if func == None: 
     392        # Try root.a.b() 
     393        if callable(root_a_b) and getattr(root_a_b, 'exposed', None): 
     394            myPath = '/'.join(searchedPathList[1:-1]) 
     395            func = root_a_b 
     396            trailingSlash = False 
    399397 
    400398    if func == None: 
    401399        # None of these exist: use the default method we found earlier 
     
    415413            myPath = '/' + myPath 
    416414 
    417415        cpg.request.objectPath = myPath 
    418         cpg.request.virtualPath = cpg.request.path[len(myPath)-1:] 
    419         cpg.response.body = func(**(cpg.request.paramMap)) 
     416        virtualParameters = pathList[len(searchedPathList):] 
     417        cpg.request.virtualPath = "/".join(virtualParameters)         
     418         
     419        if cpg.request.virtualPath: 
     420            # Add a trailing slash if the list of virtual parameters is partial 
     421            trailingSlash = len(virtualParameters) < len(inspect.getargspec(func)[0])-1 
     422         
     423        # Redirect to canonical URL 
     424        if cpg.request.path and (trailingSlash != cpg.request.trailingSlash): 
     425            if trailingSlash: 
     426                redirect(wfile, "/" + cpg.request.path + "/") 
     427            else: 
     428                redirect(wfile, "/" + cpg.request.path) 
     429             
     430        cpg.response.body = func(*virtualParameters, **(cpg.request.paramMap)) 
    420431 
    421432    _cpUtil.getSpecialFunction('_cpInitResponse')() 
    422433 
     
    448459 
    449460    if cpg.response.sendResponse: sendResponse(wfile) 
    450461 
     462def redirect(wfile, url): 
     463    cpg.response.headerMap["Status"] = "301 Moved Permanently" 
     464    cpg.response.headerMap["Location"] = url 
     465    cpg.response.body = '''<html><body>Moved <a href="%s">here</a>.</body></html>''' % url 
     466    sendResponse(wfile) 
    451467 
    452468def generateSessionId(): 
    453469    s = '' 

Hosted by WebFaction

Log in as guest/cpguest to create tickets