--- a/lib/http.py Sun Feb 08 03:13:11 2009 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,227 +0,0 @@
-"""
- WSGI HTTP utility code
-"""
-
-# for utility functions
-import cgi
-
-# for header handling
-import wsgiref.headers
-
-# for path handling
-import os.path
-
-class Request (object) :
- """
- HTTP Request with associated metadata
- """
-
- def __init__ (self, env) :
- """
- Parse env data
- """
-
- # store env
- self.env = env
-
- # get the querystring
- self.arg_str = env.get('QUERY_STRING', '')
-
- # parse query args
- self.arg_dict = cgi.parse_qs(self.arg_str, True)
-
- @property
- def site_host (self) :
- """
- Returns the site's hostname (DNS name)
- """
-
- return self.env['HTTP_HOST']
-
- @property
- def site_root (self) :
- """
- Returns the URL path to the requested script's directory with no trailing slash, i.e.
-
- / ->
- /foo.cgi ->
- /foo/bar.cgi -> /foo
- """
-
- return os.path.dirname(self.env['SCRIPT_NAME']).rstrip('/')
-
- @property
- def page_prefix (self) :
- """
- Returns the URL path root for page URLs, based on REQUEST_URI with PATH_INFO removed
-
- / ->
- /foo.cgi -> /foo.cgi
- /foo.cgi/index -> /foo.cgi
- /foo.cgi/quux/bar -> /foo.cgi
- /quux/foo.cgi/bar -> /quux/foo.cgi
- /bar ->
- """
-
- # XXX: request uri path without the query string
- request_path = self.env.get('REQUEST_URI', '').split('?', 1)[0].rstrip('/')
-
- # path info
- page_name = self.get_page_name()
-
- # special-case for empty page_name
- if not page_name :
- return request_path
-
- # sanity-check
- assert request_path.endswith(page_name)
-
- # trim
- return request_path[:-len(page_name)].rstrip('/')
-
- def get_page_name (self) :
- """
- Returns the requested page path with no leading slash, i.e.
-
- /foo.cgi ->
- /foo.cgi/ ->
- /foo.cgi/bar -> bar
- /foo.cgi/quux/ -> quux/
- """
-
- # the raw PATH_INFO
- path_info = self.env.get('PATH_INFO')
-
- # avoid nasty '.' paths
- if path_info :
- return os.path.normpath(path_info).lstrip('/')
-
- else :
- return ''
-
- def get_args (self) :
- """
- Iterate over all available (key, value) pairs from the query string
- """
-
- return cgi.parse_qsl(self.arg_str)
-
-class Response (object) :
- """
- HTTP Response with headers and data
- """
-
- def __init__ (self, data, content_type='text/html', status='200 OK', charset='UTF-8') :
- """
- Create the response. The Content-type header is built from the given values. The given \a data must be
- either a str (which is sent plain), an unicode object (which is encoded with the relevant charset), or
- None, whereupon an empty response body is sent. The content_type argument can also be forced to None to
- not send a Content-type header (e.g. for redirects)
- """
-
- # store info
- self.status = status
- self.data = data
- self.charset = charset
-
- # headers
- self.headers = wsgiref.headers.Headers([])
-
- # add Content-type header?
- if content_type :
- self.add_header('Content-type', content_type, charset=charset)
-
- def add_header (self, name, value, **params) :
- """
- Add response header with the given name/value, plus option params
-
- XXX: uses the wsgiref.headers code, not sure how that behaves re multiple headers with the same name, etc
- """
-
- self.headers.add_header(name, value, **params)
-
- def get_status (self) :
- """
- Returns response status string (XXX Foo)
- """
-
- return self.status
-
- def get_headers (self) :
- """
- Returns the list of header (name, value) pairs
- """
-
- return self.headers.items()
-
- def get_data (self) :
- """
- Returns the response data - as an encoded string
- """
-
- if self.data :
- return self.data.encode(self.charset)
-
- else :
- return ''
-
-class ErrorResponse (Response) :
- """
- A response with an error code / message
- """
-
- def __init__ (self, status, message, details=None) :
- """
- Build a plain error message response with the given status/message
-
- @param status HTTP status code
- @param message short message to describe errors
- @param details optional details, plaintext
- """
-
- data = """\
-<html><head><title>%(title)s</title></head><body>
-<h1>%(title)s</h1>
-<p>%(message)s</p>
-%(details)s
-</body></html>
-""" % dict(
- title = status,
- message = message,
- details = '<pre>%s</pre>' % details if details else ''
- )
-
- super(ErrorResponse, self).__init__(data, status=status)
-
-class ResponseError (Exception) :
- """
- An exception that results in a specfic 4xx ErrorResponse message to the client
- """
-
- def __init__ (self, message, status='400 Bad Request', details=None) :
- self.status = status
- self.message = message
- self.details = details
-
- super(ResponseError, self).__init__(message)
-
- def get_response (self) :
- return ErrorResponse(self.status, self.message, self.details)
-
-class Redirect (Response) :
- """
- Redirect response
- """
-
- def __init__ (self, url) :
- """
- Redirect to given *absolute* URL
- """
-
- # no content-type or data
- super(Redirect, self).__init__(None, content_type=None, status='302 Found')
-
- # add Location: header
- self.add_header("Location", url)
-
-