[Proposal] RFC2396 compatible traversal parameters
Title: RFC2396 compatible traversal parameters Version: 1.0 Last-Modified: 2005/10/23 Author: Dieter Maurer <dieter@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
I agree with your arguments. We considered this for Zope 3. In fact, early Zope 3 publishers supported this. We ended up abandoning this, however, after we realized that, while this feature was specified in the URL standard, it is not widely known or implemented. At the time, for example, the Python code for URL parsing got it wrong (this has been fixed) and some browsers got it wrong as well. The clincher for me was that when I mentioned it to Tim Berners-Lee and Dan Connally of W3C at IPC10, they were surprised that the feature existed and seemed to dissmiss it. :) Also, I would *really* love to see the z3 publisher replace the z2 publisher in one of the 2006 releases. Jim Dieter Maurer wrote:
Title: RFC2396 compatible traversal parameters Version: 1.0 Last-Modified: 2005/10/23 Author: Dieter Maurer <dieter@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.
-- Jim Fulton mailto:jim@zope.com Python Powered! CTO (540) 361-1714 http://www.python.org Zope Corporation http://www.zope.com http://www.zope.org
I really really wouldn't want to see added on top of the current Zope2 publisher. The Zope 2 publisher (and the various traversal mechanisms -- publisher, restrictedTraverse, TALES) should first be refactored to use Zope 3 mechanisms, and only after that is done should we consider adding the kind of feature you propose. Florent Dieter Maurer wrote:
Title: RFC2396 compatible traversal parameters Version: 1.0 Last-Modified: 2005/10/23 Author: Dieter Maurer <dieter@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.
-- Florent Guillaume, Nuxeo (Paris, France) CTO, Director of R&D +33 1 40 33 71 59 http://nuxeo.com fg@nuxeo.com
Florent Guillaume wrote at 2005-10-24 16:19 +0200:
I really really wouldn't want to see added on top of the current Zope2 publisher.
The Zope 2 publisher (and the various traversal mechanisms -- publisher, restrictedTraverse, TALES) should first be refactored to use Zope 3 mechanisms, and only after that is done should we consider adding the kind of feature you propose.
The problem (as always with my proposals): I need this within weeks (not months or years). But, as we maintain our own Zope version, this may not be a problem... -- Dieter
participants (3)
-
Dieter Maurer -
Florent Guillaume -
Jim Fulton