0.5.1 (8 Oct 2002):

  * (incompatible change for anyone doing HTTP upload with Quixote)
    Improved support for HTTP upload requests: any HTTP request with
    a Content-Type of "multipart/form-data" -- which is generally only
    used for uploads -- is now represented by HTTPUploadRequest, a
    subclass of HTTPRequest, and the uploaded files themselves are
    represented by Upload objects.  See doc/upload.txt for details.

  * (possible incompatible changes for anyone subclassing Publisher,
    or using it for custom purposes)
    Various rearrangements and refactoring in the Publisher class.
    Added create_request() method, which takes responsibility for
    creating the HTTPRequest (or HTTPUploadRequest) object away
    from parse_request().  As a consequence, the signature of
    parse_request() has changed.  Added process_request() method.
    Changed publish() so it catches exceptions coming from either
    parse_request() or process_request().  Consult the source code
    (publish.py) for details.

  * A new subpackage, quixote.server, is intended for code that
    publishes a Quixote application through HTTP, making it possible
    to run Quixote applications without having to configure Apache or
    some other full-blown Web server.  Right now there's only an
    implementation on top of Medusa; contributions of support for
    Python's BaseHTTPServer, Twisted, or other frameworks would be
    welcome.

  * Modified SessionManager.maintain_session() so it explicitly removes
    a session if that session used to have useful info (ie. exists in
    the session manager), but no longer does (patch by Jon Corbet).

  * Make the PTL compiler a bit smarter about recognizing "template"
    lines; PTL code should now be able to use 'template' as an
    identifier, which is handy when converting existing Python code
    to PTL.

  * Replaced HTTPRequest.redirect() with a cleaner, more general
    version supplied by Andreas Kostyrka <andreas@kostyrka.priv.at>.
    Redirects to fully relative URLs (no leading slash) now work.

  * Added support for putting bits of JavaScript into HTML form
    documents: added HTTPResponse.add_javascript() to collect snippts
    of JavaScript code, and Form._render_javascript() to emit them
    as part of the HTML document.

  * Added global convenience functions get_path() and redirect().

  * Change Publisher so it never modifies SCRIPT_NAME or PATH_INFO.

  * Fixed bug in quixote.sendmail._add_recip_headers(): it crashed
    if passed an empty list.

  * Factor out get_action_url() method in Form class.

  * Add the HTML version of the documentation to the source release.


0.5 (10 June 2002):

  * To fix installation problems on Win98 and Mac OS (pre OS X), 
    setup.py now uses os.curdir instead of ''.

  * Overhauled handling of PublishError exceptions: Quixote now 
    looks for the nearest _q_exception_handler() function in your
    application's namespace; the format_*error() methods of Publisher
    are gone.

  * Documented and overhauled the session management API.  If you
    were previously using session management, you will almost certainly
    need to change your code; see doc/session-mgmt.txt and
    doc/session-upgrade.txt.  If you've been wanting to use session
    management in your application but were put off by the lack of
    documentation, see doc/session-mgmt.txt.

    Specific changes:
      * removed the global singleton SessionManager object in session.py
        and several related functions
      * removed everything having to do with "application state", an
        unnecessary abstraction caused by premature over-generalization
      * removed the 'actual_user' attribute from Session -- it is
        specific to the MEMS Exchange and just confuses matters
        in Quixote
      * made most instance attributes of Session private
      * defined a sensible persistence API that should work with
        a wide variety of session persistence schemes
      * COOKIE_* config variables renamed to SESSION_COOKIE_*

  * Fix HTTPResponse so that the cookie domain and path can be None,
    and they will simply not be set in the cookie sent to the client --
    that way the browser will simply do the right thing.  Set
    COOKIE_DOMAIN and COOKIE_PATH in config.py to None, since that's
    usually fine.  (You may need to set COOKIE_PATH to "/".)

  * Subtle but far-reaching change to the publishing algorithm: objects
    found by the publisher to handle the terminal component of a URL can
    now be strings as well as callables; a string simply substitutes for
    a callable's return value.  The immediate reason for this was to
    allow _q_getname() functions to return a string, but a consequence
    is that you can now put static text in global variables and simply
    publish them.

  * Add CHECK_SESSION_ADDR config variable to control whether we
    check that requests in a session all come from the same IP address,
    as a defence against playback attacks.  (Thanks to Jonathan Corbet.)

  * In error reports, print the traceback first, ahead of form variables,
    cookies, and the environment.

  * Include the HTTP_USER_AGENT variable in access log lines.

  * Add 'sort' option to SelectWidget class, to force the list of
    allowed values to be sorted in case-insensitive lexicographic order,
    with None first.


0.4.7 (18 Apr 2002):

  * Move ACCESS_TIME_RESOLUTION to SessionManager class.  This was another
    embarrassing bug introduced in 0.4.5.

  * In http_request.py, make the test that prevents stdin from being consumed
    less restrictive (e.g.  for PUT methods).

  * Add some simple test code.


0.4.6 (12 Apr 2002):

  * a last-minute patch to http_request.py just before release 0.4.5 broke
    extracting form data from GET requests -- fixed that


0.4.5 (11 Apr 2002):

  * The meaning of the DISPLAY_EXCEPTIONS configuration variable has
    changed.  It's no longer a Boolean, and instead can take three
    different values:
      None (or any false value) [default]
        an "Internal Server Error" page that exposes no information
        about the traceback
      'plain'
        a plain text page showing the traceback and the request variables
      'html'
        a more elaborate HTML display showing the local variables and a
        few lines of context for each level of the traceback.  (This
        setting requires the cgitb module that comes with Python 2.2.)

    (Idea and first version of the patch by David Ascher)

  * Fixed SessionManager.expire_session() method so it actually works
    (spotted by Robin Wohler).

  * Fixed docs so they don't refer to the obsolete URL_PREFIX
    configuration variable (spotted by Robin Wohler).

  * Various other documentation tweaks and improvements.

  * Fixed sample Apache rewrite rules in demo.txt and web-server.txt
    (spotted by Joel Shprentz).

  * Generate new form tokens when rendering a form rather then when
    intializing it.  This prevents an extra token from being created when
    processing a valid form (suggested by Robin Wohler).

  * Ensure filenames are included in SyntaxError tracebacks from PTL modules.

  * Changed format of session cookies: they're now just random 64-bit
    numbers in hex.

  * Use HTTP 1.1 cache control headers ("Date" and "Expires") instead
    of the older "Pragma: no-cache".

  * In the form/widget library: make some effort to generate HTML that
    is XHTML-compliant.

  * New method: HTTPRequest.get_accepted_types() returns the
    MIME content types a client will accept as a dictionary mapping
    MIME type to the quality factor.  (Example: {'text/html':1.0,
    'text/plain':0.5, ...})

  * Changed escape hatch for XML-RPC handlers; standard input will
    only be consumed when the HTTP method is POST and the Content-Type 
    is either application/x-www-form-urlencoded or multipart/form-data.

  * Added quixote.util module to contain various miscellaneous utility
    functions.  Right now, it contains a single function for 
    processing requests as XML-RPC invocations.


0.4.4 (29 Jan 2002):

  * Simplify munging of SCRIPT_NAME variable, fixing a bug.
    Depending on how Quixote was called, the path could have been
    appended to SCRIPT_NAME without a separating slash.  (Found by
    Quinn Dunkan.)

  * On Windows, set mode of sys.stdout to binary.  This is important
    because responses may contain binary data.  Also, EOL translation
    can throw off content length calculations.  (Found by David Ascher)

  * Added a demonstration of the form framework. (Neil)

  * Added an escape hatch for XML-RPC handlers;
    http_request.process_inputs() will no longer consume all of standard
    input when the Content-Type is text/xml.

  * Removed a debug print from form.widget.


0.4.3 (17 Dec 2001):

  * Removed the URL_PREFIX configuration variable; it's not actually
    needed anywhere, and caused some user confusion.

  * Added FORM_TOKENS configuration variable to enable/disable
    unique form identifiers.  (These are useful as a measure against
    cross-site request forgery [CSRF] attacks, but disabled by default
    because some form of persistent session management is required,
    which is not currently included with Quixote.)

  * Added demonstration and documentation for the widget classes
    (the first part of the Quixote Form Library).

  * Added HTTPResponse.set_content_type() method.

  * Fixed some minor bugs in the widget library.

  * Fixed to work with Python 2.2.

  * Greatly reduced the set of symbols imported by
    "from quixote import *" -- it's useful for interactive sessions.


0.4.2 (14 Nov 2001):

  * Made the quixote.sendmail module a bit more flexible and robust.

  * Fix so it doesn't blow up under Windows if debug logging is disabled
    (ie. write to NUL, not /dev/null).

  * Clarified some documenation inconsistencies, and added description
    of logging to doc/programming.txt.

  * Fixed some places that we forgot to update when the PTL-related
    modules were renamed.

  * Fixed ptl_compile.py so PTL tracebacks include the full path of
    source file(s).

  * Fixed bug where a missing _q_index() triggered a confusing
    ImportError; now it triggers a TraversalError, as expected.

  * Various fixes and improvements to the Config class.

  * Miscellaneous fixes to session.py.

  * Miscellaneous fixes to widget classes.

  * Reorganized internal PTL methods of the Form class.

  * Removed the "test" directory from the distribution, since it's not
    used for anything -- ie., there's no formal test suite yet ;-(


0.4.1 (10 Oct 2001):

  * Made access logging a little more portable (don't depend on Apache's
    REQUEST_URI environment variable).

  * Work around the broken value of PATH_INFO returned by IIS.

  * Work around IIS weird handling of SERVER_SECURE_PORT (for non-SSL
    requests, it is set to "0").

  * Reassign sys.stderr so all application output to stderr goes to the
    Quixote error log.


0.4 (4 Oct 2001):

  * TraversalError now takes a public and a private message, instead of
    just a single message string.  The private message is shown if
    SECURE_ERRORS is false; otherwise, the public message is shown.  See
    the class docstring for TraversalError for more details.

  * Add the Quixote Form Library, a basic form and widget framework
    for HTML.

  * Allow classes and functions inside PTL modules.

  * Return a string object from templates rather than a TemplateIO
    instance.

  * Improve the security of session cookies.

  * Don't save empty sessions.

  * Detect expired sessions.

  * Add the quixote.sendmail module, useful for applications that need
    to send outgoing mail (as many web apps do).

  * Code reorganization -- various modules moved or renamed:
      quixote.util.fcgi        -> quixote.fcgi
      quixote.compile_template -> quixote.ptl_compile
      quixote.imphooks         -> quixote.ptl_import
      quixote.dumpptlc         -> quixote.ptcl_dump

  * More code reorganization: the quixote.zope package is gone, as are
    the BaseRequest and BaseResponse modules.  Only HTTPRequest and
    HTTPResponse survive, in the quixote.http_request and
    quixote.http_response modules.  All remaining Zope-isms have been
    removed, so the code now looks much like the rest of Quixote.  Many
    internal interfaces changed.

  * Added the quixote.mod_python module, contributed by Erno Kuusela
    <erno@iki.fi>.  Allows Quixote applications to be driven by the
    Apache module mod_python, so no CGI or or FastCGI driver script is
    required.


0.3 (11 Jun 2001):

  * Now supports Python 2.1.

  * Names of the form __*__ are reserved for Python, and 2.1 is
    beginning to enforce this rule.  Accordingly the Quixote special
    methods have been renamed:
        __access__     -> _q_access
        __exports__    -> _q_exports
        __getname__    -> _q_getname
        index          -> _q_index

  * Massive changes to quixote.publisher and quixote.config, to make the
    publishing loop more flexible and more easily changed by
    applications.  For example, it's now possible to catch the ZODB's
    ConflictErrors and retry an operation.

  * Added an ACCESS_LOG configuration setting, which allows setting up a
    file logging every call made to Quixote.

  * The error log now contains the time of each error, and a dump of the
    user's session object.

  * Added handy functions for getting request, session, user, etc.:
    quixote.get_publisher(), quixote.get_request(),
    quixote.get_session(), quixote.get_user().

  * quixote.publish can now gzip-compress its output if the browser
    claims to support it.  Only the 'gzip' and 'x-gzip' content
    encodings are supported; 'deflate' isn't because we couldn't get it
    to work reliably.  Compression can be enabled by setting the
    'compress_pages' config option to true.

  * Some fixes and minor optimizations to the FCGI code.

  * Added HTTPRequest.get_encoding() method to find the encodings a
    client accepts.


0.2 (16 Jan 2001):

  * Only pass HTTPRequest object to published functions.  The
    HTTPResponse object is available as an attribute of the request.

  * Removed more unused Zope code from HTTPRequest.  Add redirect()
    method to HTTPRequest.

  * Simplify HTTPResponse.  __init__() no longer requires the server
    name.  redirect() requires a full URL.

  * Fix a bug in the PTL compiler.  PTL modules can now have doc
    strings.

  * Added a config parser.  Individual Quixote applications can now have
    their own configuration settings (overriding the Quixote defaults).
    See the config.py module for details.

  * Re-wrote the exception handling code for exceptions raised inside of
    published functions.

  * Non-empty PATH_INFO is no longer supported.  __getname__ or query
    strings are a cleaner solution.

  * Add FIX_TRAILING_SLASH option and make code changes to carefully
    preserve trailing slashes (ie. an empty component on the end of
    paths).

  * Session management has been over-hauled.  DummySessionManager can be
    used for applications that don't require sessions.

  * Set Content-length header correctly in HTTPResponse object

  * Added a demo application.

0.1:

  * Officially given a license (the Python 1.6 license, so it's free
    software).

  * Added SECURE_ERRORS variable to prevent exception tracebacks from
    being returned to the Web browser

  * Added a __getname__() function to traversal, which is called if the
    current name isn't in the current namespace's export list. This
    allows interpolation of arbitrary user object IDs into the URL,
    which is why it has to circumvent the __exports__ check: the object
    IDs won't be known until runtime, so it would be silly to add them
    to __exports__.  Very useful and powerful feature, but it has
    security implications, so be careful!

  * compile_template.py should now work for both Python 1.5.2 or 2.0.
    
  * Better reporting of syntax errors in PTL
    
  * Always assume regular CGI on Windows

0.02 (12 Aug 2000):

  * Neil Schemenauer has completely rewritten the PTL compiler and
    changed the syntax to match Python's.  The compiler now relies on
    Jeremy Hylton's compiler code from the Python 2.0 CVS tree.

  * Added functions to quixote.sessions: get_session(), has_session(),
    get_app_state()

  * Simplified reload-checking logic 

  * Added .browser_version() method to HTTPRequest

  * Various bugfixes

  * session classes slightly tweaked, so you can subclass them

  * Added .session attribute to request object

  * Added quixote.errors module to hold exceptions

0.01:

  * Initial release.