208 lines
8.5 KiB
ReStructuredText
208 lines
8.5 KiB
ReStructuredText
PEP: 268
|
|
Title: Extended HTTP functionality and WebDAV
|
|
Author: Greg Stein <gstein@lyra.org>
|
|
Status: Rejected
|
|
Type: Standards Track
|
|
Content-Type: text/x-rst
|
|
Created: 20-Aug-2001
|
|
Python-Version: 2.x
|
|
Post-History: 21-Aug-2001
|
|
|
|
|
|
Rejection Notice
|
|
================
|
|
|
|
This PEP has been rejected. It has failed to generate sufficient
|
|
community support in the six years since its proposal.
|
|
|
|
|
|
Abstract
|
|
========
|
|
|
|
This PEP discusses new modules and extended functionality for Python's
|
|
HTTP support. Notably, the addition of authenticated requests, proxy
|
|
support, authenticated proxy usage, and WebDAV_ capabilities.
|
|
|
|
|
|
Rationale
|
|
=========
|
|
|
|
Python has been quite popular as a result of its "batteries included"
|
|
positioning. One of the most heavily used protocols, HTTP (see
|
|
:rfc:`2616`), has been included with Python for years (``httplib``). However,
|
|
this support has not kept up with the full needs and requirements of
|
|
many HTTP-based applications and systems. In addition, new protocols
|
|
based on HTTP, such as WebDAV and XML-RPC, are becoming useful and are
|
|
seeing increasing usage. Supplying this functionality meets Python's
|
|
"batteries included" role and also keeps Python at the leading edge of
|
|
new technologies.
|
|
|
|
While authentication and proxy support are two very notable features
|
|
missing from Python's core HTTP processing, they are minimally handled
|
|
as part of Python's URL handling (``urllib`` and
|
|
``urllib2``). However, applications that need fine-grained or
|
|
sophisticated HTTP handling cannot make use of the features while they
|
|
reside in urllib. Refactoring these features into a location where
|
|
they can be directly associated with an HTTP connection will improve
|
|
their utility for both urllib and for sophisticated applications.
|
|
|
|
The motivation for this PEP was from several people requesting these
|
|
features directly, and from a number of feature requests on
|
|
SourceForge. Since the exact form of the modules to be provided and
|
|
the classes/architecture used could be subject to debate, this PEP was
|
|
created to provide a focal point for those discussions.
|
|
|
|
|
|
Specification
|
|
=============
|
|
|
|
Two modules will be added to the standard library: ``httpx`` (HTTP
|
|
extended functionality), and ``davlib`` (WebDAV library).
|
|
|
|
[ suggestions for module names are welcome; ``davlib`` has some
|
|
precedence, but something like ``webdav`` might be desirable ]
|
|
|
|
|
|
HTTP Authentication
|
|
-------------------
|
|
|
|
The ``httpx`` module will provide a mixin for performing HTTP
|
|
authentication (for both proxy and origin server authentication). This
|
|
mixin (``httpx.HandleAuthentication``) can be combined with the
|
|
``HTTPConnection`` and the ``HTTPSConnection`` classes (the mixin may
|
|
possibly work with the HTTP and HTTPS compatibility classes, but that
|
|
is not a requirement).
|
|
|
|
The mixin will delegate the authentication process to one or more
|
|
"authenticator" objects, allowing multiple connections to share
|
|
authenticators. The use of a separate object allows for a long term
|
|
connection to an authentication system (e.g. LDAP). An authenticator
|
|
for the Basic and Digest mechanisms (see :rfc:`2617`) will be
|
|
provided. User-supplied authenticator subclasses can be registered and
|
|
used by the connections.
|
|
|
|
A "credentials" object (``httpx.Credentials``) is also associated with
|
|
the mixin, and stores the credentials (e.g. username and password)
|
|
needed by the authenticators. Subclasses of Credentials can be created
|
|
to hold additional information (e.g. NT domain).
|
|
|
|
The mixin overrides the ``getresponse()`` method to detect ``401
|
|
(Unauthorized)`` and ``407 (Proxy Authentication Required)``
|
|
responses. When this is found, the response object, the connection,
|
|
and the credentials are passed to the authenticator corresponding with
|
|
the authentication scheme specified in the response (multiple
|
|
authenticators are tried in decreasing order of security if multiple
|
|
schemes are in the response). Each authenticator can examine the
|
|
response headers and decide whether and how to resend the request with
|
|
the correct authentication headers. If no authenticator can
|
|
successfully handle the authentication, then an exception is raised.
|
|
|
|
Resending a request, with the appropriate credentials, is one of the
|
|
more difficult portions of the authentication system. The difficulty
|
|
arises in recording what was sent originally: the request line, the
|
|
headers, and the body. By overriding putrequest, putheader, and
|
|
endheaders, we can capture all but the body. Once the endheaders
|
|
method is called, then we capture all calls to send() (until the next
|
|
putrequest method call) to hold the body content. The mixin will have
|
|
a configurable limit for the amount of data to hold in this fashion
|
|
(e.g. only hold up to 100k of body content). Assuming that the entire
|
|
body has been stored, then we can resend the request with the
|
|
appropriate authentication information.
|
|
|
|
If the body is too large to be stored, then the ``getresponse()``
|
|
simply returns the response object, indicating the 401 or 407
|
|
error. Since the authentication information has been computed and
|
|
cached (into the Credentials object; see below), the caller can simply
|
|
regenerate the request. The mixin will attach the appropriate
|
|
credentials.
|
|
|
|
A "protection space" (see :rfc:`2617`, section 1.2) is defined as a tuple
|
|
of the host, port, and authentication realm. When a request is
|
|
initially sent to an HTTP server, we do not know the authentication
|
|
realm (the realm is only returned when authentication fails). However,
|
|
we do have the path from the URL, and that can be useful in
|
|
determining the credentials to send to the server. The Basic
|
|
authentication scheme is typically set up hierarchically: the
|
|
credentials for ``/path`` can be tried for ``/path/subpath``. The
|
|
Digest authentication scheme has explicit support for the hierarchical
|
|
setup. The ``httpx.Credentials`` object will store credentials for
|
|
multiple protection spaces, and can be looked up in two different
|
|
ways:
|
|
|
|
1. looked up using ``(host, port, path)`` -- this lookup scheme is
|
|
used when generating a request for a path where we don't know the
|
|
authentication realm.
|
|
|
|
2. looked up using ``(host, port, realm)`` -- this mechanism is used
|
|
during the authentication process when the server has specified that
|
|
the Request-URI resides within a specific realm.
|
|
|
|
The ``HandleAuthentication`` mixin will override ``putrequest()`` to
|
|
automatically insert credentials, if available. The URL from the
|
|
putrequest is used to determine the appropriate authentication
|
|
information to use.
|
|
|
|
It is also important to note that two sets of credentials are used,
|
|
and stored by the mixin. One set for any proxy that may be used, and
|
|
one used for the target origin server. Since proxies do not have
|
|
paths, the protection spaces in the proxy credentials will always use
|
|
"/" for storing and looking up via a path.
|
|
|
|
|
|
Proxy Handling
|
|
--------------
|
|
|
|
The ``httpx`` module will provide a mixin for using a proxy to perform
|
|
HTTP(S) operations. This mixin (``httpx.UseProxy``) can be combined
|
|
with the ``HTTPConnection`` and the ``HTTPSConnection`` classes (the
|
|
mixin may possibly work with the HTTP and HTTPS compatibility classes,
|
|
but that is not a requirement).
|
|
|
|
The mixin will record the ``(host, port)`` of the proxy to use. XXX
|
|
will be overridden to use this host/port combination for connections
|
|
and to rewrite request URLs into the absoluteURIs referring to the
|
|
origin server (these URIs are passed to the proxy server).
|
|
|
|
Proxy authentication is handled by the ``httpx.HandleAuthentication``
|
|
class since a user may directly use ``HTTP(S)Connection`` to speak
|
|
with proxies.
|
|
|
|
|
|
WebDAV Features
|
|
---------------
|
|
|
|
The ``davlib`` module will provide a mixin for sending WebDAV requests
|
|
to a WebDAV-enabled server. This mixin (``davlib.DAVClient``) can be
|
|
combined with the ``HTTPConnection`` and the ``HTTPSConnection``
|
|
classes (the mixin may possibly work with the HTTP and HTTPS
|
|
compatibility classes, but that is not a requirement).
|
|
|
|
The mixin provides methods to perform the various HTTP methods defined
|
|
by HTTP in :rfc:`2616`, and by WebDAV in :rfc:`2518`.
|
|
|
|
A custom response object is used to decode ``207 (Multi-Status)``
|
|
responses. The response object will use the standard library's xml
|
|
package to parse the multistatus XML information, producing a simple
|
|
structure of objects to hold the multistatus data. Multiple parsing
|
|
schemes will be tried/used, in order of decreasing speed.
|
|
|
|
|
|
Reference Implementation
|
|
========================
|
|
|
|
The actual (future/final) implementation is being developed in the
|
|
``/nondist/sandbox/Lib`` directory, until it is accepted and moved
|
|
into the main Lib directory.
|
|
|
|
|
|
References
|
|
==========
|
|
|
|
.. _WebDAV: http://www.webdav.org/
|
|
|
|
|
|
Copyright
|
|
=========
|
|
|
|
This document has been placed in the public domain.
|