[Zope-dev] [Proposal] RFC2396 compatible traversal parameters

Dieter Maurer dieter at handshake.de
Sun Oct 23 07:21:22 EDT 2005


Title: RFC2396 compatible traversal parameters
Version: 1.0
Last-Modified: 2005/10/23
Author: Dieter Maurer <dieter at handshake.de>
Content-Type: text/x-rst
Created: 23-October-2005

Abstract
========

RFC2396 defines the overall uri structure. Hierachical uri schemes
have a path component consisting of a sequence of path segments.
Each path segment consists of a name and optionally a sequence of
parameters separated by ``;``. This proposal describes how Zope's
publishing component can be enhanced to support path segment parameters,
herein called traversal parameters.


Rationale
=========

There are some important use cases that require information to be
kept across successive requests. The most prominent ones are maintaining
the session id as well as skin and language selection.
We recently met more special ones: keeping tab activation and information about
the authentication domain (for remote login).
The currently available solutions store this information in:

 - the session

 - a cookie

 - the URL

Session and cookie storage have the disadvantages that they do not play well
with the browser's history function and that they can seriously confuse caching
(mittigated a bit by appropriate 'vary' cache controls, but not solved). 
Furthermore, cookies might not be available for security reasons.

URL storage does not suffer these disadvantages but currently
requires the introduction of artificial path segments for
the additional information and
difficult traversal magic to prevent the artificial segments
from interfering with the traversal process.
Traversal parameters can solve this much more naturally than
artificial path segments.

Zope currently does not support traversal parameters.


Usage types
===========

Traversal parameters can have two kinds of uses:

 - controlling the traversal process itself

 - providing information for the whole request

Skin selection belongs for example to the first kind,
tab activation to the second one; language selection may
belong to either of them.

While it seems most natural to attach information for the
whole request to the last path segment, it is much
more practical to use some path segment further to the front
as this information might be used automatically (without explicit
URL construction) by relative uri references.


Risks
=====

Support for traversal parameters controlling the traversal process
itself will inevitably require deeper changes in Zope's traversal
implementation. As this implementation is already quite complex and
supports many use cases, the new extension might break some of them.
I will outline the special risks in the solution part.

There might be clients not implementing RFC 2396. Such clients might
support parameters only at the path end and view everything after
the first ``;`` as part of the parameters. Such clients might resolve
relative uri references incorrectly in the presence of traversal
parameters.


Proposed solution
=================

The solution modifies Zope's ``ZPublisher.BaseRequest.BaseRequest.traverse``.

Currently, the ``path`` argument is split into a sequence of names,
maintained reversed in the ``TraversalRequestNameStack``.
The solution splits it into a sequence of pairs, consisting of
the name and the sequence of parameters. ``TraversalRequestNameStack``
will contain the name only when the parameter sequence is empty
but the pair, otherwise. Usually, this will allow traversal magic (modification
of ``TraversalRequestNameStack`` to change the traversal process) to
continue to work as previously unless it hits a pair when it expects a
name only. Such (hopefully rare) cases will break.

When the traversal process has located a subobject, it checks
whether it has a ``__traversal_parameter_process_hook__``. If so,
it calls it with ``request`` and the parameter list as arguments.
The method may change the list which will affect the
parameters added to the constructed (URL) path segment.

The traversal will maintain the parameters for the current step
in ``TraversalRequestStepParameterList`` to make them available
for ``__bobo_traverse__``. An aware ``__bobo_traverse__`` implementation
might change this list affecting the parameters seen in further processing.

To support parameters destined to the complete request (rather than
individual traversal steps), all found parameters are collected
in ``TraversalRequestCollectedParameterList``. Individual steps
that want to modify the collected parameters can assign a new
list to ``TraversalRequestStepCollectParameterList``. The original
value is a reference to ``TraversalRequestStepParameterList``.
Thus, if it is changed in place, this other list changes as well.

For an application, it is difficult to work with parameter lists.
Therefore, ``BaseRequest`` gets the new method ``dictifyTraversalParameters``.
It takes a parameter list as argument and returns a parameter dictionary.
It performs the same conversions and assemblies as
``ZPublisher.HTTPRequest.HTTPRequest.processInputs``. To
avoid code duplication, ``processInputs`` is refactored.

After traversal, the request gets a lazy key
``TraversalRequestCollectedParameterDict``. It makes the collected
traversal parameters available as a dictionary.

``BaseRequest`` gets a new method ``physicalPathToURL`` (that
of ``HTTPRequest`` is modified accordingly). It checks whether an object
on the path defines a ``__traversal_parameter_creation_hook__``.
If so, it is called with the request as argument and can determine
the path segment corresponding to this object. This allows
``absolute_url`` and friends to add request parameters to created
URLs. There remain some open questions with respect to virtual hosting.
I prefer that the URL parts corresponding to the virtual host
cannot be modified by traversal parameters during URL construction.


-- 
Dieter


More information about the Zope-Dev mailing list