ploneasgi.vhm#
Read VirtualHostMonster rewrites at the ASGI layer.
Native routes are siblings of the Zope mount, which puts them on the wrong side of the proxy: a deployment already rewrites every request into
/VirtualHostBase/<protocol>/<host:port>/<site-path>/VirtualHostRoot/<rest>
and a route that does not understand that shape needs its own proxy rule to be reachable — one more rule per route, forever. Parsing the rewrite here instead means the existing rule serves native routes too, and no new infrastructure is needed to add one.
It also removes a duplication. The site path is already inside the rewrite
(Plone above), so a route does not have to restate it in its path, and the
external scheme and host are recovered as a side effect — without them a native
route behind TLS termination sees http and the container's address.
The reserved prefix is what makes this unambiguous. Anything whose rewritten path
starts with it belongs to a native route; everything else is Zope's, and its
scope is passed through untouched so Zope's own VirtualHostMonster still sees
the URL it expects. Getting that wrong would corrupt every URL Plone generates,
which is why tests/test_vhm.py spends most of its length on it.
Grammar per Products.SiteAccess.VirtualHostMonster. _vh_ segments — the
virtual-path-prefix feature — are deliberately not supported: they change what
the root path means, and guessing wrong would silently mis-route. A request that
uses them against a native route is refused loudly instead.
- ploneasgi.vhm.DEFAULT_PREFIX = '/++asgi++'#
Path prefix reserved for native ASGI routes. Chosen to match Zope's
++namespace++traversal convention, which content ids cannot collide with.
- ploneasgi.vhm.SITE_KEY = 'ploneasgi.site'#
Key under which the path to the virtual root is placed on the ASGI scope.
- ploneasgi.vhm.RAW_PATH_SAFE = "/:@!$&'()*+,;="#
Characters left unquoted in
raw_path: RFC 3986pcharminus%, plus the/separator.
- ploneasgi.vhm.REWRITTEN_KEY = 'ploneasgi.vhm'#
Key marking that a scope was rewritten, so downstream code can tell a proxied request from a direct one.
- class ploneasgi.vhm.VirtualHost[source]#
A parsed VirtualHostMonster rewrite.
- Variables:
protocol -- External scheme, e.g.
https.host -- External host, without the port.
port -- External port, or
Nonewhen the URL carried none.site -- Path from the Zope root to the virtual root, e.g.
Ploneorsites/Plone/folder— everything beforeVirtualHostRoot. It names an object inside a site, not necessarily the site itself;ploneasgi.context.run_authenticated()finds the site by walking it.path -- The real request path, after
VirtualHostRoot.has_vh_segments -- Whether
_vh_prefix segments were present.
- ploneasgi.vhm.parse_virtual_host(path)[source]#
Parse a VirtualHostMonster-rewritten path.
- Parameters:
path (str) -- The raw request path.
- Returns:
The parsed rewrite, or
Nonewhen the path is not one.- Return type:
VirtualHost | None
- class ploneasgi.vhm.VirtualHostMiddleware[source]#
Route VirtualHostMonster-rewritten requests to native ASGI routes.
- Variables:
prefix -- Reserved path prefix identifying a native route.
default_site -- Site id used when a request arrives without a rewrite, which is the direct-access case in development.
- __init__(app, *, prefix='/++asgi++', default_site=None)[source]#
- Parameters:
app (Callable[[MutableMapping[str, Any], Callable[[], Awaitable[MutableMapping[str, Any]]], Callable[[MutableMapping[str, Any]], Awaitable[None]]], Awaitable[None]]) -- The ASGI application to wrap.
prefix (str) -- Reserved path prefix for native routes.
default_site (str | None) -- Site id assumed when there is no rewrite.
- Return type:
None