/usr/share/pyshared/albatross/httpdapp.py is in python-albatross 1.36-5.5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | #
# Copyright 2003 by Object Craft P/L, Melbourne, Australia.
#
# LICENCE - see LICENCE file distributed with this software for details.
#
# AUTHOR(S)
# Matt Goodall <matt AT pollenation DOT net>
import BaseHTTPServer
import cgi
import mimetypes
from cStringIO import StringIO
from urlparse import urlsplit
import os.path
import shutil
import time
import stat
from albatross.request import RequestBase
from albatross.common import *
RFC822_FORMAT = '%a, %d %b %Y %H:%M:%S +0000'
class Request(RequestBase):
"""
BaseHTTPServer request adaptor
We set up an environment to look like we've been invoked
via a web server, and let the standard cgi module parse
the request.
"""
def __init__(self, handler):
self.__handler = handler
self.__headers = []
environ = {
'REQUEST_METHOD': self.__handler.command,
'QUERY_STRING': urlsplit(self.__handler.requestline.split()[1])[3],
}
self.__handler.headers.setdefault('content-type',
'application/x-www-form-urlencoded')
field_storage = cgi.FieldStorage(fp = self.__handler.rfile,
headers = self.__handler.headers,
environ = environ)
RequestBase.__init__(self, field_storage)
def get_header(self, name):
return self.__handler.headers.get(name)
def write_header(self, name, value):
self.__headers.append((name, value))
def end_headers(self):
self.__handler.send_response(self.status())
for name, value in self.__headers:
self.__handler.send_header(name, value)
self.__handler.end_headers()
def get_uri(self):
return self.__handler.path
def get_method(self):
return self.__handler.command
def get_path_info(self):
return self.__handler.path
def get_servername(self):
server_name = self.__handler.server.server_name
port = self.__handler.server.server_port
return '%s:%d' % (server_name, port)
def write_content(self, data):
self.__handler.wfile.write(data)
def redirect(self, loc):
self.set_status(HTTP_MOVED_PERMANENTLY)
self.write_header('Location', loc)
self.end_headers()
class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""
Handle HTTP request, routing them through to the Albatross
application
"""
def do_GET(self):
# Try the static resources first
if self.server.static_resources:
for uri_path, fs_path in self.server.static_resources:
if self.path.startswith(uri_path):
path = self.path.split(uri_path)[1]
self.send_file('%s%s' % (fs_path, path))
return
self.process_request()
def do_POST(self):
self.process_request()
def process_request(self):
'''Process a request to the Albatross app'''
self.server.app.run(Request(self))
def send_file(self, path):
'''Send a file directly from the filesystem'''
# Stat the file
try:
stats = os.stat(path)
except OSError, e:
self.send_error(HTTP_NOT_FOUND)
self.end_headers()
return
# Get the last modified date in RFC822 form
last_modified = time.gmtime(stats[stat.ST_MTIME])
last_modified = time.strftime(RFC822_FORMAT, last_modified)
# See if a 304 (not modified) is enough
ts = self.headers.get('If-Modified-Since')
if ts and ts == last_modified:
self.send_response(HTTP_NOT_MODIFIED)
self.end_headers()
return
# Need to send the whole file
f = None
try:
try:
f = file(path, 'rb')
self.send_response(HTTP_OK)
self.send_header('Content-Type', mimetypes.guess_type(path)[0])
self.send_header('Content-Length', os.path.getsize(path))
self.send_header('Last-Modified', last_modified)
self.end_headers()
shutil.copyfileobj(f, self.wfile)
except IOError, e:
self.send_error(HTTP_FORBIDDEN)
self.end_headers()
finally:
if f:
f.close()
class HTTPServer(BaseHTTPServer.HTTPServer):
"""
Simple, standalone HTTP server for Albatross applications.
HTTPServer is a simple web server dedicated to processing requests and
mapping that request through to Albatross. It can also serve static
resources such as images, stylesheets etc directly from the filesystem.
"""
def __init__(self, app, port, static_resources=None):
'''
Create an HTTP server for the Albatross application, app,
and listen for requests on the specified port.
static_resources is an optional list that maps uri paths to
a corresponding filesystem path. Static resources are served directly
from the filesystem without involving the Albatross application.
'''
BaseHTTPServer.HTTPServer.__init__( self, ('', port), RequestHandler)
self.app = app
try:
self.static_resources = static_resources.items()
except AttributeError:
self.static_resources = static_resources
|