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

Ticket #638 (defect)

Opened 2 years ago

Last modified 2 years ago

Cannot mount two CP apps using PasteDeploy

Status: closed (fixed)

Reported by: alberto@toscat.net Assigned to: rdelon
Priority: normal Milestone:
Component: CherryPy code Keywords:
Cc:

Hi,

I've downloaded the zip file found at http://cherrypy.org/wiki/CherryPyAndPasteCanPlayNice but I'm having problems mounting the same blogapp at different urls using URLMap.

My configuration file looks like this:

[composite:main]
use = egg:Paste#urlmap
/ = blogapp0
/blog1 = blogapp1
/blog2= blogapp2

[app:blogapp0]
use = egg:cp_blog_app#main
bar = Im blog 0

[app:blogapp1]
use = egg:cp_blog_app#main
bar = Im blog 1

[app:blogapp2]
use = egg:cp_blog_app#main
bar = Im blog 2

[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 8080

The problems I see are:

  1. /blog1 and /blog2 causes "303 See other" redirect loops.
  2. /blog1/foo returns "im blog 0" (should be "im blog 1" as specified by config)
  3. /blog2/foo returns "im blog 0" (should be "im blog 2")

I've been doing some experiements with this and made it work by monkey-patching cherrypy.config to use paste.deploy.config.CONFIG and stacking a paste.config.ConfigMiddleware above the CP app in the app_factory.

I could share some code if interested.

Alberto

Change History

01/07/07 22:04:41: Modified by alberto@toscat.net

BTW, The redirect problems dissapear when I change server to use cherrypy (requires PasteScript==dev for 3.0.0)

[server:main]
use = egg:PasteScript#cherrypy
host = 127.0.0.1
port = 8081

Alberto

01/07/07 22:22:58: Modified by fumanchu

Thanks for trying it out! I think the "Im blog X" problems are due to a small bug in the cpwsgihelper file. If I understand correctly, it should be the following instead:

def make_factory(app):
    """Return a PasteDeploy compatible app_factory that will configure

    the given Application.
    """
    
    def app_factory(global_config, **local_conf):
        cherrypy.config.update(global_config)
        app.merge({'/': local_conf})
        init_wsgi()
        return app
    return app_factory

Am I correct in thinking that the line bar = Im blog 1 should be passed in local_conf and not global_config?

01/07/07 23:08:48: Modified by alberto@toscat.net

Yep, it should be passed as local_conf. However, I've tried the app_factory "patch" and get the same results.

Code I mentioned is at http://paste.turbogears.org/paste/769 and http://paste.turbogears.org/paste/770

Some experimental code merging deployment config with app CP-style config (should enable setting up tools, etc... a là CherryPy) is at http://paste.turbogears.org/paste/783

paste.turbogears.org (paste for pastebin, any coincidence with the subject of the ticket purely coincindential! ;) should be online now.

Alberto

01/08/07 00:32:03: Modified by fumanchu

Aha. Then cp_blog_app shouldn't create the Application object, because that single global object is being re-used for each mounting. Instead, it should say app_factory = make_factory(BlogApp) and make_factory should look something like this:

def make_factory(root):
    """Return a PasteDeploy compatible app_factory that will configure
    the given Application root.
    """
    
    def app_factory(global_config, **local_conf):
        cherrypy.config.update(global_config)
        app = cherrypy.Application(root(), script_name=None)
        app.merge({'/': local_conf})
        init_wsgi()
        return app
    return app_factory

I think that will remove the need for any config hacks. And if you're using Paste to mount applications, there should be no need for Tree or any hacks to Tree.

01/08/07 08:19:56: Modified by alberto

yep! That made it work... :) So I grasp that a Tree is a full tree, I mean, should always be rooted at app's "/"(base_url aside...), right? No problem really as, like you've said, app's could be still be composed by Paste using CP's Application objects to wrap CP apps.

It would still be nice if those globals (I can think of request, response, config, engine?,.... am i missing something?) could be stacked so CP applications could act as middleware if needed. I'll be posting at our thread in the trunk ML the use cases we have for that soon. To give an advance, we'd like to be able to do:

class MyController(TGController):
    blog = WsgiApp(load_app("config:foo.ini"))

Where the app loaded could be a CP app. TG controllers should be completely agnostic of the fact that the app is a CP or not... (it might even be close-sourced!)

Thanks for the help,

Alberto

01/08/07 10:42:17: Modified by fumanchu

  • status changed from new to closed.
  • resolution set to fixed.

So I grasp that a Tree is a full tree, I mean, should always be rooted at app's "/"(base_url aside...), right? No problem really as, like you've said, app's could be still be composed by Paste using CP's Application objects to wrap CP apps.

I think I should say "yes", but there's an odd double-use of "app" in that statement, both for a WSGI component and a WSGI complex of WSGI components. It would be simpler for me to say "yes" if it said:

A Tree is a full tree, and should always be rooted at site's "/" (proxy urls aside...). But it doesn't have to be the first object in the WSGI stack--it's just that it uses SCRIPT_NAME to dispatch, and SCRIPT_NAME is always "rooted" at "/". No problem really as complexes could be still be composed by Paste using CP's Application objects to wrap CP apps.

In other words, we've got to find a new word for "set of apps working together" that's not the word "app". We could use "site", but that goes too far the other way, implying that all are mounted at "/" and directly connected to an HTTP server. A "complex" can be mounted anywhere; a Tree can appear anywhere in a WSGI stack; but SCRIPT_NAME is always an absolute URL.

01/08/07 11:23:27: Modified by fumanchu

I might not have said that bit about Tree and SCRIPT_NAME right. What I meant was that a Tree always uses SCRIPT_NAME to dispatch, and so it's never really "mounted" at a URL. It can appear anywhere in the WSGI stack and it will act the same way.

01/14/07 21:50:59: Modified by dowski

Updated the example at CherryPyAndPasteCanPlayNice based on this information. Thanks.

Hosted by WebFaction

Log in as guest/cpguest to create tickets