![](https://web.archive.org/web/20010307022153im_/http://classic.zope.org:8080/Images/white_spacer.gif)
Zope ORB
Introduction
The Zope ORB provides a simple mechanism for publishing a
collection of Python objects as World-Wide-Web (Web) resources without any
plumbing (e.g. CGI) specific code. The Zope ORB is the central
component of the Zope web application platform.
The Zope ORB is part of the ZPublisher Package.
Benefits
Applications do not have to include code for interfacing with the
web server.
Applications can be moved from one publishing mechanism, such as
CGI, to another mechanism, such as PCGI, ZopeHTTPServer, Fast CGI or COM, with no change.
Python objects are published as Python objects. The web server
"calls" the objects in much the same way that other Python objects
would.
Automatic conversion of URL to object/sub-object traversal.
Automatic marshaling of form data, cookie data, and request
meta-data to Python function arguments.
Automated exception handling.
Automatic generation of CGI headers.
Automated authentication and authorization.
Published objects
Objects are published by including them in a published module.
When a module is published, any objects that:
can be found in the module's global name space,
that do not have names starting with an underscore,
that have non-empty documentation strings, and
that are not modules
are published.
Sub-objects (or sub-sub objects, ...) of published objects are
also published, as long as the sub-objects:
have non-empty doc strings,
have names that do not begin with an underscore, and
are not modules.
Note that object methods are considered to be subobjects.
Object-to-subobject traversal is done by converting steps in the URI
path to get attribute or get item calls. For example, in traversing
from http://some.host/some_module/object to
http://some.host/some_module/object/subobject , the module
publisher will try to get some_module.object.subobject . If the
access fails with other than an attribute error, then the object
publisher raises a "NotFound" exception. If the access fails with
an attribute error, then the object publisher will try to obtain the
subobject with: some_module.object["subobject"] . If this access
fails, then the object publisher raises a "Not Found" exception. If
either of the accesses suceeds, then, of course, processing continues.
During object traversal, the names . and .. have special meaning
if the application does not provide meaning for them. If the name
. is encountered and the application does not provide a value,
then the name is effectively skipped. For example, the path x/./y
is equivalent to x/y . If the name .. is encountered and the
application does not provide a value, then the parent of the object
being traversed is used. For example, x/y/../z is almost
equivalent to x/z , except that y is considered to be part of the
path to z . If y has a user folder, it will be consulted when
validadting access to z before a user folder in x is consulted.
Normally, URL traversal begins with the published module. If the
Published module has a global variable named bobo_application ,
then traversal begins with this object instead.
If the final object encountered when traversing the URL has an
index_html attribute, the object traversal will continue to this
attribute. This is useful for providing default methods for objects.
Access Control
Object access can be further controlled via
roles and user databases.
The Zope authorization model uses roles to control access to
objects. As Zope traverses URLs, it checked for __roles__
attributes in the objects it encounters. The last value found
controls access to the published object.
If found, __roles__ should be None or a sequence of role names. If
__roles__ is None , then the published object is public. If
__roles__ is not None , then the user must provide a user name and
password that can be validated by a user database.
Zope Permissions
The Zope platform offers a higher level of abstraction for binding roles to methods with
permissions.
A permission is a collection of methods. When a permission is bound to a role, it equivanent
to assigning the given role to each method in the permission. Permissions allow easier
managment through the web.
User Databases
If an object has a __roles__ attribute that is not empty and not
None , Zope tries to find a user database to authenticate the user.
It searches for user databases by looking for an __allow_groups__
attribute, first in the published object, then in it's container,
and so on until a user database is found. When a user database
is found, Zope attempts to validate the user against the user
database. If validation fails, then Zope will continue searching
for user databases until the user can be validated or until no
more user databases can be found.
User database objects
The user database may be an object that provides a validate method:
validate(request, http_authorization, roles)
where:
-
request a mapping object that contains request information,
-
http_authorization the value of the HTTP Authorization header
or None if no authorization header was provided, and
-
roles a list of user role names
The validate method returns None if it cannot validate a user and
a user object if it can. Normally, if the validate method returns
None , Zope will try to use other user databases, however, a user
database can prevent this by raising an exception.
If validation succeeds Zope assigns the user object to the
request variable, AUTHENTICATED_USER . Zope currently places
no restriction on user objects.
Mapping user databases
If the user database is a mapping object, then the keys of the
object are role names and values are the associated user groups for
the roles. Zope attempts to validate the user by searching
for a user name and password matching the user name and
password given in the HTTP Authorization header in a groups for
role names matching the roles in the published object's
__roles__ attribute.
If validation succeeds Zope assigns the user name to the
request variable, AUTHENTICATED_USER .
Zope User Folders
The Zope platform provides a default user database object called a User Folder.
User folders allow easy managment of users and roles though the web.
Authentication user interface
When a user first accesses a protected object, Zope returns an
error response to the web browser that causes a password dialog
to be displayed.
Specifying a realm name for basic authentication
You can control the realm name used for Zope's Basic
authentication by providing a module variable named
__bobo_realm__ .
Using the web server to perform authentication
Some web servers cannot be coaxed into passing authentication
information to applications. In this case, Zope applications
cannot perform authentication. If the web server is configured
to authenticate access to a Zope application, then the Zope
application can still perform authorization using the
REMOTE_USER variable. Zope does this automatically when
mapping user databases are used, and custom user databases may
do this too.
In this case, it may be necessary to provide more than one path
to an application, one that is authenticated, and one that
isn't, if public methods and non-public methods are
interspursed.
Fixed-attribute objects
For some interesting objects, such as functions, and methods,
it may not be possible for applications to set
__roles__ attributes. In these cases, the
object's parent object may contain attribute
object_name__roles__ , which
will be used as surrogates for the object's
__role__ attribute.
Function, method, and class objects
If a published object is a function, method, or class, then the
object will be called and the return value of the call will be
returned as the HTTP resonse. Calling arguments will be supplied
from "environment variables", from URL-encoded form data, if any,
and from HTTP cookies by matching argument names defined for the
object with variable names.
Accessing request data directly
If the object being called has an argument named REQUEST , then
a request object will be passed. Request objects encapsulate
request meta data and provide full access to all environment
data, form data, cookies, and the input data stream (i.e. body
data as a stream).
Providing finer control over responses and stream output
If the object being called has an argument named RESPONSE ,
then a response object will be passed. This object can be used
to specify HTTP headers and to perform stream-oriented output.
Rather than returning a result, data may be output by calling
the write and flush methods of the response object one or more
times. This is useful, for example, when outputing results from
a time-consuming task, since partial results may be displayed
long before complete results are available.
Argument Types and File upload
Normally, string arguments are passed to called objects. The
called object must be prepared to convert string arguments to
other data types, such as numbers.
If file upload fields are used, however, then FileUpload objects
will be passed instead for these fields. FileUpload objects
bahave like file objects and provide attributes for inspecting the
uploaded file's source name and the upload headers, such as
content-type.
If field names in form data are of the form: name:type, then an
attempt will be to convert data from from strings to the indicated
type. The data types currently supported are:
- float
Python floating point numbers
- int
Python integers
- long
Python long integers
- string
python strings
- required
non-blank python strings
- date
Date-time values
- list
Python list of values, even if there is only
one value.
- lines
Python list of values entered as multiple lines
in a single field
- tokens
Python list of values entered as multiple space-separated
tokens in a single field
- tuple
Python tuple of values, even if there is only one.
- method
Augment PATH_INFO with information from the form field.
(See "Method Arguments" blow.)
For example, if the name of a field in an input
form is age:int , then the field value will be passed in argument,
age, and an attempt will be made to convert the argument value to
an integer. This conversion also works with file upload, so using
a file upload field with a name like myfile:string will cause the
UploadFile to be converted to a string before being passed to the
object.
Method Arguments
Sometimes, it is desireble to control which method is called based
on form data. For example, one might have a form with a select
list and want to choose which method to call depening on the item
chosen. Similarly, one might have multiple submit buttons and want
to invoke a different method for each button.
Zope provides a way to select methods using form variables through
use of the "method" argument type. The method type allows the
request PATH_INFO to be augmented using information from a
form item name or value.
If the name of a form field is :method , then the value of the
field is added to PATH_INFO . For example, if the original
PATH_INFO is foo/bar and the value of a :method field is
x/y , then PATH_INFO is transformed to foo/bar/x/y . This is
useful when presenting a select list. Method names can be
placed in the select option values.
If the name of a form field ends in :method and is longer than 7
characters, then the part of the name before :method is added to
PATH_INFO . For example, if the original PATH_INFO is
foo/bar and there is a x/y:method field, then PATH_INFO is
transformed to foo/bar/x/y . In this case, the form value is
ignored. This is useful for mapping submit buttons to methods,
since submit button values are displayed and should, therefore,
not contain method names.
Only one method field should be provided. If more than one method
field is included in the request, the behavior is undefined.
The base HREF is set when method fields are provided. In the
above examples, the base HREF is set to .../foo/bar/x . Of
course, if, in this example, y was an object with an index_html
method, then the base HREF would be reset to .../foo/bar/x/y .
Published objects that are not functions, methods, or classes
If a published object that is not a function, method, or class
is accessed, then the object itself will be returned.
Return types
A published object, or the returned value of a called published
object can be of any Python type. If the returned value has an
asHTML method, then this method will be called to convert the
object to HTML, otherwise the returned value will be converted to a
string and examined to see if it appears to be an HTML document. If
it appears to be an HTML document, then the response content-type
will be set to text/html . Otherwise the content-type will be set
to text/plain .
If the returned object is None or the string representation of the
returned object is an empty string, then the HTTP return status will
be set to "No Content", and no body will be returned. On some
browsers, this will cause the displayed document to be unchanged.
Base References
In general, in Zope, relative URL references should be interpreted
relative to the parent of the published object, to make it easy for
objects to provide links to siblings.
If
the result of a request is HTML text,
the text does not define a base tag in the head portion of
the HTML, and
The published object had an index_html attribute that was not included
in the request URL,
then a base reference will be inserted that is the URL of the
published object.
Exception handling
Unhandled exceptions are caught by the object publisher
and are translated automatically to nicely formatted HTTP output.
When an exception is raised, the exception type is mapped to an HTTP
code by matching the value of the exception type with a list of
standard HTTP status names. Any exception types that do not match
standard HTTP status names are mapped to "Internal Error" (500).
The standard HTTP status names are: "OK" , "Created" ,
"Accepted" , "No Content" , "Multiple Choices" , "Redirect" ,
"Moved Permanently" , "Moved Temporarily" , "Not Modified" ,
"Bad Request" , "Unauthorized" , "Forbidden" , "Not Found" ,
"Internal Error" , "Not Implemented" , "Bad Gateway" , and
"Service Unavailable" , Variations on these names with different
cases and without spaces are also valid.
An attempt is made to use the exception value as the body of the
returned response. The object publisher will examine the exception
value. If the value is a string that contains some white space,
then it will be used as the body of the return error message. It it
appears to be HTML, the the error content type will be set to
text/html , otherwise, it will be set to text/plain . If the
exception value is not a string containing white space, then the
object publisher will generate it's own error message.
There are two exceptions to the above rule:
If the exception type is: "Redirect" , "Multiple Choices"
"Moved Permanently" , "Moved Temporarily" , or
"Not Modified" , and the exception value is an absolute URI,
then no body will be provided and a Location header will be
included in the output with the given URI.
If the exception type is "No Content" , then no body will be
returned.
When a body is returned, traceback information will be included in a
comment in the output. The module variable
__bobo_hide_tracebacks__ can be used to control how tracebacks are
included. If this variable and false, then tracebacks are included
in PRE tags, rather than in comments. This is very handy during
debugging.
Redirection
Automatic redirection may be performed by a published object
by raising an exception with a type and value of "Redirect" and
a string containing an absolute URI.
The default object
If no object is specified in a URI, then the publisher will try to
publish the object index_html , if it exists, otherwise the module's
doc string will be published.
Pre- and post-call hooks
If a published module defines objects __bobo_before__ or
__bobo_after__ , then these functions will be called before
or after a request is processed. One possible use for this is to
acquire and release application locks in applications with
background threads.
|