# HG changeset patch # User paulb # Date 1189267338 0 # Node ID 9156c2205b8f2f5cf8c0e9106465bed6c2969218 # Parent 5ea48ef5ca2ce74619decaee299daf49c2685268 [project @ 2007-09-08 16:02:18 by paulb] Tidied the documentation HTML, adding XML declarations, removing entities, reformatting in some cases. diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/anatomy.html --- a/docs/anatomy.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/anatomy.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Anatomy of a WebStack Application + Anatomy of a WebStack Application @@ -58,4 +58,4 @@ - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/attributes.html --- a/docs/attributes.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/attributes.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Transaction Attributes + Transaction Attributes

Transaction Attributes

@@ -54,4 +54,4 @@ customer departments. This resource would do the following:

  1. Ask for the path without info, along with the processed virtual path info (as described in "Paths To and Within Applications").
  2. Join the paths together.
  3. Store the result on an attribute (called "root", perhaps).
  4. Invoke another resource.

The advantage of doing this dynamically is that should we decide to change the location of the application or the path to services within it, we will not need to track down hard-coded path values and change them in lots of different places.

Fortunately, WebStack provides a class to do this work for us - PathSelector - and we can use it in the following way:

from WebStack.Resources.Selectors import PathSelector

resource = MapResource({
"services" : PathSelector(
MapResource({
"finance" : finance_department,
"customer" : customer_department
})
)
})

Now, once the services part of the path has been detected, the PathSelector resource will discover the path details, store them on an attribute, and then invoke the MapResource which chooses between departments, which in turn invokes other resources, and so on. However, all of the resources "below" the PathSelector resource will have an attribute called "root" which contains the selected "root path" of the application (or at least the interesting part of the -application).

See the "Selectors" document for more details of the PathSelector class.

\ No newline at end of file +application).

See the "Selectors" document for more details of the PathSelector class.

diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/authenticators.html --- a/docs/authenticators.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/authenticators.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,9 +1,8 @@ + Application-Wide Authenticators - diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/cookies.html --- a/docs/cookies.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/cookies.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,10 +1,9 @@ + Cookies - diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/deploying-applications.html --- a/docs/deploying-applications.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/deploying-applications.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Deploying an Application + Deploying an Application

Deploying an Application

@@ -77,4 +77,4 @@
  • WSGI
  • Zope 2
  • - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/deploying.html --- a/docs/deploying.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/deploying.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,9 +1,8 @@ + - - Deploying a WebStack Application + Deploying a WebStack Application -

    Deploying a WebStack Application

    The process of deploying a WebStack application should be as @@ -47,4 +46,4 @@

  • Getting PYTHONPATH Right
  • Deploying an Application
  • - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/design.html --- a/docs/design.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/design.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Application Design Considerations + Application Design Considerations

    Application Design Considerations

    @@ -59,4 +59,4 @@
  • Cookies, Sessions, Users and Persistent Information
  • - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/developing.html --- a/docs/developing.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/developing.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,85 +1,48 @@ + - - - Developing a WebStack Application + Developing a WebStack Application

    Developing a WebStack Application

    Many different topics are involved in the development of WebStack applications; below is a map of each of the topics covered in this -documentation (with related example material found in the examples/Common directory given beside certain topics):

    +documentation (with related example material found in the examples/Common directory given beside certain topics):

    The following topic is referenced in many locations and should +

  • Securing a WebStack Application
  • Integrating with Other Systems
  • +

    The following topic is referenced in many locations and should be reviewed when encountering problems with input and output text:

    Deployment

    The following topics (illustrated by the programs found in the other subdirectories of the examples directory) describe how WebStack applications may be deployed in server environments:

    Useful Additions

    WebStack +Features in Server Environments +

    Useful Additions

    WebStack provides a number of potentially useful modules either providing resource classes for direct use in applications, or providing other kinds of classes and functions which may be used to perform particular -activities.

    The following resources are provided for direct use in applications:

    WebStack also provides modules which provide session-like access to different kinds of repositories:

    \ No newline at end of file +activities.

    The following resources are provided for direct use in applications:

    WebStack also provides modules which provide session-like access to different kinds of repositories:

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/directory-repository.html --- a/docs/directory-repository.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/directory-repository.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,32 +1,32 @@ + - - DirectoryRepository - Simple Access to Files in a Directory + DirectoryRepository - Simple Access to Files in a Directory

    DirectoryRepository - Simple Access to Files in a Directory

    -

    In applications it is often convenient to be able to save or remember information provided or edited by a user. Whilst sessions +

    In applications it is often convenient to be able to save or remember information provided or edited by a user. Whilst sessions often provide a convenient means of remembering such information, they have certain limitations, notably that they are only available to a particular user and cannot be shared with other users, and that their data is stored in a form that is not necessarily convenient to access -by other tools or systems.

    The principle behind the DirectoryRepository +by other tools or systems.

    The principle behind the DirectoryRepository class is that it stores information as files in a designated directory, that such files can be accessed by any resource with access to that directory, and that a certain degree of locking is provided to avoid -contention between resources. Once created, instances of DirectoryRepository +contention between resources. Once created, instances of DirectoryRepository can be accessed almost like sessions, although it is possible to obtain the full paths to files in the repository and to use file objects and -methods to obtain and deposit content in such files.

    WebStack API - DirectoryRepository Initialisation

    The DirectoryRepository class (found in the WebStack.Repositories.Directory module) accepts the following parameters when being initialised:

    path
    This parameter specifies the path to the directory in the filesystem where repository files are to be stored.
    fsencoding
    This +methods to obtain and deposit content in such files.

    WebStack API - DirectoryRepository Initialisation

    The DirectoryRepository class (found in the WebStack.Repositories.Directory module) accepts the following parameters when being initialised:

    path
    This parameter specifies the path to the directory in the filesystem where repository files are to be stored.
    fsencoding
    This optional parameter specifies the character encoding employed by the filesystem to represent filenames. If left unspecified, the implementation will attempt to guess the correct encoding or, where supported, to use Unicode filenames.
    delay
    This optional parameter specifies a delay period for which a program will be made to wait if a repository file is found to be locked by another -process.

    Initialisation Strategies

    One might choose to initialise a repository in the initialisation method of a resource:

    # Inside a module defining a resource...

    class MyResource:
    def __init__(self):
    repository_dir = os.path.join(os.path.split(__file__)[0], "repository")
    self.repository = DirectoryRepository(repository_dir, "iso-8859-1")

    Here, the repository will reside alongside the resource's module in the filesystem.

    Session-like Access

    One might use a repository with a session-like API as follows:

    # Given a name and some data, possibly provided in user input, store the data in the repository.

    repository[name] = data

    Note that DirectoryRepository +process.

    Initialisation Strategies

    One might choose to initialise a repository in the initialisation method of a resource:

    # Inside a module defining a resource...

    class MyResource:
    def __init__(self):
    repository_dir = os.path.join(os.path.split(__file__)[0], "repository")
    self.repository = DirectoryRepository(repository_dir, "iso-8859-1")

    Here, the repository will reside alongside the resource's module in the filesystem.

    Session-like Access

    One might use a repository with a session-like API as follows:

    # Given a name and some data, possibly provided in user input, store the data in the repository.

    repository[name] = data

    Note that DirectoryRepository places some restrictions on the values that can be used as keys in the session-like API since each key must correspond to a filename within -the designated directory.

    Advanced Access

    The DirectoryRepository class also provides various methods to support access to files in the repository using standard file objects and methods:

    # Given a name and some data...

    edit_path = repository.lock(name)
    f = open(edit_path, "wb")
    try:
    f.write(data)
    finally:
    f.close()
     repository.unlock(name)

    The usage of try and finally +the designated directory.

    Advanced Access

    The DirectoryRepository class also provides various methods to support access to files in the repository using standard file objects and methods:

    # Given a name and some data...

    edit_path = repository.lock(name)
    f = open(edit_path, "wb")
    try:
    f.write(data)
    finally:
    f.close()
    repository.unlock(name)

    The usage of try and finally clauses is important to ensure that files are not left locked and -inaccessible due to unhandled exceptions being raised. See the API documentation for the DirectoryRepository class for more information about the available methods and their behaviour.

    +inaccessible due to unhandled exceptions being raised. See the API documentation for the DirectoryRepository class for more information about the available methods and their behaviour.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/directory-resource.html --- a/docs/directory-resource.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/directory-resource.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,16 +1,16 @@ + - - DirectoryResource - Serving Static Content + DirectoryResource - Serving Static Content

    DirectoryResource - Serving Static Content

    -

    The DirectoryResource class provides a means to +

    The DirectoryResource class provides a means to serve static files from within a particular directory in the filesystem. By inspecting the remainder of the path information -supplied in an incoming request, instances of DirectoryResource may identify files and serve their contents as a response to such a request.

    There are various situations where providing static content is virtually essential:

    By instantiating DirectoryResource classes and deploying them in conjunction with MapResource objects (see the "ResourceMap - Simple Mappings from Names to Resources" document), it should be possible to retain control of the serving of static content within a WebStack application. Note, however, that the performance of a system can be improved if the job of serving static @@ -18,10 +18,10 @@ for example, set up an Apache Web server to serve things like stylesheets, script files and images, and then link to the locations of such things in the Web pages generated by the WebStack application.

    WebStack API - The DirectoryResource Class

    -

    Given a directory from which files shall be served, DirectoryResource uses a simple method to identify files to serve. First, it examines the virtual "path info" and takes the first component of that information. For example, consider the following path information:

    /styles.css

    Here, DirectoryResource identifies the file to be served as having the name styles.css. Note that any trailing path information would be ignored; for example:

    /styles/abc

    Here, the file to be served would be identified as having the name styles.

    Handling Missing Files

    Where -no file exists in the specified directory with the identified +

    Given a directory from which files shall be served, DirectoryResource uses a simple method to identify files to serve. First, it examines the virtual "path info" and takes the first component of that information. For example, consider the following path information:

    /styles.css

    Here, DirectoryResource identifies the file to be served as having the name styles.css. Note that any trailing path information would be ignored; for example:

    /styles/abc

    Here, the file to be served would be identified as having the name styles.

    Handling Missing Files

    Where +no file exists in the specified directory with the identified name, a "file not found" response code is set by the resource and a -message is emitted. To modify the simple behaviour of DirectoryResource in this regard, it is recommended that a subclass of DirectoryResource is defined with its own implementation of the not_found method.

    Types of Served Files

    Given +message is emitted. To modify the simple behaviour of DirectoryResource in this regard, it is recommended that a subclass of DirectoryResource is defined with its own implementation of the not_found method.

    Types of Served Files

    Given that a file exists in the specified directory, it is usually critical that the file is served along with special file type information so that a user's Web browser may understand the nature of the file's @@ -29,11 +29,11 @@ a file type indicating that the contents of the file are HTML (or some variant thereof). Instances of DirectoryResource employ a special registry mapping filename extensions to file types in order -to automate the process of deciding what type a file might be.

    Using the content_types parameter (see below), one might choose to serve all files whose names have the .html extension with the HTML file (or content) type. This would be expressed with the following dictionary:

    {"html" : WebStack.Generic.ContentType("text/html", "utf-8")}

    Note that the . +to automate the process of deciding what type a file might be.

    Using the content_types parameter (see below), one might choose to serve all files whose names have the .html extension with the HTML file (or content) type. This would be expressed with the following dictionary:

    {"html" : WebStack.Generic.ContentType("text/html", "utf-8")}

    Note that the . character is omitted from the filename extension. Where it is tedious to create content type objects and where the same character encoding -applies for all types of files, it is possible to use the media_types and default_encoding parameters instead.

    Further Reading

    The API documentation for the DirectoryResource class provides more information on the usage of the class.

    Initialisation

    The DirectoryResource class (found in the WebStack.Resources.Static module) accepts the following parameters when being initialised:

    -
    directory
    The directory from which static files shall be served.
    media_types
    A dictionary or dictionary-like object mapping filename extensions to media types.
    unrecognised_media_type
    An optional parameter setting the media type for files whose extensions do not map to any media type according to the media_types parameter.
    content_types
    A dictionary or dictionary-like object mapping filename extensions to content type objects (such as WebStack.Generic.ContentType).
    unrecognised_content_type
    An optional parameter setting the content type for files whose extensions do not map to any content type according to the content_types parameter.
    default_encoding
    An optional parameter setting the character encoding for all media types defined in the media_types and unrecognised_media_type parameters. If not specified, no character encoding will be stated for content associated with such media types.
    urlencoding
    When +applies for all types of files, it is possible to use the media_types and default_encoding parameters instead.

    Further Reading

    The API documentation for the DirectoryResource class provides more information on the usage of the class.

    Initialisation

    The DirectoryResource class (found in the WebStack.Resources.Static module) accepts the following parameters when being initialised:

    +
    directory
    The directory from which static files shall be served.
    media_types
    A dictionary or dictionary-like object mapping filename extensions to media types.
    unrecognised_media_type
    An optional parameter setting the media type for files whose extensions do not map to any media type according to the media_types parameter.
    content_types
    A dictionary or dictionary-like object mapping filename extensions to content type objects (such as WebStack.Generic.ContentType).
    unrecognised_content_type
    An optional parameter setting the content type for files whose extensions do not map to any content type according to the content_types parameter.
    default_encoding
    An optional parameter setting the character encoding for all media types defined in the media_types and unrecognised_media_type parameters. If not specified, no character encoding will be stated for content associated with such media types.
    urlencoding
    When specified, this parameter forces a particular interpretation of "URL encoded" character values in the path. Otherwise, the default encoding -is employed to interpret such values. (See "URLs and Paths" for an explanation of "URL encoded" values.)

    Combining MapResource with DirectoryResource

    One might combine MapResource with DirectoryResource to provide stylesheet and script file directories for an application as follows:

    from WebStack.Resources.ResourceMap import MapResource
    from WebStack.Resources.Static import DirectoryResource

    # This is where the application's resources would be obtained.

    app_resource = ...

    # Here is where we combine MapResource and DirectoryResource.
    # Note that one would not necessarily hard-code directory paths into the application.

    top_resource = MapResource({
    "styles" : DirectoryResource("/usr/share/apps/MyApp/styles", media_types={"css" : "text/css"}),
    "scripts" : DirectoryResource("/usr/share/apps/MyApp/scripts", media_types={"js" : "text/javascript"}),
    "" : app_resource
    })

    In the above example, any file in the styles directory whose name ends with .css is served as text/css. Similarly, any file in the scripts directory whose name ends with .js is served as text/javascript.

    \ No newline at end of file +is employed to interpret such values. (See "URLs and Paths" for an explanation of "URL encoded" values.)

    Combining MapResource with DirectoryResource

    One might combine MapResource with DirectoryResource to provide stylesheet and script file directories for an application as follows:

    from WebStack.Resources.ResourceMap import MapResource
    from WebStack.Resources.Static import DirectoryResource

    # This is where the application's resources would be obtained.

    app_resource = ...

    # Here is where we combine MapResource and DirectoryResource.
    # Note that one would not necessarily hard-code directory paths into the application.

    top_resource = MapResource({
    "styles" : DirectoryResource("/usr/share/apps/MyApp/styles", media_types={"css" : "text/css"}),
    "scripts" : DirectoryResource("/usr/share/apps/MyApp/scripts", media_types={"js" : "text/javascript"}),
    "" : app_resource
    })

    In the above example, any file in the styles directory whose name ends with .css is served as text/css. Similarly, any file in the scripts directory whose name ends with .js is served as text/javascript.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/encodings.html --- a/docs/encodings.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/encodings.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Character Encodings + Character Encodings

    Character Encodings

    @@ -19,16 +19,16 @@ users of your application, the text will be in some kind of character encoding. For example, in English-speaking environments, the US-ASCII encoding is common and contains the basic letters, numbers and symbols -used in English, whereas in Western Europe encodings like -ISO-8859-1 and ISO-8859-15 are typically used, since they contain +used in English, whereas in Western Europe encodings like +ISO-8859-1 and ISO-8859-15 are typically used, since they contain additional letters and symbols in order to support other languages. Often, UTF-8 is used to encode text because it covers most languages simultaneously and is therefore flexible enough for many applications.

    When URLs are received in applications, in order for some of the request parameters to be interpreted, the situation is a bit more awkward. The original text is encoded in US-ASCII but will contain -special numeric codes that indicate character values in the -original text encoding - see the description +special numeric codes that indicate character values in the +original text encoding - see the description of query strings for more information.

    Recommendations

    @@ -47,7 +47,7 @@
  • If you must include hard-coded messages in your application code, make sure to specify the encoding using the standard declaration at the top of your source file.
  • -
  • Remember that the standard library codecs +
  • Remember that the standard library codecs module contains useful functions to access streams as if Unicode objects were being transmitted; for example:
  • @@ -73,14 +73,14 @@ can be used directly with various transaction methods. Here is an outline of code which does this:

    from WebStack.Generic import ContentType

    class MyResource:

    encoding = "utf-8" # We decide on "utf-8" as our chosen
    # encoding.
    def respond(self, trans):
    [Do various things.]

    fields = trans.get_fields_from_body(encoding=self.encoding) # Explicitly use the encoding.

    [Do other things with the Unicode values from the fields.]

    trans.set_content_type(ContentType("text/html", self.encoding)) # The output Web page uses the encoding.

    [Produce the response, making sure that self.encoding is used to convert Unicode to raw strings.]
    -

    Use EncodingSelector to Set the Default Encoding

    An arguably better approach is to use selectors (as described in "Selectors - Components for Dispatching to Resources"), typically in a "site map" arrangement (as described in "Deploying a WebStack Application"), specifically using the EncodingSelector:

    from WebStack.Generic import ContentType

    class MyResource:

    def respond(self, trans):
    [Do various things.]

    fields = trans.get_fields_from_body() # Encoding set by EncodingSelector.

    [Do other things with the Unicode values from the fields.]

    trans.set_content_type(ContentType("text/html")) # The output Web page uses the default encoding.

    [Produce the response, making sure that self.encoding is used to convert Unicode to raw strings.]

    def get_site_map():

    return EncodingSelector(MyResource(), "utf-8")

    Tell Encodings to Other Components

    +

    Use EncodingSelector to Set the Default Encoding

    An arguably better approach is to use selectors (as described in "Selectors - Components for Dispatching to Resources"), typically in a "site map" arrangement (as described in "Deploying a WebStack Application"), specifically using the EncodingSelector:

    from WebStack.Generic import ContentType

    class MyResource:

    def respond(self, trans):
    [Do various things.]

    fields = trans.get_fields_from_body() # Encoding set by EncodingSelector.

    [Do other things with the Unicode values from the fields.]

    trans.set_content_type(ContentType("text/html")) # The output Web page uses the default encoding.

    [Produce the response, making sure that self.encoding is used to convert Unicode to raw strings.]

    def get_site_map():

    return EncodingSelector(MyResource(), "utf-8")

    Tell Encodings to Other Components

    When using other components to generate content (see "Integrating with Other Systems"), it may be the case that such components will just write the generated content -straight to a normal stream (rather than one wrapped by a codecs +straight to a normal stream (rather than one wrapped by a codecs module function). In such cases, it is likely that for textual content such as XML or related formats (XHTML, SVG, HTML) you will need to instruct the component to use your chosen encoding; for example:

            # In the respond method, xml_document is an xml.dom.minidom.Document object...
    xml_document.toxml(self.encoding)

    This will then generate the appropriate characters in the output and specify the correct encoding for the XML document.

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/features.html --- a/docs/features.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/features.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,12 +1,11 @@ + - - Support for WebStack Features in Server Environments + Support for WebStack Features in Server Environments - -

    Support for WebStack Features in Server Environments

    +

    Support for WebStack Features in Server Environments

    Some basic features of Web applications are not supported by all server environments or frameworks. The table below summarises the implementation details of such features when applications are deployed @@ -68,4 +67,4 @@ on certain frameworks.

  • Some mod_python releases do not provide session support directly.
  • - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/file-resource.html --- a/docs/file-resource.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/file-resource.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,15 +1,16 @@ + - - - DirectoryResource - Serving Static Content + + + DirectoryResource - Serving Static Content

    FileResource - Serving Individual Files

    -

    The FileResource class provides a means to -serve individual static files from the +

    The FileResource class provides a means to +serve individual static files from the filesystem. Although a DirectoryResource object may serve files having specific filename extensions as particular types from a filesystem directory, we sometimes need to -select individual files from special locations and serve their -contents as part of a response.

    WebStack API - FileResource Initialisation

    The FileResource class (found in the WebStack.Resources.Static module) accepts the following parameters when being initialised:

    -
    filename
    The full path to the particular static file being served.
    content_type
    A content type object (such as WebStack.Generic.ContentType) providing sufficient information for user agents to interpret the file's contents.

    Combining MapResource with FileResource

    One might combine MapResource with FileResource to provide a favicon.ico image for an application as follows:

    from WebStack.Resources.ResourceMap import MapResource
    from WebStack.Resources.Static import FileResource

    # This is where the application's resources would be obtained.

    app_resource = ...

    # Here is where we combine MapResource and FileResource.
    # Note that one would not necessarily hard-code directory paths into the application.

    top_resource = MapResource({
    "favicon.ico" : FileResource("/usr/share/apps/MyApp/images/py.ico"), ContentType("image/x-icon")),
    "" : app_resource
    })

    In the above example, the favicon.ico file in the images directory is served as image/x-icon.

    \ No newline at end of file +select individual files from special locations and serve their +contents as part of a response.

    WebStack API - FileResource Initialisation

    The FileResource class (found in the WebStack.Resources.Static module) accepts the following parameters when being initialised:

    +
    filename
    The full path to the particular static file being served.
    content_type
    A content type object (such as WebStack.Generic.ContentType) providing sufficient information for user agents to interpret the file's contents.

    Combining MapResource with FileResource

    One might combine MapResource with FileResource to provide a favicon.ico image for an application as follows:

    from WebStack.Resources.ResourceMap import MapResource
    from WebStack.Resources.Static import FileResource

    # This is where the application's resources would be obtained.

    app_resource = ...

    # Here is where we combine MapResource and FileResource.
    # Note that one would not necessarily hard-code directory paths into the application.

    top_resource = MapResource({
    "favicon.ico" : FileResource("/usr/share/apps/MyApp/images/py.ico"), ContentType("image/x-icon")),
    "" : app_resource
    })

    In the above example, the favicon.ico file in the images directory is served as image/x-icon.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/headers.html --- a/docs/headers.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/headers.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,21 +1,19 @@ + - - - Request Headers + Request Headers

    Request Headers

    -

    Request headers are pieces of information that describe certain aspects of a request, such as:

    -

    The location and related query information is conveniently accessible through path information and request header parameter information. Other types of header information are made available through other WebStack API methods.

    +

    The location and related query information is conveniently accessible through path information and request header parameter information. Other types of header information are made available through other WebStack API methods.

    Content Types

    When a Web application sends some information in a response, it describes the content type of that information, and this is described @@ -28,7 +26,7 @@

    Unfortunately, such information is not always provided by Web browsers.

    Content Preferences

    -

    Sometimes, Web browsers describe the kinds of information that +

    Sometimes, Web browsers describe the kinds of information that they are willing to receive, and WebStack provides various means to query such preferences:

    @@ -52,7 +50,7 @@
    get_header_values
    Given a header name as parameter, this method returns a list of string values associated with that name.
    get_content_type
    -
    This returns a content type object (typically WebStack.Generic.ContentType) describing the incoming request body content.
    +
    This returns a content type object (typically WebStack.Generic.ContentType) describing the incoming request body content.
    get_content_languages
    This returns a list of language identifiers, in descending order of preference, indicating in which languages the sender of the request @@ -63,8 +61,8 @@ the request would prefer to receive information.
    -

    It should be noted that the get_headers and get_header_values methods +

    It should be noted that the get_headers and get_header_values methods present a slightly different view of the available header information, -in that only a single header value is made available through the get_headers method for each header name, whereas get_header_values provides potentially many values for the same header name.

    +in that only a single header value is made available through the get_headers method for each header name, whereas get_header_values provides potentially many values for the same header name.

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/index.html --- a/docs/index.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/index.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Creating Web Applications with WebStack + Creating Web Applications with WebStack

    Creating Web Applications with WebStack

    @@ -29,11 +29,11 @@ you may wish to investigate the other supported frameworks in order to run WebStack applications in other environments.

    Viewing the API Documentation

    The API documentation for use in conjunction with this -guide can be found inside the apidocs +guide can be found inside the apidocs directory within the WebStack-1.2.5 directory. Of course, it is always possible to view WebStack's API documentation -within Python by importing modules (such as WebStack.Generic) -and using Python's built-in help function.

    +within Python by importing modules (such as WebStack.Generic) +and using Python's built-in help function.

    About WebStack Applications

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/integrating.html --- a/docs/integrating.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/integrating.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,19 +1,18 @@ + Integrating with Other Systems -

    Integrating with Other Systems

    Most Web applications are not self-contained - instead of -providing information which is written into the application -code itself, they may often access data from other places or even +providing information which is written into the application +code itself, they may often access data from other places or even communicate with other systems. Since applications may be very -different in the way that they access external systems or the way +different in the way that they access external systems or the way in which they obtain external information, WebStack does not mandate rigid mechanisms for hooking into such systems or loading such information. Instead, it is recommended that applications import @@ -51,7 +50,7 @@ the above code is itself imported into Python. - Use the urlopen + Use the urlopen function of urllib to actually access a remote service. This happens in the resource code each time the resource decides to access the service. @@ -100,20 +99,20 @@ control of the application - some database systems limit the number of connections, for example, and if a large number of resources suddenly became active, some of them would fail to obtain connections if the -connection initialisation code were in the respond +connection initialisation code were in the respond method of the resource.

    Configuring Packages Globally

    Of course, the above resource might not be the only resource to use database connections. It might then be tempting to initialise a connection for each module whose resource needs (or, since as normal Python classes we can put many resources in a single module, whose -resources need) to access a database. But it would surely be more +resources need) to access a database. But it would surely be more convenient to define a single, central place to hold such global resources.

    One approach is to define a module which can be accessed by all modules, and thus by all resources. Let us create such a module in the file Properties.py which will reside alongside MyApplication.py -(or whatever the application module is called). Inside the Properties +(or whatever the application module is called). Inside the Properties module we can write the following code:

    import mydb

    connection = mydb.connect("me", "myPassword")

    Now, in each module containing resources which need to access the diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/login-redirect.html --- a/docs/login-redirect.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/login-redirect.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - LoginRedirect and Login Modules + LoginRedirect and Login Modules

    LoginRedirect and Login Modules

    @@ -104,7 +104,7 @@ optional parameter indicating the character encoding used to generate (and, in other places, to interpret) URL-encoded character values in URLs and paths. -

    See the API documentation for the LoginRedirectResource class for more details.

    +

    See the API documentation for the LoginRedirectResource class for more details.

    Redirection from/to the Application

    Some server/framework environments do not permit automatic @@ -126,11 +126,11 @@ support the "single sign-on" aspects of this mechanism - mixing in such classes with LoginAuthenticator may provide a solution to this -issue, however.

    Extending LoginRedirectResource

    Sometimes, using LoginRedirectResource directly is not appropriate in an application. For example, specifying the app_url and login_url as absolute URLs (so that LoginRedirectResource can +issue, however.

    Extending LoginRedirectResource

    Sometimes, using LoginRedirectResource directly is not appropriate in an application. For example, specifying the app_url and login_url as absolute URLs (so that LoginRedirectResource can redirect users into the application and over to the login screen) may seem like excessive detail which will need to be changed if the application is deployed even in a slightly different location. We might -therefore wish to use a PathSelector resource (see "Transaction Attributes" and "Selectors") to record the "root path" into an application and then to employ a login URL which is relative to the "root path".

    To achieve this, LoginRedirectResource provides methods which can be overridden - get_app_url and get_login_url - and we might define a subclass of LoginRedirectResource as follows:

    class MyLoginRedirectResource(LoginRedirectResource):

    "An example of customising LoginRedirectResource."

    def get_login_url(self, trans):

    "Use a different login URL, using 'trans' to find out what it might be."

    # Find out what the PathSelector stored for the root of the application.

    root_path = trans.get_attributes()["root"]

    # Return the value of the login_url attribute appended to the root path.

    return root_path + self.login_url

    Since LoginRedirectResource calls the get_login_url method when forming the URL to redirect to the login resource, by overriding the original method from the LoginRedirectResource class we can define different behaviour. Of course, to take advantage of this new behaviour, we must instantiate MyLoginRedirectResource instead of LoginRedirectResource when setting up the application.

    +therefore wish to use a PathSelector resource (see "Transaction Attributes" and "Selectors") to record the "root path" into an application and then to employ a login URL which is relative to the "root path".

    To achieve this, LoginRedirectResource provides methods which can be overridden - get_app_url and get_login_url - and we might define a subclass of LoginRedirectResource as follows:

    class MyLoginRedirectResource(LoginRedirectResource):

    "An example of customising LoginRedirectResource."

    def get_login_url(self, trans):

    "Use a different login URL, using 'trans' to find out what it might be."

    # Find out what the PathSelector stored for the root of the application.

    root_path = trans.get_attributes()["root"]

    # Return the value of the login_url attribute appended to the root path.

    return root_path + self.login_url

    Since LoginRedirectResource calls the get_login_url method when forming the URL to redirect to the login resource, by overriding the original method from the LoginRedirectResource class we can define different behaviour. Of course, to take advantage of this new behaviour, we must instantiate MyLoginRedirectResource instead of LoginRedirectResource when setting up the application.

    Deploying a Login Application

    In order for this authentication mechanism to function in its entirety, a @@ -198,4 +198,4 @@ out. A special logout confirmation URL may also be configured (see logout_url and use_logout_redirect above).

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/methods.html --- a/docs/methods.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/methods.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,10 +1,8 @@ + - - Request Methods + Request Methods - -

    Request Methods

    @@ -84,4 +82,4 @@ trans as follows:

    trans.set_response_code(405)
    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/parameters-body.html --- a/docs/parameters-body.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/parameters-body.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Request Body Parameters + Request Body Parameters

    Request Body Parameters

    @@ -53,14 +53,14 @@

    One way request body parameters may be used is to provide a mechanism for the uploading of entire files from browsers and other Web clients to applications. Unlike other parameters, those which carry file upload data -expose the contents of such uploaded files as FileContent objects +expose the contents of such uploaded files as FileContent objects instead of Unicode objects.

    Unsupported Environments and Framework Issues

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/parameters-headers.html --- a/docs/parameters-headers.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/parameters-headers.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,12 +1,11 @@ + - - Request Header Parameters + Request Header Parameters

    Request Header Parameters

    -

    Header parameters are typically specified in the URL like this:

    http://www.boddie.org.uk/application?param1=value1&param2=value2
    @@ -39,7 +38,7 @@
    This returns the request parameters (fields) from the request headers (as defined in the path or URL). The fields are provided in a dictionary mapping field names to lists of values
    -An optional encoding parameter may be used to assist +An optional encoding parameter may be used to assist the process of converting parameter values to Unicode objects - see below for a discussion of the issues with this parameter.
    get_query_string
    @@ -61,4 +60,4 @@ - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/parameters.html --- a/docs/parameters.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/parameters.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Request Parameters and Uploads + Request Parameters and Uploads

    Request Parameters and Uploads

    @@ -29,7 +29,7 @@

    One useful application of parameters transferred in request bodies @@ -56,9 +56,9 @@

    get_query_string
    This method returns the part of the URL which contains parameter information. Such information will be "URL-encoded", meaning that -certain characters will have the form %xx where xx +certain characters will have the form %xx where xx is a two digit hexadecimal number referring to the byte value of the -unencoded character - see "Character +unencoded character - see "Character Encodings" for information on how byte values should be interpreted.
    @@ -108,4 +108,4 @@

    The purpose and behaviour of PUT request methods is described in the HTTP specification.

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/path-design.html --- a/docs/path-design.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/path-design.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,10 +1,9 @@ + Path Design and Interpretation - diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/path-info-support.html --- a/docs/path-info-support.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/path-info-support.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,10 +1,9 @@ + - - Path Info Support in Server Environments + Path Info Support in Server Environments -

    Path Info Support in Server Environments

    The following table summarises the support for "path info" within @@ -52,4 +51,4 @@ - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/path-info.html --- a/docs/path-info.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/path-info.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,9 +1,9 @@ + - Paths To and Within Applications - -

    Paths -To and -Within Applications

    + + Paths To and Within Applications + +

    Paths To and Within Applications

    One thing to be aware of, in the code of an application, is which part of @@ -30,7 +30,7 @@

    /resource/operation

    In WebStack, we refer to this latter case - the path within the -application - as the "path info".

    +application - as the "path info".

    WebStack API - Paths To Resources Within Applications

    On transaction objects, the @@ -40,8 +40,8 @@

    get_path_info
    This gets the path of a resource within an application. The path should always contain a -leading / character at the very least.
    -An optional encoding parameter may be +leading / character at the very least.
    +An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see "Character Encodings" for more information.
    get_virtual_path_info
    @@ -49,9 +49,9 @@ resource within a part of an application - the application itself decides the scope of the path and can set the "virtual path info" using the set_virtual_path_info -method. The path should either contain a leading / +method. The path should either contain a leading / character optionally followed by other characters, or an empty string.
    -An optional encoding parameter may be +An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see "Character Encodings" for more information.
    get_processed_virtual_path_info
    @@ -60,12 +60,12 @@ info which does not appear in the virtual path info. In other words, when components at the start of the virtual path info are removed, such components will appear at the end of the processed virtual path info.
    -An optional encoding parameter may be +An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see "Character Encodings" for more information.

    Choosing the Right Path Value

    -

    Given that the path may change depending on +

    Given that the path may change depending on where an application is deployed in a server environment, it may not be very easy to use when determining which resources are being requested or @@ -81,7 +81,7 @@ resources within an application. Path without path infoFinding the location of the application in a server environment. (This is the -path with the "path info" subtracted from +path with the "path info" subtracted from the end.) Path info Determining which resources are being accessed within an application. @@ -91,9 +91,9 @@ application-defined version of "path info" and is discussed below.

    Using the Virtual Path

    -

    Although WebStack sets the "path info" so that +

    Although WebStack sets the "path info" so that applications -know which part of themselves are being accessed, you may +know which part of themselves are being accessed, you may decide that upon processing the request, these different parts of your application @@ -110,7 +110,7 @@ same as the "path info")...

    /company/department/employee

    ...a -resource might extract company from +resource might extract company from the start of the path as follows:

     # Inside a respond method...
    path = trans.get_virtual_path_info() # get the virtual path
    parts = path.split("/") # split the path into components - the first will be empty

    Then, @@ -118,12 +118,12 @@ the first part will be an empty string)...

     if len(parts) > 1: # check to see how deep we are in the path
    process_something(parts[1]) # process the first non-empty part

    ...it will reconstruct the path, removing the processed part (but -remembering to preserve a leading / +remembering to preserve a leading / character)...

     trans.set_virtual_path_info("/" + "/".join(parts[2:]))

    ...and hand over control to another resource which would do the same thing with the first of the other path components (department -and employee), and so on.

    +and employee), and so on.

    The compelling thing about this strategy is the way that each resource would only need to take the "virtual path info" into consideration, and that each resource would believe that it is running @@ -137,9 +137,9 @@ following method exists to set virtual paths within applications.

    set_virtual_path_info
    This sets the virtual path, affecting subsequent calls to the get_virtual_path_info -method. The path should either contain a leading / +method. The path should either contain a leading / character optionally followed by other characters, or an empty string.
    -

    Summary

    The following illustration hopefully provides a more memorable way of representing the structure of paths:

    +

    Summary

    The following illustration hopefully provides a more memorable way of representing the structure of paths:

    @@ -172,4 +172,4 @@
    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/path-manipulation.html --- a/docs/path-manipulation.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/path-manipulation.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Manipulating Paths + Manipulating Paths

    Manipulating Paths

    Whilst path values are useful in telling @@ -10,4 +10,4 @@ processing of a resource has progressed, it is sometimes useful to apply some kind of transformation to the path in order to produce a reference to another resource or application. Consider the simple case -of redirecting a user to another resource:

    First we must obtain a reference to the current resource:

    this_resource = trans.get_path_without_query() # eg. "/app/resource/some-data"

    We may wish to redirect the user to the main application resource; this is done by removing resource from the end of the path:

    this_app = trans.update_path("..")             #     produces "/app/resource"

    A complete description of this method can be found in the API documentation.

    \ No newline at end of file +of redirecting a user to another resource:

    First we must obtain a reference to the current resource:

    this_resource = trans.get_path_without_query() # eg. "/app/resource/some-data"

    We may wish to redirect the user to the main application resource; this is done by removing resource from the end of the path:

    this_app = trans.update_path("..")             #     produces "/app/resource"

    A complete description of this method can be found in the API documentation.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/path-strategies.html --- a/docs/path-strategies.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/path-strategies.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,15 +1,17 @@ + - Path Processing Strategies - + + Path Processing Strategies +

    Path Processing Strategies

    In the development of most Web applications, the structure of the -application - also known as the "site map" - needs to be defined +application - also known as the "site map" - needs to be defined at a very early stage. We might decide that if a user requests a certain path, a particular part of the application will be invoked, and -we might define the site map in a number of different ways:

    As a set of acceptable paths...

    As a tree of resources...

    Since +we might define the site map in a number of different ways:

    As a set of acceptable paths...

    As a tree of resources...

    Since all of the action in WebStack applications takes place inside resources, the challenge is to define resources in such a way which -makes processing paths relatively easy.

    Chaining Resources

    Whilst the classic resource, as described in "Applications and Resources", might resemble a simple class whose respond +makes processing paths relatively easy.

    Chaining Resources

    Whilst the classic resource, as described in "Applications and Resources", might resemble a simple class whose respond method performs most of the necessary work, it is useful to reconsider such a resource as doing such work only for a particular narrow part of a larger Web application. Moreover, resources are not restricted in @@ -20,13 +22,13 @@ resource then invokes other resources to produce certain pages, we can separate the path processing from the rest of the application's functionality. So, for the first site map strategy, we could define a -path processing resource as follows:

    from WebStack.Generic import EndOfResponse

    class PathProcessor:

    "A path processing resource."

    def __init__(self, main_page, salary_report_page, complaints_page):

    # Supplied resources are chained to this resource.

    self.main_page = main_page
    self.salary_report_page = salary_report_page
     self.complaints_page = complaints_page

     def respond(self, trans):

    # This is where the resources are invoked...

    path = trans.get_path_without_query() # should really use an encoding here
    if path == "/":
    self.main_page.respond(trans)
    elif path == "/services/finance/salaries/":
    self.main_page.respond(trans)
    elif path == "/services/finance/salaries/":
    self.main_page.respond(trans)

    # Administrative details...

    else:
    trans.set_response_code(404) # not found!
    raise EndOfResponse

    Of +path processing resource as follows:

    from WebStack.Generic import EndOfResponse

    class PathProcessor:

    "A path processing resource."

    def __init__(self, main_page, salary_report_page, complaints_page):

    # Supplied resources are chained to this resource.

    self.main_page = main_page
    self.salary_report_page = salary_report_page
    self.complaints_page = complaints_page

    def respond(self, trans):

    # This is where the resources are invoked...

    path = trans.get_path_without_query() # should really use an encoding here
    if path == "/":
    self.main_page.respond(trans)
    elif path == "/services/finance/salaries/":
    self.main_page.respond(trans)
    elif path == "/services/finance/salaries/":
    self.main_page.respond(trans)

    # Administrative details...

    else:
    trans.set_response_code(404) # not found!
    raise EndOfResponse

    Of course, more elegant methods of mapping paths to resources could be employed - a dictionary might be an acceptable solution, if defined in the initialiser method. The above class might be initialised as follows:

    main_page = MainResource()
    salary_report_page = SalaryReportResource()
    complaints_page = ComplaintsResource()
    path_processor = PathProcessor(main_page, salary_report_page, complaints_page)

    For the second site map strategy, we retain the basic parts of the above strategy, focusing only on one level in the path as opposed to the complete path. However, this means that our path processing resources -need to know exactly which part of the path they should be +need to know exactly which part of the path they should be considering, and perhaps which part of the path has already been -processed.

    As described in "Paths To and Within Applications", special path information of the nature required is provided by two methods: get_virtual_path_info and get_processed_virtual_path_info. Such information can thus be obtained and updated at each level in the processing chain.

    class MainPathProcessor:

    "A path processor for the top of the application."

    def __init__(self, main_page, services_processor):
    self.main_page = main_page
    self.services_processor = services_processor

    def respond(self, trans):

    # This is where the resources are invoked...

    path = trans.get_virtual_path_info() # should really use an encoding here
    if path == "/":
    self.main_page.respond(trans)
    elif path.startswith("/services/"):
    trans.set_virtual_path_info(path[len("/services"):]) # cut off "/services"
    self.services_processor.respond(trans)

    # Administrative details...

    else:
    trans.set_response_code(404) # not found!
    raise EndOfResponse

    A suite of similar classes can be defined and might be initialised as follows:

    main_page = MainResource()
    salary_report_page = SalaryReportResource()
    complaints_page = ComplaintsResource()
    finance_processor = FinancePathProcessor(salary_report_page)
    customer_processor = CustomerPathProcessor(complaints_page)
    services_processor = ServicesPathProcessor(finance_processor, customer_processor)
    main_processor = MainPathProcessor(main_page, services_processor)

    Fortunately, this latter strategy is supported by WebStack in the form of the ResourceMap module. See "Treating the Path Like a Filesystem" and "ResourceMap - Simple Mappings from Names to Resources" for details.

    \ No newline at end of file +processed.

    As described in "Paths To and Within Applications", special path information of the nature required is provided by two methods: get_virtual_path_info and get_processed_virtual_path_info. Such information can thus be obtained and updated at each level in the processing chain.

    class MainPathProcessor:

    "A path processor for the top of the application."

    def __init__(self, main_page, services_processor):
    self.main_page = main_page
    self.services_processor = services_processor

    def respond(self, trans):

    # This is where the resources are invoked...

    path = trans.get_virtual_path_info() # should really use an encoding here
    if path == "/":
    self.main_page.respond(trans)
    elif path.startswith("/services/"):
    trans.set_virtual_path_info(path[len("/services"):]) # cut off "/services"
    self.services_processor.respond(trans)

    # Administrative details...

    else:
    trans.set_response_code(404) # not found!
    raise EndOfResponse

    A suite of similar classes can be defined and might be initialised as follows:

    main_page = MainResource()
    salary_report_page = SalaryReportResource()
    complaints_page = ComplaintsResource()
    finance_processor = FinancePathProcessor(salary_report_page)
    customer_processor = CustomerPathProcessor(complaints_page)
    services_processor = ServicesPathProcessor(finance_processor, customer_processor)
    main_processor = MainPathProcessor(main_page, services_processor)

    Fortunately, this latter strategy is supported by WebStack in the form of the ResourceMap module. See "Treating the Path Like a Filesystem" and "ResourceMap - Simple Mappings from Names to Resources" for details.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/path-value-encoding.html --- a/docs/path-value-encoding.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/path-value-encoding.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Encoding and Decoding Path Values + Encoding and Decoding Path Values

    Encoding and Decoding Path Values

    On some occasions it can @@ -12,19 +12,19 @@ transaction methods are available:

    WebStack API - Encoding and Decoding Path Values

    WebStack provides the following methods to transform path values:

    -
    decode_path
    This method accepts a path containing "URL encoded" information (as defined in the "URLs and Paths" +
    decode_path
    This method accepts a path containing "URL encoded" information (as defined in the "URLs and Paths" document) and, using an optional encoding parameter, returns a Unicode object containing genuine character values in place of the "URL encoded" values.
    encode_path
    This method accepts a Unicode object containing the path and an optional encoding -parameter; it reverses the process carried out by the decode_path method.
    -

    Generally, the decode_path method is of little interest; its only relatively common application might be to decode query strings:

    qs = trans.get_query_string()                # eg. "a=%E6"
    new_qs = trans.decode_path(qs, "iso-8859-1") # producing "a=æ"

    Such operations are generally better performed using the request parameter methods.

    The encode_path +parameter; it reverses the process carried out by the decode_path method. +

    Generally, the decode_path method is of little interest; its only relatively common application might be to decode query strings:

    qs = trans.get_query_string()                # eg. "a=%E6"
    new_qs = trans.decode_path(qs, "iso-8859-1") # producing "a=æ"

    Such operations are generally better performed using the request parameter methods.

    The encode_path method is slightly more useful: since various transaction methods return values which have already been transformed into Unicode objects, we must consider the use of encode_path to produce values which are suitable for feeding into other methods. For example, having obtained a path, we may wish to cause a redirect to another location -based on that path:

    path = trans.get_path_without_query("iso-8859-1") # eg. "/app/resource"
    path += "/æøå"
    new_path = trans.encode_path(path, "iso-8859-1") # producing "/app/resource/%E6%F8%E5"
    trans.redirect(new_path)

    It +based on that path:

    path = trans.get_path_without_query("iso-8859-1") # eg. "/app/resource"
    path += "/æøå;"
    new_path = trans.encode_path(path, "iso-8859-1") # producing "/app/resource/%E6%F8%E5"
    trans.redirect(new_path)

    It is essential to encode the path in such situations because the underlying mechanisms do not support the full range of Unicode -characters. Some cases where this limitation exists are listed in the "Character Encodings" document.

    \ No newline at end of file +characters. Some cases where this limitation exists are listed in the "Character Encodings" document.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/paths-filesystem.html --- a/docs/paths-filesystem.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/paths-filesystem.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,68 +1,46 @@ + - - Treating the Path Like a Filesystem + Treating the Path Like a Filesystem -

    Treating the Path Like a -Filesystem

    -

    ...or as a reference into -deeply categorized resources. In this approach, +

    Treating the Path Like a Filesystem

    +

    ...or as a reference into deeply categorized resources. In this approach, we take a path like this...

    /documents/news/2005/article.html
    -

    ...and we consider documents, -news, -and -2005 -as directories, and article.html -as a +

    ...and we consider documents, news, and +2005 as directories, and article.html as a file-like resource. If we ask for the following path...

    /documents/news/2005
    -

    ...we may decide to provide a -listing of files within that directory, or -we may decide to refuse such a request. Indeed some kinds of -applications insist -that such a listing may only be produced with the following path -instead:

    +

    ...we may decide to provide a listing of files within that directory, or +we may decide to refuse such a request. Indeed some kinds of applications insist +that such a listing may only be produced with the following path instead:

    /documents/news/2005/
    -

    Applications of this kind are -quite common since the publishing of files -on a Web server often just involves exposing parts of a real filesystem -to +

    Applications of this kind are quite common since the publishing of files +on a Web server often just involves exposing parts of a real filesystem to requests through the server.

    -

    Resource Hierarchies in -WebStack

    -

    There are a number of different -ways that paths can be interpreted and handled in WebStack +

    Resource Hierarchies in WebStack

    +

    There are a number of different ways that paths can be interpreted and handled in WebStack applications, including...

    -

    Predefining Resource -Hierarchies

    -

    We might decide to represent -components in these kinds of paths using +

    Predefining Resource Hierarchies

    +

    We might decide to represent components in these kinds of paths using different resource classes; for example:

    -We might then predefine a hierarchy of resources -so that when a request arrives for a resource, we can check it against -the -hierarchy and process the request according to whichever type of -resource is -being accessed. For example:
    +

    We might then predefine a hierarchy of resources +so that when a request arrives for a resource, we can check it against the +hierarchy and process the request according to whichever type of resource is +being accessed. For example:

    -

    Consider the above hierarchy; -we would implement such a hierarchy with a -resource object mapped to documents, -and that resource object +

    Consider the above hierarchy; we would implement such a hierarchy with a +resource object mapped to documents, and that resource object would contain a mapping of years to other resources. Eventually, at the bottom of the hierarchy, individual resources would represent articles -and be -mapped to names such as article.html.

    +and be mapped to names such as article.html.

    -

    WebStack API - Predefining -Resource Hierarchies in Adapter Code

    +

    WebStack API - Predefining Resource Hierarchies in Adapter Code

    WebStack provides the MapResource class (in the WebStack.Resources.ResourceMap module) for convenient mapping of path -components to resource objects. See the "ResourceMap - Simple Mappings from Names to Resources" document for a more detailed description of the MapResource class.

    This class can be used in adapter code -to initialise an -application as follows:

    +components to resource objects. +See the "ResourceMap - Simple Mappings from Names to Resources" +document for a more detailed description of the MapResource class.

    + +

    This class can be used in adapter code +to initialise an application as follows:

    from WebStack.Resources.ResourceMap import MapResource
    from MyApplication import FileResource # import some resource class

    article_resource = FileResource(...) # make a resource representing the article
    document_resource = FileResource(...) # make a resource representing the document
    year_2004_resource = MapResource({"document.html" : document_resource})
    year_2005_resource = MapResource({"article.html" : article_resource})
    news_resource = MapResource({"2005" : year_2005_resource, "2004" : year_2004_resource})
    documents_resource = MapResource({"news" : news_resource})
    top_resource = MapResource({"documents" : documents_resource})

    Of course, predefining resource @@ -108,4 +85,4 @@ hierarchies. We could inspect paths and act dynamically on the supplied information, either choosing to create resources or choosing to handle such paths in the same resource.

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/paths-opaque.html --- a/docs/paths-opaque.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/paths-opaque.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,27 +1,20 @@ + Using the Path as an Opaque Reference into an Application -

    Using the Path as an Opaque Reference into an Application

    Since many Web applications have complete control over how paths are -interpreted, the form of the path doesn't necessarily have to follow -any -obvious structure as far as users of your application is concerned. -Here's an +interpreted, the form of the path doesn't necessarily have to follow any +obvious structure as far as users of your application is concerned. Here's an example:

    /000251923572ax-0015
    -

    Many people would argue that such obscure references, whilst -perfectly -acceptable to machines, would make any application counter-intuitive -and very -difficult to reference. However, application developers sometimes -do not want people -"bookmarking" resources or functions within an application, and so such -concerns don't matter to them.

    +

    Many people would argue that such obscure references, whilst perfectly +acceptable to machines, would make any application counter-intuitive and very +difficult to reference. However, application developers sometimes do not want people +"bookmarking" resources or functions within an application, and so such concerns don't matter to them.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/paths-services.html --- a/docs/paths-services.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/paths-services.html Sat Sep 08 16:02:18 2007 +0000 @@ -4,7 +4,6 @@ Treating the Path Mostly Like a Filesystem - diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/paths.html --- a/docs/paths.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/paths.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - URLs and Paths + URLs and Paths

    URLs and Paths

    @@ -31,7 +31,7 @@

    In an application the full URL, containing the address of the machine on which it is running, is not always interesting. In the WebStack API (and in other Web programming frameworks), we also talk -about "paths" - a path is just the part of the +about "paths" - a path is just the part of the URL which refers to the resource or service, ignoring the actual Internet address, and so the above example would have a path which looks like @@ -53,18 +53,18 @@

    This gets the entire path of a resource including parameter information (as described in "Request Parameters and Uploads").
    -An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see below.
    +An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see below.
    get_path_without_query
    This gets the entire path of a resource but without any parameter information.
    -An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see below.
    get_path_without_info
    This gets the entire path of a resource but without any parameter +An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see below.
    get_path_without_info
    This gets the entire path of a resource but without any parameter information or any special "path info" (as described in "Paths To and Within Applications"). The result is more or less equivalent to the location where an application has been "published" - ie. the location of an application in a server environment.
    -An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see below.
    +An optional encoding parameter may be used to assist the process of converting the path to a Unicode object - see below.

    To obtain the above path using the WebStack API, we can write the following code:

    @@ -95,21 +95,21 @@ Uploads".

    WebStack API - Getting Query Strings

    -

    WebStack provides a method to get only the query string from the URL:

    +

    WebStack provides a method to get only the query string from the URL:

    get_query_string
    This method returns the part of the URL which contains parameter information. Such information will be "URL encoded", meaning that -certain characters will have the form %xx where xx +certain characters will have the form %xx where xx is a two digit hexadecimal number referring to the byte value of the unencoded character - see below for discussion of this.
    -

    Note that unlike the path access methods, get_query_string +

    Note that unlike the path access methods, get_query_string does not accept an encoding as a parameter. Moreover, when retrieving a path including a query string, the encoding is not used to interpret "URL encoded" character values in the query string itself. Consider this example URL:

    http://www.boddie.org.uk/application-%E6?var%F8=value%E5

    Upon requesting the path and the query string, certain differences should be noticeable:

    -
    trans.get_path("iso-8859-1")               # returns /application-æ?var%F8=value%E5
    trans.get_path_without_query("iso-8859-1") # returns /application-æ
    trans.get_query_string() # returns var%F8=value%E5
    +
    trans.get_path("iso-8859-1")               # returns /application-æ?var%F8=value%E5
    trans.get_path_without_query("iso-8859-1") # returns /application-æ
    trans.get_query_string() # returns var%F8=value%E5

    One reason for this seemingly arbitrary distinction in treatment is the way certain servers present path information to WebStack - often the "URL encoded" information has been replaced by raw character values @@ -121,7 +121,7 @@

    http://www.boddie.org.uk/application?a=%26b

    If we were to just decode the query string and then extract the parameters/fields, the result would be two empty parameters with the -names a and b, as opposed to the correct interpretation of the query string as describing a single parameter a with the value &b.

    +names a and b, as opposed to the correct interpretation of the query string as describing a single parameter a with the value &b.

    Final Note

    Regardless of all this, all inspection of path parameters should be done using the appropriate methods (see "Request Parameters and Uploads"), @@ -134,4 +134,4 @@

  • Path Info Support in Server Environments
  • - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/pythonpath.html --- a/docs/pythonpath.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/pythonpath.html Sat Sep 08 16:02:18 2007 +0000 @@ -4,7 +4,6 @@ Getting PYTHONPATH Right - diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/redirection.html --- a/docs/redirection.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/redirection.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Redirection + Redirection

    Redirection

    Instead of presenting information to a user when @@ -14,4 +14,4 @@

    WebStack provides the following method in transaction objects to perform redirection:

    redirect
    This method accepts a path value suitable for use in response headers indicating the location to which a -user shall be redirected. An optional response code (see "Responses and Presentation") can be specified to modify the meaning of the redirection (as defined in the HTTP specifications).

    Since the path value must be usable in response header, it is necessary to transform paths as described in the "Encoding and Decoding Path Values" document, and an example of redirection is given in that document.

    \ No newline at end of file +user shall be redirected. An optional response code (see "Responses and Presentation") can be specified to modify the meaning of the redirection (as defined in the HTTP specifications).

    Since the path value must be usable in response header, it is necessary to transform paths as described in the "Encoding and Decoding Path Values" document, and an example of redirection is given in that document.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/resource-creation.html --- a/docs/resource-creation.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/resource-creation.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,24 +1,23 @@ + How Resources are Created -

    How Resources are Created

    -

    In the MyApplication +

    In the MyApplication example (and in many applications), the only thing we need to consider is -what our code does, not how objects are created from the MyResource +what our code does, not how objects are created from the MyResource class and how the respond method is invoked. However, the mechanisms behind all these things are -not magic - the adapter +not magic - the adapter code is responsible for all of this. Let us turn the diagram of components on its side and investigate what happens @@ -51,7 +50,7 @@ in the application... A resource + align="undefined" valign="undefined">A resource object is created and initialised. @@ -79,7 +78,7 @@

    In more complicated applications, there may be a -need to create a number of resource objects and possibly to do so +need to create a number of resource objects and possibly to do so dynamically within an application itself, but this is not usually interesting or relevant to think about when writing your first application - see "Treating the Path diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/resource-map.html --- a/docs/resource-map.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/resource-map.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,29 +1,30 @@ + - - - ResourceMap - Simple Mappings from Names to Resources + + + ResourceMap - Simple Mappings from Names to Resources

    ResourceMap - Simple Mappings from Names to Resources

    -

    The ResourceMap module provides classes (although +

    The ResourceMap module provides classes (although currently only one class is supplied) which act as standard WebStack resources, but which examine the path or URL from incoming requests and direct such requests to other resources based on the contents of the path or URL. In other words, such classes map names or patterns to -WebStack resources and dispatch requests accordingly.

    Introducing MapResource

    The "Treating the Path Like a Filesystem" document contains an example involving the MapResource class; this class is initialised with a dictionary mapping names to resources as described below.

    -

    WebStack API - The MapResource Class

    +WebStack resources and dispatch requests accordingly.

    Introducing MapResource

    The "Treating the Path Like a Filesystem" document contains an example involving the MapResource class; this class is initialised with a dictionary mapping names to resources as described below.

    +

    WebStack API - The MapResource Class

    -

    The MapResource +

    The MapResource class (found in the WebStack.Resources.ResourceMap module) maps names to resource objects, where to select a resource the -corresponding name must match the first component discovered +corresponding name must match the first component discovered in the virtual "path info". For example, consider the following virtual "path info" (where there may have been -more information in the path, but this has already been processed):

    /documents/news/2005/article.html

    Here, the name documents +more information in the path, but this has already been processed):

    /documents/news/2005/article.html

    Here, the name documents would match the above virtual "path info". Meanwhile, after processing more of the information, we might have the following remains of the -path:

    /2005/article.html

    Here, the name 2005 would match, leaving the following information unprocessed:

    /article.html

    Here, the name article.html would match. However, let us consider the following original virtual "path info" instead:

    /documents/news/2005/

    After processing the leading components, we may instead end up with this:

    /

    Here, only an empty string as the name will specifically match the above.

    Further Reading

    The API documentation for the MapResource +path:

    /2005/article.html

    Here, the name 2005 would match, leaving the following information unprocessed:

    /article.html

    Here, the name article.html would match. However, let us consider the following original virtual "path info" instead:

    /documents/news/2005/

    After processing the leading components, we may instead end up with this:

    /

    Here, only an empty string as the name will specifically match the above.

    Further Reading

    The API documentation for the MapResource class provides more detail on the subject of name matching, including the special "catch all" name and a discussion of the pass-through -parameter.

    \ No newline at end of file +parameter.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/resources.html --- a/docs/resources.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/resources.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,12 +1,12 @@ + - - Applications and Resources + Applications and Resources

    Applications and Resources

    -At its simplest a WebStack application is just a single Python +At its simplest a WebStack application is just a single Python class that we call a "resource". This class can be defined inside a normal Python module or package, so let us start by doing the following:
      @@ -16,19 +16,19 @@
    1. Create a file called MyApplication.py - this is our module.
    -We are going to call our resource MyResource +We are going to call our resource MyResource and in principle it will have a structure that looks like this:
    class MyResource:
    def respond(self, trans):
    [Examine the transaction, decide what the user wants to do.]
    [Perform some kind of action with the information supplied.]
    [Produce some kind of response which tells the user what happened.]

    It is in this kind of resource class that we write the actual application code or at least the beginnings of it. When a user of the application sends us a request, -the respond method +the respond method will be called and the code within it executed. The parts of the pseudo-code in the above text which aren't valid Python (ie. the bits in square brackets) will, when we have written them, use -the trans +the trans object to find out what any given user of the application has sent us, and to send information back to the @@ -40,23 +40,23 @@ to produce some kind of response. Here is how we can make our application do something:

      -
    1. Edit the module -file MyApplication.py.
    2. +
    3. Edit the module +file MyApplication.py.
    4. Write into it the following -code which defines MyResource:
    5. +code which defines MyResource:
    -
    class MyResource:
     def respond(self, trans):
    out = trans.get_response_stream()
    print >>out, "Hello world."
    +
    class MyResource:
    def respond(self, trans):
    out = trans.get_response_stream()
    print >>out, "Hello world."

    Testing the Resource

    To test this resource we need to deploy it, and to do that we need an adapter to connect it to the outside world. Here is a quick way of writing an adapter and testing this code:

      -
    1. Create a file called MyAdapter.py - you +
    2. Create a file called MyAdapter.py - you can choose another name if you want - this will be where the adapter code lives.
    3. Write into it the following code:
    from WebStack.Adapters.BaseHTTPRequestHandler import deploy    # import the support for the server environment
    from MyApplication import MyResource # import the main resource class
    print "Serving..." # just for testing - we might want to remove this later
    deploy(MyResource()) # connect a resource object to the server environment

    Now, with two files in your directory, MyApplication.py -and MyAdapter.py, you may run MyAdapter.py +and MyAdapter.py, you may run MyAdapter.py as follows:

    @@ -64,6 +64,6 @@

    This should start the adapter program and print the following message:

    Serving...
    -

    You should now be able to visit http://localhost:8080 +

    You should now be able to visit http://localhost:8080 in your -browser and see the message printed by your application:

    Hello world.

    Related Examples

    The code presented in this document is very similar to that found in the following files:

    Note that a number of different adapters are provided in the examples directory hierarchy; for example:

    See "Deploying a WebStack Application" for more information about adapters.

    \ No newline at end of file +browser and see the message printed by your application:

    Hello world.

    Related Examples

    The code presented in this document is very similar to that found in the following files:

    Note that a number of different adapters are provided in the examples directory hierarchy; for example:

    See "Deploying a WebStack Application" for more information about adapters.

    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/responses.html --- a/docs/responses.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/responses.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Responses and Presentation + Responses and Presentation

    Responses and Presentation

    @@ -33,12 +33,12 @@

    The kind of code involved may well resemble the following:

    from WebStack.Generic import ContentType

    class MyResource:
    def respond(self, trans):
    [Perform the requested operations.]

    if [the operation was successful]:
    trans.set_response_code(200)
    trans.set_content_type(ContentType("text/html", encoding="utf-8"))
    out = trans.get_response_stream()
    out.write([some data either as a plain string suitably encoded or as Unicode])
    else:
    trans.set_response_code(500) # or some other code
    trans.set_content_type(ContentType("text/html", encoding="utf-8"))
    out = trans.get_response_stream()
    out.write([some other data either as a plain string suitably encoded or as Unicode])
    -

    Unicode and the Response Stream

    Although an encoding may be specified or be set as a default by the EncodingSelector (see "Selectors - Components for Dispatching to Resources"), +

    Unicode and the Response Stream

    Although an encoding may be specified or be set as a default by the EncodingSelector (see "Selectors - Components for Dispatching to Resources"), it should be noted that the encoding of textual information will only take place if Unicode objects are written to the stream. Where binary information or information which should not be changed is being written, this must be supplied as plain strings to the transaction -object's write method.

    As discussed in "Character Encodings", +object's write method.

    As discussed in "Character Encodings", care must be taken generating the response so that it meets any expectations that @@ -69,7 +69,7 @@ convey information to the user (and their software) which is comparable to that found in request headers sent in to the Web application; for example, the content type information is -transmitted using response headers (using the Content-Type header name), although the above set_content_type method is a more convenient means of preparing such information. +transmitted using response headers (using the Content-Type header name), although the above set_content_type method is a more convenient means of preparing such information.

    get_response_stream
    This returns the output stream through which data may be sent to the user.
    @@ -77,14 +77,14 @@

    Ending the Response Explicitly

    Although it is possible to produce some output and then to let -the respond function complete normally, sometimes it +the respond function complete normally, sometimes it is appropriate to terminate the response and to hand control straight back to the server environment; in other words, to decide that no more activity will be performed within the application and to send the -response immediately. Whilst just using a return +response immediately. Whilst just using a return statement might be adequate in many applications...

            # In the respond method...
    if some_condition:
    [Produce a response.]
    return
    [Produce a different response.]
    -

    ...sometimes a resource's respond method is being +

    ...sometimes a resource's respond method is being called from another resource, and it may be the case that this other resource may produce additional output if control is returned to it.

    To provide a definitive end of response signal, a special exception @@ -108,9 +108,9 @@ it is usually advisable to consider using templating systems which combine raw data and templates to produce formatted output that can be displayed as a Web page (amongst other things).

    -

    See "Integration with Other Systems" +

    See "Integration with Other Systems" for more information on the principles of using such external libraries. See also XSLTools for a distribution of utilities, including a Web forms framework called XSLForms, which can be of use in generating content for Web applications.

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/securing.html --- a/docs/securing.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/securing.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,9 +1,8 @@ + Securing a WebStack Application - diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/selectors.html --- a/docs/selectors.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/selectors.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Selectors - Components for Dispatching to Resources + Selectors - Components for Dispatching to Resources

    Selectors - Components for Dispatching to Resources

    @@ -10,7 +10,7 @@ resources, but which attempt to "select" other resources, dispatch each request to those resources, and to cause various side-effects, mostly on the attributes stored on the transaction object. These "selector" -classes behave those in the ResourceMap module, but aspire to be more generally applicable.

    Selecting Path Roots with PathSelector

    In +classes behave those in the ResourceMap module, but aspire to be more generally applicable.

    Selecting Path Roots with PathSelector

    In non-trivial applications, it is often desirable to know the path or URL to a particular resource, especially the "root" resource under which the application or one of its components may reside. The PathSelector @@ -20,12 +20,12 @@

    The PathSelector class (found in the -WebStack.Resources.Selectors module) wraps resource +WebStack.Resources.Selectors module) wraps resource objects whose location (as indicated by a path or URL) should be recorded as an attribute on the current transaction. The most common use of the class is to record the "root" resource's location, and this would be done as follows:

    def get_site_map():
    return PathSelector(MyResource())

    Here, the get_site_map -function (as described in the "Deploying a WebStack Application" document) would provide a PathSelector object instead of an instance of the MyResource class. However, the side-effect of combining these two resources would be the availability of an attribute named root on the transaction object. Thus, the "root" MyResource +function (as described in the "Deploying a WebStack Application" document) would provide a PathSelector object instead of an instance of the MyResource class. However, the side-effect of combining these two resources would be the availability of an attribute named root on the transaction object. Thus, the "root" MyResource object and, indeed, all resource objects visited after this side-effect has occurred will have access to the "root" path or URL information.

    Further Reading

    The API documentation for the PathSelector class provides additional information.

    Defining Encodings using EncodingSelector

    One @@ -33,9 +33,9 @@ processing and production of text in different encodings. Whilst the WebStack API lets applications explicitly state the character encoding for various operations, one often wants to be able to ignore such -details since they start to clutter up application code. The EncodingSelector class offers a basic solution which is compatible with the mechanisms in transaction objects: by wrapping WebStack resources with instances of EncodingSelector, +details since they start to clutter up application code. The EncodingSelector class offers a basic solution which is compatible with the mechanisms in transaction objects: by wrapping WebStack resources with instances of EncodingSelector, an application-wide default encoding (or character set) will be -defined; this will result in request information being processed +defined; this will result in request information being processed according to the stated encoding and response information being produced according to that encoding (see below for more details of the latter activity).

    @@ -43,22 +43,22 @@

    The EncodingSelector class (found in the -WebStack.Resources.Selectors module) wraps resource -objects whilst changing the default encoding of the current transaction object. The class can be applied like this:

    def get_site_map():
    return EncodingSelector(MyResource(), "utf-8")

    Here, the get_site_map -function (as described in the "Deploying a WebStack Application" document) would provide a EncodingSelector object instead of an instance of the MyResource class. However, the EncodingSelector will forward requests on to MyResource (since it "selects" that resource), whilst setting the default encoding to be "utf-8".

    Request Streams and Encodings

    Although a default encoding affects the processing of request parameters, direct access to the request stream using the get_request_stream +WebStack.Resources.Selectors module) wraps resource +objects whilst changing the default encoding of the current transaction object. The class can be applied like this:

    def get_site_map():
    return EncodingSelector(MyResource(), "utf-8")

    Here, the get_site_map +function (as described in the "Deploying a WebStack Application" document) would provide a EncodingSelector object instead of an instance of the MyResource class. However, the EncodingSelector will forward requests on to MyResource (since it "selects" that resource), whilst setting the default encoding to be "utf-8".

    Request Streams and Encodings

    Although a default encoding affects the processing of request parameters, direct access to the request stream using the get_request_stream method will only produce plain strings. This behaviour is justified by the observation that, if conversion from an encoding to Unicode were to take place, the resulting character values may be unsuitable substitutes for the original byte values in applications intending to make use of the raw incoming (possibly binary) data. A recipe for -making a Unicode stream is provided in the "Character Encodings" document.

    Response Encodings and Content Types

    Although EncodingSelector sets -a default encoding, responses will generally be written in that +making a Unicode stream is provided in the "Character Encodings" document.

    Response Encodings and Content Types

    Although EncodingSelector sets +a default encoding, responses will generally be written in that encoding, at least if textual data is written to the response stream as Unicode objects. However, the content type must typically be set either to match the encoding in use or to not specify an encoding. It may become necessary to find out what the response stream encoding is when -creating a ContentType object. For this and other purposes, the get_response_stream_encoding method is available on the transaction object:

    from WebStack.Generic import ContentType

    def respond(self, trans):

    # Some code...

    trans.set_content_type(ContentType("text/html", trans.get_response_stream_encoding()))
    out = trans.get_response_stream()
    out.write(some_unicode_object)

    However, it is completely acceptable to omit the encoding information where a default encoding has been set:

        trans.set_content_type(ContentType("text/html")) # no encoding/charset specified

    Reading the Default Directly

    For +creating a ContentType object. For this and other purposes, the get_response_stream_encoding method is available on the transaction object:

    from WebStack.Generic import ContentType

    def respond(self, trans):

    # Some code...

    trans.set_content_type(ContentType("text/html", trans.get_response_stream_encoding()))
    out = trans.get_response_stream()
    out.write(some_unicode_object)

    However, it is completely acceptable to omit the encoding information where a default encoding has been set:

        trans.set_content_type(ContentType("text/html")) # no encoding/charset specified

    Reading the Default Directly

    For some activities, such as making a Unicode stream from the request stream, it is desirable to find out the encoding set by the selector. -This information is made available on transaction objects as the default_charset attribute.

    Further Reading

    The API documentation for the EncodingSelector -class provides additional information, along with the "Responses and Presentation" document.


    \ No newline at end of file +This information is made available on transaction objects as the default_charset attribute.

    Further Reading

    The API documentation for the EncodingSelector +class provides additional information, along with the "Responses and Presentation" document.


    diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/sessions-servers.html --- a/docs/sessions-servers.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/sessions-servers.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,18 +1,17 @@ + - - Server Environment Support for Sessions + Server Environment Support for Sessions -

    Server Environment Support for Sessions

    Various server environments or frameworks do not support sessions directly. In order to provide primitive support for sessions within -WebStack upon such frameworks, the WebStack.Helpers.Session +WebStack upon such frameworks, the WebStack.Helpers.Session module is used to provide a simple file-based session store. Before deploying an application on one of these frameworks, it may be necessary to -create a directory called WebStack-sessions in a +create a directory called WebStack-sessions in a particular location so that the storage of session information will work, although WebStack will attempt to create such a directory if it does not already exist.

    The location of the WebStack-sessions directory @@ -36,7 +35,7 @@ mod_python The server root (such -as /usr/local/apache2). +as /usr/local/apache2). Twisted @@ -45,7 +44,7 @@ -

    Note that the WebStack-sessions directory must +

    Note that the WebStack-sessions directory must have the appropriate ownership and privileges necessary for the server or framework to write session information into it.

    @@ -57,4 +56,4 @@ CVS snapshot used for testing) do not support session detection or expiry correctly. - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/sessions-usage.html --- a/docs/sessions-usage.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/sessions-usage.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Using Sessions + Using Sessions

    Using Sessions

    @@ -13,7 +13,7 @@ - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/sessions.html --- a/docs/sessions.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/sessions.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,8 +1,8 @@ + - - Sessions and Persistent Information + Sessions and Persistent Information @@ -18,10 +18,10 @@
  • It then accesses a data store containing information associated different users.
  • Finally, it accesses information specific to the stated user - -this is that particular user's session.
  • +this is that particular user's session.

    Sessions vs. Persistent Information

    -

    Information can be said to be "persistent" when it is +

    Information can be said to be "persistent" when it is remembered beyond the lifetime of a particular request to an application. Sessions, meanwhile, are effectively a special case of persistent information - data is addressed or accessed using each @@ -60,4 +60,4 @@

  • Server Environment Support for Sessions
  • - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/state.html --- a/docs/state.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/state.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,16 +1,15 @@ + Cookies, Sessions, Users and Persistent Information -

    Cookies, Sessions, Users and Persistent Information

    Due to the nature of the communications mechanisms -involved, Web applications do not have automatic or "magic" +involved, Web applications do not have automatic or "magic" knowledge about the people or entities accessing them as application users. Moreover, Web applications do not necessarily remember anything about what that user has done before. Due to this behaviour, where diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/supported-frameworks.html --- a/docs/supported-frameworks.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/supported-frameworks.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Supported Frameworks + Supported Frameworks

    Supported Frameworks

    @@ -55,4 +55,4 @@

    See the "Deploying Applications" document for information on exact deployment procedures for each of the above frameworks.

    - \ No newline at end of file + diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/users.html --- a/docs/users.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/users.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,17 +1,16 @@ + Users and Authentication -

    Users and Authentication

    One way of discovering the identity of the user sending a request -into your application is to test the identity using methods on the -transaction object. Before this can be made to work, you must set +into your application is to test the identity using methods on the +transaction object. Before this can be made to work, you must set up authentication for your application, as described in "Securing a WebStack Application". Once authentication is working, every request that arrives in the diff -r 5ea48ef5ca2c -r 9156c2205b8f docs/writing-adapters.html --- a/docs/writing-adapters.html Sat Sep 08 16:01:41 2007 +0000 +++ b/docs/writing-adapters.html Sat Sep 08 16:02:18 2007 +0000 @@ -1,7 +1,7 @@ + - - Writing Adapters + Writing Adapters

    Writing Adapters

    @@ -19,7 +19,7 @@

    When deploying an application, it is possible to use a one-shot deployment -function for BaseHTTPRequestServer, CGI, Django, Java Servlet, mod_python, Twisted and WSGI configurations. The +function for BaseHTTPRequestServer, CGI, Django, Java Servlet, mod_python, Twisted and WSGI configurations. The deploy function is called as follows:

    deploy(resource)
    deploy(resource, authenticator) # where authenticators are used
    @@ -27,7 +27,7 @@ may be specified:

    deploy(resource, address=(host_string, port_integer))
    deploy(resource, authenticator, address=(host_string, port_integer))

    And for some frameworks, the return value of the function is important:

    something = deploy(resource)
    something, something_else = deploy(resource, authenticator)

    Here is a summary of which -frameworks require address information and which produce important return values from the deploy function:

    +frameworks require address information and which produce important return values from the deploy function:

    @@ -57,10 +57,10 @@

    Sometimes, when resources throw unhandled exceptions when processing requests, it is desirable to see the details of the exceptions either in the Web browser or in the console from which the application was -started. For such purposes, a parameter to the deploy +started. For such purposes, a parameter to the deploy function can be used:

    deploy(resource, handle_errors=0)
    -

    The handle_errors parameter, if specified with a +

    The handle_errors parameter, if specified with a false value, will not supress unhandled exceptions with an "internal server error" response, but will instead provide the underlying server environment's report of such exceptions.

    @@ -143,4 +143,4 @@

    See "Deploying an Application" for more details of the deployment process for each environment.

    - \ No newline at end of file +