1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
.. index::
single: virtual hosting
.. _vhosting_chapter:
Virtual Hosting
===============
"Virtual hosting" is, loosely, the act of serving a :app:`Pyramid` application
or a portion of a :app:`Pyramid` application under a URL space that it does not
"naturally" inhabit.
:app:`Pyramid` provides facilities for serving an application under a URL
"prefix", as well as serving a *portion* of a :term:`traversal` based
application under a root URL.
.. index::
single: hosting an app under a prefix
Hosting an Application Under a URL Prefix
-----------------------------------------
:app:`Pyramid` supports a common form of virtual hosting whereby you can host a
:app:`Pyramid` application as a "subset" of some other site (e.g., under
``http://example.com/mypyramidapplication/`` as opposed to under
``http://example.com/``).
If you use a "pure Python" environment, this functionality can be provided by
Paste's `urlmap <http://pythonpaste.org/modules/urlmap.html>`_ "composite" WSGI
application. Alternatively, you can use :term:`mod_wsgi` to serve your
application, which handles this virtual hosting translation for you "under the
hood".
If you use the ``urlmap`` composite application "in front" of a :app:`Pyramid`
application or if you use :term:`mod_wsgi` to serve up a :app:`Pyramid`
application, nothing special needs to be done within the application for URLs
to be generated that contain a prefix. :mod:`paste.urlmap` and :term:`mod_wsgi`
manipulate the :term:`WSGI` environment in such a way that the ``PATH_INFO``
and ``SCRIPT_NAME`` variables are correct for some given prefix.
Here's an example of a PasteDeploy configuration snippet that includes a
``urlmap`` composite.
.. code-block:: ini
:linenos:
[app:mypyramidapp]
use = egg:mypyramidapp
[composite:main]
use = egg:Paste#urlmap
/pyramidapp = mypyramidapp
This "roots" the :app:`Pyramid` application at the prefix ``/pyramidapp`` and
serves up the composite as the "main" application in the file.
.. note:: If you're using an Apache server to proxy to a Paste ``urlmap``
composite, you may have to use the `ProxyPreserveHost
<http://httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxypreservehost>`_
directive to pass the original ``HTTP_HOST`` header along to the
application, so URLs get generated properly. As of this writing the
``urlmap`` composite does not seem to respect the ``HTTP_X_FORWARDED_HOST``
parameter, which will contain the original host header even if ``HTTP_HOST``
is incorrect.
If you use :term:`mod_wsgi`, you do not need to use a ``composite`` application
in your ``.ini`` file. The ``WSGIScriptAlias`` configuration setting in a
:term:`mod_wsgi` configuration does the work for you:
.. code-block:: apache
:linenos:
WSGIScriptAlias /pyramidapp /Users/chrism/projects/modwsgi/env/pyramid.wsgi
In the above configuration, we root a :app:`Pyramid` application at
``/pyramidapp`` within the Apache configuration.
.. index::
single: virtual root
.. _virtual_root_support:
Virtual Root Support
--------------------
:app:`Pyramid` also supports "virtual roots", which can be used in
:term:`traversal`-based (but not :term:`URL dispatch`-based) applications.
Virtual root support is useful when you'd like to host some resource in a
:app:`Pyramid` resource tree as an application under a URL pathname that does
not include the resource path itself. For example, you might want to serve the
object at the traversal path ``/cms`` as an application reachable via
``http://example.com/`` (as opposed to ``http://example.com/cms``).
To specify a virtual root, cause an environment variable to be inserted into
the WSGI environ named ``HTTP_X_VHM_ROOT`` with a value that is the absolute
pathname to the resource object in the resource tree that should behave as the
"root" resource. As a result, the traversal machinery will respect this value
during traversal (prepending it to the PATH_INFO before traversal starts), and
the :meth:`pyramid.request.Request.resource_url` API will generate the
"correct" virtually-rooted URLs.
An example of an Apache ``mod_proxy`` configuration that will host the ``/cms``
subobject as ``http://www.example.com/`` using this facility is below:
.. code-block:: apache
:linenos:
NameVirtualHost *:80
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
RewriteRule ^/(.*) http://127.0.0.1:6543/$1 [L,P]
ProxyPreserveHost on
RequestHeader add X-Vhm-Root /cms
</VirtualHost>
.. note:: Use of the ``RequestHeader`` directive requires that the Apache
`mod_headers <http://httpd.apache.org/docs/2.2/mod/mod_headers.html>`_
module be available in the Apache environment you're using.
For a :app:`Pyramid` application running under :term:`mod_wsgi`, the same can
be achieved using ``SetEnv``:
.. code-block:: apache
:linenos:
<Location />
SetEnv HTTP_X_VHM_ROOT /cms
</Location>
Setting a virtual root has no effect when using an application based on
:term:`URL dispatch`.
Further Documentation and Examples
----------------------------------
The API documentation in :ref:`traversal_module` documents a
:func:`pyramid.traversal.virtual_root` API. When called, it returns the
virtual root object (or the physical root object if no virtual root has been
specified).
:ref:`modwsgi_tutorial` has detailed information about using :term:`mod_wsgi`
to serve :app:`Pyramid` applications.
|