Author: ts
Date: Tue Aug 7 12:06:20 2007
New Revision: 5830
Log:
- Updated regarding Kores and my discussions this morning.
Modified:
experimental/Webdav/design/design.txt
Modified: experimental/Webdav/design/design.txt
==============================================================================
--- experimental/Webdav/design/design.txt [iso-8859-1] (original)
+++ experimental/Webdav/design/design.txt [iso-8859-1] Tue Aug 7 12:06:20 2007
@@ -11,13 +11,12 @@
=====
The scope of this document is to describe the initial design of a component
-that provides a webdav server and a webdav client, which work with all major
-other implementations of the WebDAV_ protocol.
+that provides a WebDAV server, which works with all major other implementations
+of the WebDAV_ protocol.
.. _WebDAV_: http://en.wikipedia.org/wiki/WebDAV
-The client part of the component is not part of the initial design and will
-therefore be added in a future version.
+It is currently not planned to also offer a WebDAV client component.
Design overview
===============
@@ -40,114 +39,142 @@
clients. A factory pattern implementation will be provided, which takes
automatically care of creating the correct server instance for a client.
-Backends
---------
-
-Lock checking for all operations is done centrally in the server, which may
-dispatch to the backend - see below for details. There are several groups of
-methods which a backend should implement for full functionality:
-
-- Options
-
- Mandatory to implement?
-
-- Properties (propfind, propfetch)
-
- Mandatory to implement?
-
-- Make collection (mkcol)
-
- Mandatory to implement?
-
-- Writing (put)
-
- Mandatory to implement?
-
- There are several optional methods which may or may not be supported by the
- backend, like md5 checksum verfication, partial puts and content encoding.
- Do we want to provide interfaces for all of them, or just let the backend
- send "501 - Not implemented"?
-
- Some of them may be implemented directly in ther sever, so that again only
- optionally implement this in the backend for optimization or custom
- handling.
-
-- Changing (delete, copy, move)
-
- Mandatory to implement?
-
-- Get, Head
-
- GET seems to require support for partial data. Should this be done in the
- server? Multipart responses could be aggregated and served centrally by the
- server only with requests for contained files and collections to the
- backend?
-
-- Lock, Unlock
-
- Optionally done in the server with dead properties in the client, or
- dispatched to the client, if it implements ezcWebdavBackendCustomLocking
+Tiers
+=====
+
+The component is basically devided into 3 tiers: The top tier, being
+represented by the main server class. An instance of this class is responsible
+to dispatch a received request to a correct transport handler, which is capable
+of parsing the request.
+
+The transport handler level is the second tier. Classes in this tier are
+responsible to parse an incoming request and extract all relevant information
+to generate a response for it into a struct object. These struct object is then
+passed back to the server object.
+
+Based on the request struct object, the server checks the capabilities of its
+third tier, the used backend handler. If the handler object provides all
+necessary capabilities to generate a response, it is called to do so. If the
+server class can perform emulation of not available capabilities and rely on
+different features of the backend. In case there is no way, the backend can
+handle, the request, the server class will indicate that with an error
+response.
+
+The way back flows through the 3 tiers back again: The backend handler
+generates a response object, which is passed back to the main server object,
+which makes the active transport handler encode the response and sends it back
+to the client.
Classes
=======
-Request processing
-------------------
-
ezcWebdavServer
-
- Implements a method handle() which is called to process a request by a
- client. Basing on the client name optionally dispatches to specialized
- request reader / writer.
-
-ezcWebdavRequestReader
-
- Standard conform class for parsing and interpreting requests to the
webdav
- server. Specialized extensions of this class may be registered in the
main
- handler for misbehaving clients.
-
-ezcWebdavRequestWriter
-
- Standard conform class for responding requests to the webdav server.
- Specialized extensions of this class may be registered in the main
handler
- for misbehaving clients.
-
-Backends
---------
-
-ezcWebdavBackend
-
- Abstract base class for all webdav backends.
-
-ezcWebdavBackendFile
-
- Implementation of a webdav backend serving the contents of a directory
- tree.
-
-ezcWebdavBackendCustomLocking
-
- Interface implemented by backends which hanled the locking itself.
-
-Suggestions for more interfaces
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-ezcWebdavBackendPartial(?:Read|Write)?
-
- Support for partial requests in the backend. Server do not need to
handle
- this.
-
-ezcWebdavBackendLanguage
-
- Backend knows about content language
-
-ezcWebdacBackendEncoding(?:bzip2|gz)?
-
- Backend may encode / compress the content itself, no action by the
server
- required.
+---------------
+
+The ezcWebdavServer class is the main class of the package. It has to be
+instantiated to create a server instance and provides a method to get the
+server up and running. An object of this class takes the main controll over
+serving the webdav service.
+
+Among the configuration of the server instance there must be: A backend handler
+object, which will be used to serve the received WebDAV requests. A fitting
+configuration for the backend handler. A collection of transport handlers which
+can be used to parse incoming requests. General configuration on the bevahiour
+of the server instance (like locking and stuff).
+
+The backend handler object must extend the base class ezcWebdavBackendHandler
+and must indicate to the main server, which capabilities it provides. The
+server class can potentially emulate certain capabilities, if the handler does
+not provide it. An example here is locking, which can be either performed by
+the handler itself or the main server class.
+
+Such emulation functionality could possibly be extracted to a third category of
+classes, which is only loaded by the main server object on-demand.
+
+All configured transport handlers must implement the interface
+ezcWebdavTransportHandler, which defines the ncessary methods.
+
+ezcWebdavBackendHandler
+-----------------------
+
+All backend handlers for the Webdav component must extends this abstract base
+class and implement its abstract methods for very basic WebDAV serving. The
+operations defined for every backend handler to be mandatory are:
+
+- head()
+- get()
+- propFind()
+- propFetch()
+
+All other WebDAV operations are optional to be implemented by a backend handler
+and are defined by the handler itself. It is an open issue, if the handlers
+should implement different interfaces, to indicate different capabilities or if
+a bitmask or similar mechanisms are more efficient here.
+
+The logical groups of capabilities are:
+
+Put
+ The put capability indicates, that a handler is capable of handling file
+ uploads via HTTP-PUT method.
+Change
+ This sub class of WebDAV operations defines delete, copy and move operations
to
+ be supported by the handler class.
+Make collection
+ The creation of new collections also makes up a capability unit and can
+ optionally be implemented.
+Lock
+ If the hander provides locking facilities on its own, the main server object
+ must not take care about that.
+GZIP-Compress
+ Handlers implementing this facility can deal with GZIP based compression.
+
+
+If a handler does not support a certain facility and the main server object is
+not capable of emulating it with existing facilities, the server will respond
+using a "501" server error, "Not implemented".
+
+ezcWebdavTransportHandler
+-------------------------
+
+A class implementing this interface is capable of parsing a raw HTTP request
+into a struct extending ezcWebdavRequest. One transport handler is usually
+built to handle the communication with a certain set of specific client
+implementations.
+
+A transport handler class will be able to parse the incoming HTTP request data
+into a struct identifying a certain type of request and containg all necessary
+and unified data, so that a backend handler can repsond to it.
+
+The backend handler will then create a corresponding response object, which
+will be encoded back into HTTP data by the transport handler and send to the
+client by the server.
+
+Each request type will come with its own struct classes to represent request
+and response data for the request. Beside the structured HTTP data, the structs
+can contain any additional information that must be transferred between server,
+transport handler and backend handler.
+
+All struct classes representing either a request of response of the server will
+extend the abstract base classes ezcWebdavRequest and ezcWebdavResponse.
+
+An example of this structure is: ezcWebdavGetRequest and ezcWebdavGetResponse
+
+These 2 classes will be used to serve GET requests. Beside the usual request
+information - like URI, date and headers - the request object will contain
+information about partial GET mechanisms to use and what else is important.
+The backend handler will return an instance of ezcWebdavGetResponse if the
+request was handled correctly, or a corresponding error object, if the
+request failed.
+
+An open issue is, how the server instance can figure out best, which transport
+to use.
Example code
============
+The following snippet shows the API calls necessary to get a WebDAV server up
+and running.
+
::
<?php
@@ -157,33 +184,93 @@
// Server data using file backend with data in "path/"
$server->backend = new ezcWebdavBackendFile( '/path' );
- // Register custom reader implementation to extend the list of already
- // used special implementations
- $server->registerReader(
+ // Register transport handlers
+ $server->registerTransportHandler(
// Regular expression to match client name
'(Microsoft.*Webdav\s+XP)i',
- // Class name of reader, extending ezcWebdavRequestReader
- 'customWebdavMicrosoftRequestReader'
+ // Class name of transport handler, extending
ezcWebdavTransportHandler
+ 'ezcWebdavMicrosoftTransport'
);
-
- // Serve request
+ $server->registerTransportHandler(
+ // Regular expression to match client name
+ '(.*Firefox.*)i',
+ // Class name of transport handler, extending
ezcWebdavTransportHandler
+ 'ezcWebdavMozillaTransport'
+ );
+
+ // Serve requests
$server->handle();
-Algorithms
-==========
-
-Algorithms to select proper reader and writers for parsing and serving a
-request.
-
-Select reader / writer
-----------------------
-
-The standard webdav server contains a list of readers and writers associated
-with regular expressions which should match the client name to be used. As a
-fallback the standards complient reader / writer will be used.
-
-Special implementation added by the user will be add on top of the list, to be
-used at highest priority.
+Open issues
+===========
+
+There are several open issues which need to be discussed before starting to
+implement this design:
+
+Capabilities
+------------
+
+Backend handlers can offer several different capabilities as noted in the
+specific section. It is not set, if the indication of supported capabilities
+should be done by implementing interfaces or going another way.
+
+Implementing interfaces would be a nice, OO-style solution, but can possibly
+end up in a huge lot of interfaces and possibly with interfaces that don't
+indicate any methods. For example, every handler needs to support GET and can
+optioanlly support partial GET. There are several ways, how a handler can
+indicate that he supports this:
+
+The implementation of an interface is the most plausible one: ::
+
+ <?php
+
+ interface ezcWebdavPartialGetHandler
+ {
+ public function partialGet();
+ }
+
+ ?>
+
+Going this way, we end up with 1 method for every special case for a
+handler, which will result in messy code in the main server class, which needs
+to check for several methods and interfaces, which could satisfy a request and
+then choose the right method of the right interface to perform the work.
+
+The second option is, to let the handler implement empty interfaces and just
+let those be used for declarative purposes. That way, the above shown example
+would implement ::
+
+ <?php
+
+ interface ezcWebdavPartialGetHandler
+ {
+ }
+
+ ?>
+
+The server class could then use the interface to determine the capability of
+partial GET and utilize the usual get() method to initialize the operation and
+possibly add a parameter for partiality to the request struct.
+
+The third alternative is to not use interfaces but a bitmask for handlers to
+indicate their capabilities. This will possibly the fastest and cleanest way,
+because one can define fine graned stages of capability support and can easily
+check on different capabilities.
+
+Suitable transport
+------------------
+
+Another open issue is the mechanism to identify a suitable transport handler
+for a certain request. Currently, the main server instance will know about
+available clients and will have a regular expression for each of them, to
+identify the clients it communicates to. The regex must be defined by the user,
+while registering the handler.
+
+It is not clear, if 1 regex into 1 header field is enough to identify the
+handler correctly every time. Therefore, it must be discussed, if handlers
+shouldn't better have a static method like canParse() to perform the parsing
+checks on their own. That way, the mechanism to identify the correct handler is
+much more flexible, but all classes need to be loaded on every request.
..
--
svn-components mailing list
[EMAIL PROTECTED]
http://lists.ez.no/mailman/listinfo/svn-components