Graham Dumpleton
grahamd at dscpl.com.au
Wed Nov 15 16:12:12 EST 2006
On 16/11/2006, at 5:05 AM, g.farina at pharaondev.com wrote: > Hi, > > in my simple MVC framework I'd like to use a different directory > root for > controllers based on the website requested by the user. > For instance if someone connects to www.test.it/first I'd like to use > /var/www/test as controllers root, and if someone connects to > www.test2.it/first use /var/www/test2. > > I didn't have enought knowledge of how Apache works, so I don't > know if > the value of req.server.server_hostname is reliable to do the > switch of > the root. > The solution used should work indipendently from Apache > configuration, and > I don't want to rely on headers sent by the client. > > The directory switching should be configured from the application, > so I > can't use Virtual Hosting or Apache configuration directly. Why can't you use virtual hosting, this is what it is designed for? If it is because your site is already running within a virtual host and you don't want to pay some ISP extra money for running an extra virtual host, then it will be pretty well impossible to do what you want. The reason it would be impossible if you are already running within a virtual host is that the way virtual hosting works is that HTTP/1.1 compliant browsers will set a 'Host' header in the HTTP request to identify the actual name of the site it wants to connect to. The web server uses the value of this header to determine which of many virtual hosts it may be hosting to direct the request to. This is done by looking in the Apache configuration for VirtualHost directive which lists that site: <VirtualHost www.test.it> ... </VirtualHost> A second independent virtual host could be setup listing the second site, thus: <VirtualHost www.test.it> ... </VirtualHost> <VirtualHost www.test2.it> ... </VirtualHost> If they need to share some but not all content, you'll need to use Alias directives as well as setting the DocumentRoot to the main content. Alternatively, if you want everything to be the same but do certain things differently based on host connected to, you can also use: <VirtualHost www.test.it www.test2.it> ... </VirtualHost> In either case, it is going to require a change to the Apache configuration. If you can't get one of these done, you can't do it, as the request to the additional site will not even be able to be routed to you. If the second virtual hosting arrangement is used, or virtual hosting isn't used at all, then you still have to use some trickery to have different parts of the filesystem mapped if the desired host is different. The cleanest way of doing this is to use a PythonTransHandler. Because it is called prior to any URL mapping, it must be at the level of VirtualHost or in main Apache configuration if virtual hosting is not used. It cannot be a Directory, Location or .htaccess context as mapping is already done at that point. The transhandler you use would need to use (untested) something like: from mod_python import apache def transhandler(req): if req.hostname == 'www.test2.it': req.filename = '/var/www/test2' + req.uri return apache.OK return apache.DECLINED This assumes that default DocumentRoot is 'var/www/test'. It then sees if the target host is 'www.test2.it' and overrides req.filename to cause mapping of requests against the alternate document root. A problem with this is that it will potentially override any other Alias/Location mappings you might have defined, thus to accommodate that the trans handler may have to only do it for certain values of req.uri. NOTE, the above code may have to cleanup req.uri and normalise it before it uses it to avoid attacks whereby people use '..' in a URI to try and get access to files outside of the document tree. It might also normalise the path after creating the combined path and ensuring the result still resides within the document tree. If Apache has cleaned up req.uri already, this will not be needed. I need to check for myself what Apache has already done at that point as not sure. In terms of other ways of doing it, you might be able to use mod_rewrite, but for this to work, the additional document tree would need to be available as a subtree of the first. You would then be essentially using a internal redirect to get the request applied against the subtree. This though can cause lots of base url rewriting issues for pages. The subtree would also be directly accessible as well unless you protect it by a handler in some way to ensure that is only accessed as part of a subrequest. In summary, you can't probably do it cleanly without modifying the main Apache configuration, as you either have to setup a virtual host, or a trans handler, both of which have to be done in the main configuration. Can you now explain why you can't modify the main Apache configuration. Graham
|