Author: ts
Date: Fri Feb 29 21:04:18 2008
New Revision: 7473

Log:
- Changed structure of design document.
- Rephrased some parts.

Modified:
    trunk/Webdav/design/design-1.1.txt

Modified: trunk/Webdav/design/design-1.1.txt
==============================================================================
--- trunk/Webdav/design/design-1.1.txt [iso-8859-1] (original)
+++ trunk/Webdav/design/design-1.1.txt [iso-8859-1] Fri Feb 29 21:04:18 2008
@@ -1,4 +1,4 @@
-eZ component: Webdav, Design, 1.2
+eZ component: Webdav, Design, 1.1
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 :Author: Tobias Schlitt
@@ -17,8 +17,8 @@
 The general goal for this version is to support locking as described in RFC
 2518. To achieve this, the if-header must be parsed and respected by the Webdav
 component. This currently is not the case. The if-header must also be used to
-respect entity tags, which is not an integral part of the locking feature. 
However,
-the support of entity tags is part of this design, too. 
+respect entity tags, which is not an integral part of the locking feature.
+However, the support of entity tags is part of this design, too. 
 
 The following issues are covered in this design:
 
@@ -26,16 +26,295 @@
   (#12583).
 - Lock support (#12286).
 
+For locking, a plugin based approach has been favored while desiging and
+creating the Webdav component version 1.0. However, it turned out that the
+realization of lock support through a plugin is not as easy as it seemed to be.
+Therefore this document describes 2 different design approaches for lock
+related functionality: A plugin based one and an integrated one.
+
+The document is devided into 3 parts. The first part deals with the realization
+of functionality that is execlusively meant to support entity tags. The second
+part describes features that are exclusively used to support locking features.
+Since WebDAV mixes entity tags (originally HTTP/1.1) and locking in some
+places, the third section describes the design for these common concerns.
+
+Entity tag support
+^^^^^^^^^^^^^^^^^^
+
+This section describes the support of entity tags in the Webdav component, 
including
+the usage of the if-header with entity tags and the generation and sending of 
the
+ETag header.
+
+The following design only refers to the support of entity tags as defined in
+the HTTP/1.1 RFC. This includes the headers mentioned in the above RFC overview
+and the generation and comparison of entity tags.
+
+Entity tag generation
+=====================
+
+The generation of an entity tag requires uniqueness for the state of a resource
+(the so-called entity), To achieve this, multiple data of the resource and be
+involved and combined.
+
+The last modification time in combination with the file size should be a
+sufficient combination of data to generate an entity tag from. The Lighttpd
+web server uses this information on a configurable basis, too. In addition it
+can use the inode of the file for entity tag generation. Since inodes are
+operating system dependent and only available for file system based back ends,
+they will not be used in our entity tag generation scheme.
+
+Since entity tags in WebDAV are also available through the getetag
+live-property, a common way is needed to generate the entity tags for the
+headers and the property. The ezcWebdavSimpleBackend will therefore request the
+getetag property from the extending back end and use it's value for the headers
+and validation.
+
+The current generation of entity tags in ezcWebdavFileBackend will be replaced
+by a mechanism that uses the last modification time and the size of the file.
+It currently uses the path, which is not reliable and does not belong into the
+entity tag. Entity tags are only valid for a single resource and only in
+combination with its URI.
+
+Header handling
+===============
+
+The handling of entity tag related headers must take place in several different
+architecture levels of the Webdav component.
+
+Transport layer
+---------------
+
+The transport layer needs to be able to parse the request headers and to
+serialize the response headers back. Therefore the ezcWebdavHeaderHandler class
+will be adjusted.
+
+The class must parse the following new request headers:
+
+- If-Match
+- If-None-Match
+
+ezcWebdavHeaderHandler will check if both of these headers are set. If this is
+the case, both headers will be silently discarded, since such a combination is
+undefined.
+
+Both headers can contain a list of weak/non-weak entity tags or the "*" value,
+to indicate that the resource must just exists, no matter in which state. To
+represent this in PHP, the parsed headers will be represented either as an
+array of string values or as the boolean value true. The headers will be parsed
+into every request object automatically, if they are set.
+
+The back end layer must take responsibility for interpreting the headers and
+their values.
+
+In addition, ezcWebdavHeaderHandler must take care of serializing an ETag
+header, if this one is present in a response object. Since the ETag header may
+only contain the string value of an entity tag, this mechanism is already
+implemented in the response processing.
+
+Back end layer
+--------------
+
+The interpretation of incoming If-Match and If-None-Match headers must be done
+in the back end. The implementation will take place in the
+ezcWebdavSimpleBackend class. With every incoming request, no matter which
+request method is used, the If-Match and If-None-Match headers will be honored
+in the following way:
+
+If the back end determines that an If-Match header is set, it will:
+
+- Check if all preconditions (except the If-Match) are fulfilled.
+
+  - If not, return a corresponding error response.
+
+- Check if the If-Match value is a boolean true.
+  
+  - Check if the requested path exists.
+  
+  - If it *does not*, cancel the method and return 412 (Precondition Failed).
+
+- Check if the If-Match value is an array of strings.
+  
+  - Retrieve the affected resources getetag property and compare it with all
+    strings in the array.
+  
+  - If *none* matches, cancel the method and return 412 (Precondition Failed).
+
+- Process the method as if the If-Match header was not set.
+
+If the back end determines that an If-None-Match header is set, it will:
+
+- Check if all preconditions (except the If-Match) are fulfilled.
+  
+  - If not, return a corresponding error response.
+
+- Check if the If-Match value is a boolean true.
+  
+  - Check if the requested path exists.
+    
+    - If it *does*, cancel the method and return 412 (Precondition Failed).
+
+- Check if the If-Match value is an array of strings.
+  
+  - Retrieve the affected resources getetag property and compare it with all
+    strings in the array.
+    
+    - If *any* matches, cancel the method and return 412 (Precondition Failed).
+
+- Process the method as if the If-None-Match header was not set.
+
+Since this behavior will be implemented within the ezcWebdavSimpleBackend
+class, it automatically works with all extending back end classes. Back ends
+that do not extend ezcWebdavSimpleBackend will have to take care for these
+headers on their own.
+
+Lock support
+^^^^^^^^^^^^
+
+Locking allows a WebDAV client to gain exclusive access to a resource
+(collection or non-collection) to avoid the "lost update problem". This means
+that a client can define to have exclusive access to a resource for a certain
+time, where no other client may gain access to this resource.
+
+The WebDAV RFC distinguishes locks by 2 essential properties: The scope of the
+lock (shared vs. exclusive) and the type of the lock (write vs. read), while
+for the type only a write lock is specified. Using an exclusive lock the client
+ensures that he has absolutely exclusive access to the locked resource. With a
+shared lock it is possible the multiple clients take part in one and the same
+lock. More information on lock scopes are provided later.
+
+============
+Plugin based
+============
+
+This section describes a potential realization of locking through a plugin for
+the Webdav component. This plugin will make use of the, not yet officially
+released, plugin API.
+
+Design goals
+============
+
+This design drafts goal is to build a lock plugin that is almost completely
+independent from the used back end. In this sense, the requirements to be
+fulfilled by a back end must be cut down as far as possible. Beside that, the
+plugin should provide the largest possible compatibility to clients. However a
+plugin that hooks into the parsing process cannot provide the same client
+compatibility mechanisms as the base Webdav transport layer.
+
+Hooks
+=====
+
+The plugin needs to assign to several hooks offered by the plugin API, which
+will be described roughly in this section.
+
+parseUnknownRequest (ezcWebdavTransport)
+----------------------------------------
+
+The requests LOCK and UNLOCK are dedicated to the locking mechanism. Therefore
+the plugin needs to hook into parseUnknownRequest and parse the incoming
+requests into (new) corresponding request objects.
+
+
+
+===========
+Open issues
+===========
+
+Authentication
+==============
+
+The problem
+-----------
+
+The WebDAV RFC specifies that lock tokens are not secure for authentication
+since the can be obtained by every client with access to the repository through
+the lockdiscovery property. Therefore, a server must provide its own
+authentication scheme. We currently do not support any authentication mechanism
+in the Webdav component. To realize locking, we need to support at least 1
+authentication model in the component.
+
+Solution attempt
+----------------
+
+The only possible authentication scheme provided through the HTTP protocol is
+HTTP-Auth. Therefore the HTTP-Auth information should be integrated into every
+request object, if provided. To check this information, an interface should be
+provided that provides the following capabilities:
+
+- Information of the assignment of a new lock token to a specific HTTP-Auth
+  user.
+- Removal of a lock token.
+- Answer to the question if a certain user may perform an action with a given
+  lock token.
+
+In addition we should provide a basic implementation of this class, which does
+actually not do anything but discard the given information and return true on
+authentication question. This will not provide any security, but allow users to
+plug their own authentication mechanisms into the lock facilities.
+
+Further thoughts
+----------------
+
+In future it might be possibly that a WebdavAuthenticationTiein is implemented,
+which might then be plugged into the described mechanism, too. This could in
+addition be used for a "plugin" that performs authentication (and possibly
+authorization?) in general on the transport/server level.
+
+Lock null resources
+===================
+
+The problem
+------------
+
+For our special case this means, that we need to "physically" create
+lock-null resources in the utilized back end, to make it persist during
+requests, whenever a null-lock is acquired. This lock-null resource must
+not appear as a real resource to the client (e.g. must not have a
+correct content type and must not respond to GET requests). If the
+resource is unlocked again, it must be removed from the back end again.
+
+In our internal handling, that means, that we need to intervene any of
+the operations not supported by a lock-null resource (e.g. COPY, MOVE,
+PROPPATCH) requests to check is a lock-null resource is affected and
+remove it potentially or forbid the operation. Furthermore, we need to
+intervene any operation that is supported by a lock-null resource to
+remove potential information from responses that must not be available
+for lock-null resources. This will mean a lot of internally generated
+requests to the back end and a lot of processing of the back end generated
+responses.
+
+For example, if a MOVE request is issued by a client, we need to check
+the whole affected directory tree for lock-null resources and remove
+those from the destination and send a special error code for them in the
+response.
+
+Atomicity of operations also comes into play here, since our internal
+requests to the back end might interfere with other external requests. For
+example, a null-lock might be acquired by the client while we are
+internally checking the correctness of a MOVE request (race-condition).
+
+Solution attempts
+-----------------
+
+I currently do not see a full solution for this problem, still there are
+some ideas in my mind, that might be helpful. For lock-null resources we
+can invent a special dead-property name space to indicate such resources.
+If a special (for lock-null resources forbidden) operation occurs, we
+can easily check for them using a PROPFIND request. Creating and
+maintaining lock-null resources should then be not problem.
+
+For the race-condition issue, we'll definitely need support in the
+back end, because I see no other solution attempt here to ensure the
+consistency.
+
 Common concerns
 ^^^^^^^^^^^^^^^
 
-This section introduces common concerns of the issues covered in this design
-document and the features resulting from them. Especially the if-header and its
-support in the Webdav component are described.
-
-=========================
-Plugin based design draft
-=========================
+This section describes the design to realize support for the If header, which
+is used in WebDAV with combinations of entity tags and lock tokens.
+
+============
+Plugin based
+============
 
 This section tries to design the honoring of the If header in the Webdav
 component using a plugin based approach for lock handling. This works
@@ -159,8 +438,8 @@
 will be contained, since the If header does not use tagging to specify which
 resources are affected by the conditions.
 
-Plugin
-======
+Plugin layer
+============
 
 If the lock plugin is active, it needs to hook into every affected request (see
 `Affected base methods`_) and check the If header conditions. The check does
@@ -267,276 +546,6 @@
 request object passes ezcWebdavServer, the headers are validated anyways there.
 
 
-Entity tag support
-^^^^^^^^^^^^^^^^^^
-
-This section describes the support of entity tags in the Webdav component, 
including
-the usage of the if-header with entity tags and the generation and sending of 
the
-ETag header.
-
-The following design only refers to the support of entity tags as defined in
-the HTTP/1.1 RFC. This includes the headers mentioned in the above RFC overview
-and the generation and comparison of entity tags.
-
-Entity tag generation
-=====================
-
-The generation of an entity tag requires uniqueness for the state of a resource
-(the so-called entity), To achieve this, multiple data of the resource and be
-involved and combined.
-
-The last modification time in combination with the file size should be a
-sufficient combination of data to generate an entity tag from. The Lighttpd
-web server uses this information on a configurable basis, too. In addition it
-can use the inode of the file for entity tag generation. Since inodes are
-operating system dependent and only available for file system based back ends,
-they will not be used in our entity tag generation scheme.
-
-Since entity tags in WebDAV are also available through the getetag
-live-property, a common way is needed to generate the entity tags for the
-headers and the property. The ezcWebdavSimpleBackend will therefore request the
-getetag property from the extending back end and use it's value for the headers
-and validation.
-
-The current generation of entity tags in ezcWebdavFileBackend will be replaced
-by a mechanism that uses the last modification time and the size of the file.
-It currently uses the path, which is not reliable and does not belong into the
-entity tag. Entity tags are only valid for a single resource and only in
-combination with its URI.
-
-Header handling
-===============
-
-The handling of entity tag related headers must take place in several different
-architecture levels of the Webdav component.
-
-Transport layer
----------------
-
-The transport layer needs to be able to parse the request headers and to
-serialize the response headers back. Therefore the ezcWebdavHeaderHandler class
-will be adjusted.
-
-The class must parse the following new request headers:
-
-- If-Match
-- If-None-Match
-
-ezcWebdavHeaderHandler will check if both of these headers are set. If this is
-the case, both headers will be silently discarded, since such a combination is
-undefined.
-
-Both headers can contain a list of weak/non-weak entity tags or the "*" value,
-to indicate that the resource must just exists, no matter in which state. To
-represent this in PHP, the parsed headers will be represented either as an
-array of string values or as the boolean value true. The headers will be parsed
-into every request object automatically, if they are set.
-
-The back end layer must take responsibility for interpreting the headers and
-their values.
-
-In addition, ezcWebdavHeaderHandler must take care of serializing an ETag
-header, if this one is present in a response object. Since the ETag header may
-only contain the string value of an entity tag, this mechanism is already
-implemented in the response processing.
-
-Back end layer
---------------
-
-The interpretation of incoming If-Match and If-None-Match headers must be done
-in the back end. The implementation will take place in the
-ezcWebdavSimpleBackend class. With every incoming request, no matter which
-request method is used, the If-Match and If-None-Match headers will be honored
-in the following way:
-
-If the back end determines that an If-Match header is set, it will:
-
-- Check if all preconditions (except the If-Match) are fulfilled.
-
-  - If not, return a corresponding error response.
-
-- Check if the If-Match value is a boolean true.
-  
-  - Check if the requested path exists.
-  
-  - If it *does not*, cancel the method and return 412 (Precondition Failed).
-
-- Check if the If-Match value is an array of strings.
-  
-  - Retrieve the affected resources getetag property and compare it with all
-    strings in the array.
-  
-  - If *none* matches, cancel the method and return 412 (Precondition Failed).
-
-- Process the method as if the If-Match header was not set.
-
-If the back end determines that an If-None-Match header is set, it will:
-
-- Check if all preconditions (except the If-Match) are fulfilled.
-  
-  - If not, return a corresponding error response.
-
-- Check if the If-Match value is a boolean true.
-  
-  - Check if the requested path exists.
-    
-    - If it *does*, cancel the method and return 412 (Precondition Failed).
-
-- Check if the If-Match value is an array of strings.
-  
-  - Retrieve the affected resources getetag property and compare it with all
-    strings in the array.
-    
-    - If *any* matches, cancel the method and return 412 (Precondition Failed).
-
-- Process the method as if the If-None-Match header was not set.
-
-Since this behavior will be implemented within the ezcWebdavSimpleBackend
-class, it automatically works with all extending back end classes. Back ends
-that do not extend ezcWebdavSimpleBackend will have to take care for these
-headers on their own.
-
-Lock support
-^^^^^^^^^^^^
-
-Locking allows a WebDAV client to gain exclusive access to a resource
-(collection or non-collection) to avoid the "lost update problem". This means
-that a client can define to have exclusive access to a resource for a certain
-time, where no other client may gain access to this resource.
-
-The WebDAV RFC distinguishes locks by 2 essential properties: The scope of the
-lock (shared vs. exclusive) and the type of the lock (write vs. read), while
-for the type only a write lock is specified. Using an exclusive lock the client
-ensures that he has absolutely exclusive access to the locked resource. With a
-shared lock it is possible the multiple clients take part in one and the same
-lock. More information on lock scopes are provided later.
-
-Locking
-^^^^^^^
-
-===================
-Plugin design draft
-===================
-
-This section describes a potential realization of locking through a plugin for
-the Webdav component. This plugin will make use of the, not yet officially
-released, plugin API.
-
-Design goals
-============
-
-This design drafts goal is to build a lock plugin that is almost completely
-independent from the used back end. In this sense, the requirements to be
-fulfilled by a back end must be cut down as far as possible. Beside that, the
-plugin should provide the largest possible compatibility to clients. However a
-plugin that hooks into the parsing process cannot provide the same client
-compatibility mechanisms as the base Webdav transport layer.
-
-Hooks
-=====
-
-The plugin needs to assign to several hooks offered by the plugin API, which
-will be described roughly in this section.
-
-parseUnknownRequest (ezcWebdavTransport)
-----------------------------------------
-
-The requests LOCK and UNLOCK are dedicated to the locking mechanism. Therefore
-the plugin needs to hook into parseUnknownRequest and parse the incoming
-requests into (new) corresponding request objects.
-
-
-
-===========
-Open issues
-===========
-
-Authentication
-==============
-
-The problem
------------
-
-The WebDAV RFC specifies that lock tokens are not secure for authentication
-since the can be obtained by every client with access to the repository through
-the lockdiscovery property. Therefore, a server must provide its own
-authentication scheme. We currently do not support any authentication mechanism
-in the Webdav component. To realize locking, we need to support at least 1
-authentication model in the component.
-
-Solution attempt
-----------------
-
-The only possible authentication scheme provided through the HTTP protocol is
-HTTP-Auth. Therefore the HTTP-Auth information should be integrated into every
-request object, if provided. To check this information, an interface should be
-provided that provides the following capabilities:
-
-- Information of the assignment of a new lock token to a specific HTTP-Auth
-  user.
-- Removal of a lock token.
-- Answer to the question if a certain user may perform an action with a given
-  lock token.
-
-In addition we should provide a basic implementation of this class, which does
-actually not do anything but discard the given information and return true on
-authentication question. This will not provide any security, but allow users to
-plug their own authentication mechanisms into the lock facilities.
-
-Further thoughts
-----------------
-
-In future it might be possibly that a WebdavAuthenticationTiein is implemented,
-which might then be plugged into the described mechanism, too. This could in
-addition be used for a "plugin" that performs authentication (and possibly
-authorization?) in general on the transport/server level.
-
-Lock null resources
-===================
-
-The problem
-------------
-
-For our special case this means, that we need to "physically" create
-lock-null resources in the utilized back end, to make it persist during
-requests, whenever a null-lock is acquired. This lock-null resource must
-not appear as a real resource to the client (e.g. must not have a
-correct content type and must not respond to GET requests). If the
-resource is unlocked again, it must be removed from the back end again.
-
-In our internal handling, that means, that we need to intervene any of
-the operations not supported by a lock-null resource (e.g. COPY, MOVE,
-PROPPATCH) requests to check is a lock-null resource is affected and
-remove it potentially or forbid the operation. Furthermore, we need to
-intervene any operation that is supported by a lock-null resource to
-remove potential information from responses that must not be available
-for lock-null resources. This will mean a lot of internally generated
-requests to the back end and a lot of processing of the back end generated
-responses.
-
-For example, if a MOVE request is issued by a client, we need to check
-the whole affected directory tree for lock-null resources and remove
-those from the destination and send a special error code for them in the
-response.
-
-Atomicity of operations also comes into play here, since our internal
-requests to the back end might interfere with other external requests. For
-example, a null-lock might be acquired by the client while we are
-internally checking the correctness of a MOVE request (race-condition).
-
-Solution attempts
------------------
-
-I currently do not see a full solution for this problem, still there are
-some ideas in my mind, that might be helpful. For lock-null resources we
-can invent a special dead-property name space to indicate such resources.
-If a special (for lock-null resources forbidden) operation occurs, we
-can easily check for them using a PROPFIND request. Creating and
-maintaining lock-null resources should then be not problem.
-
-For the race-condition issue, we'll definitely need support in the
-back end, because I see no other solution attempt here to ensure the
-consistency.
 
 
 ..


-- 
svn-components mailing list
svn-components@lists.ez.no
http://lists.ez.no/mailman/listinfo/svn-components

Reply via email to