changeset 4625:1c60c378eb1a

updated werkzeug
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sun, 01 Mar 2009 23:13:49 +0100
parents fb5abe50c6d2
children 25532a36f2b5
files MoinMoin/support/werkzeug/__init__.py MoinMoin/support/werkzeug/contrib/fixers.py MoinMoin/support/werkzeug/contrib/lint.py MoinMoin/support/werkzeug/serving.py
diffstat 4 files changed, 87 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/support/werkzeug/__init__.py	Sun Mar 01 21:57:08 2009 +0100
+++ b/MoinMoin/support/werkzeug/__init__.py	Sun Mar 01 23:13:49 2009 +0100
@@ -103,11 +103,19 @@
 # keep a reference to this module so that it's not garbage collected
 old_module = sys.modules['werkzeug']
 
+# figure out the version
+try:
+    version = __import__('pkg_resources').get_distribution('Werkzeug').version
+except:
+    version = 'unknown'
+
 # setup the new module and patch it into the dict of loaded modules
 new_module = sys.modules['werkzeug'] = module('werkzeug')
 new_module.__dict__.update({
-    '__file__': __file__,
-    '__path__': __path__,
-    '__doc__':  __doc__,
-    '__all__':  tuple(object_origins) + tuple(attribute_modules)
+    '__file__':         __file__,
+    '__path__':         __path__,
+    '__doc__':          __doc__,
+    '__all__':          tuple(object_origins) + tuple(attribute_modules),
+    '__docformat__':    'restructuredtext en',
+    '__version__':      version
 })
--- a/MoinMoin/support/werkzeug/contrib/fixers.py	Sun Mar 01 21:57:08 2009 +0100
+++ b/MoinMoin/support/werkzeug/contrib/fixers.py	Sun Mar 01 23:13:49 2009 +0100
@@ -22,6 +22,8 @@
 class LighttpdCGIRootFix(object):
     """Wrap the application in this middleware if you are using lighttpd
     with FastCGI or CGI and the application is mounted on the URL root.
+
+    :param app: the WSGI application
     """
 
     def __init__(self, app):
@@ -45,6 +47,8 @@
     `REQUEST_URL`, or `UNENCODED_URL` (whatever is available).  Thus the
     fix can only be applied if the webserver supports either of these
     variables.
+
+    :param app: the WSGI application
     """
 
     def __init__(self, app):
@@ -76,6 +80,8 @@
     The original values of `REMOTE_ADDR` and `HTTP_HOST` are stored in
     the WSGI environment as `werkzeug.proxy_fix.orig_remote_addr` and
     `werkzeug.proxy_fix.orig_http_host`.
+
+    :param app: the WSGI application
     """
 
     def __init__(self, app):
@@ -94,3 +100,35 @@
         if forwarded_host:
             environ['HTTP_HOST'] = forwarded_host
         return self.app(environ, start_response)
+
+
+class HeaderRewriterFix(object):
+    """This middleware can remove response headers and add others.  This
+    is for example useful to remove the `Date` header from responses if you
+    are using a server that adds that header, no matter if it's present or
+    not or to add `X-Powered-By` headers::
+
+        app = HeaderRewriterFix(app, remove_headers=['Date'],
+                                add_headers=[('X-Powered-By', 'WSGI')])
+
+    :param app: the WSGI application
+    :param remove_headers: a sequence of header keys that should be
+                           removed.
+    :param add_headers: a sequence of ``(key, value)`` tuples that should
+                        be added.
+    """
+
+    def __init__(self, app, remove_headers=None, add_headers=None):
+        self.app = app
+        self.remove_headers = set(x.lower() for x in (remove_headers or ()))
+        self.add_headers = list(add_headers or ())
+
+    def __call__(self, environ, start_response):
+        def rewriting_start_response(status, headers, exc_info=None):
+            new_headers = []
+            for key, value in headers:
+                if key.lower() not in self.remove_headers:
+                    new_headers.append((key, value))
+            new_headers += self.add_headers
+            return start_response(status, new_headers, exc_info)
+        return self.app(environ, rewriting_start_response)
--- a/MoinMoin/support/werkzeug/contrib/lint.py	Sun Mar 01 21:57:08 2009 +0100
+++ b/MoinMoin/support/werkzeug/contrib/lint.py	Sun Mar 01 23:13:49 2009 +0100
@@ -168,12 +168,9 @@
                 if bytes_sent:
                     warn(HTTPWarning('%r responses must not have a body' %
                                      status_code))
-            else:
-                if content_length is None:
-                    warn(WSGIWarning('Content-Length header missing'))
-                elif content_length != bytes_sent:
-                    warn(WSGIWarning('Content-Length and the number of bytes '
-                                     'sent to the client do not match.'))
+            elif content_length is not None and content_length != bytes_sent:
+                warn(WSGIWarning('Content-Length and the number of bytes '
+                                 'sent to the client do not match.'))
 
     def __del__(self):
         if not self.closed:
--- a/MoinMoin/support/werkzeug/serving.py	Sun Mar 01 21:57:08 2009 +0100
+++ b/MoinMoin/support/werkzeug/serving.py	Sun Mar 01 23:13:49 2009 +0100
@@ -50,12 +50,15 @@
 from itertools import chain
 from SocketServer import ThreadingMixIn, ForkingMixIn
 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
+
+from werkzeug import __version__ as version
 from werkzeug._internal import _log
 from werkzeug.utils import responder
 from werkzeug.exceptions import InternalServerError
 
 
 class BaseRequestHandler(BaseHTTPRequestHandler, object):
+    server_version = 'Werkzeug/' + version
 
     def run_wsgi(self):
         path_info, _, query = urlparse(self.path)[2:5]
@@ -97,8 +100,18 @@
                 status, response_headers = headers_sent[:] = headers_set
                 code, msg = status.split(None, 1)
                 self.send_response(int(code), msg)
-                for line in response_headers:
-                    self.send_header(*line)
+                header_keys = set()
+                for key, value in response_headers:
+                    self.send_header(key, value)
+                    key = key.lower()
+                    header_keys.add(key)
+                if 'content-length' not in header_keys:
+                    self.close_connection = True
+                    self.send_header('Connection', 'close')
+                if 'server' not in header_keys:
+                    self.send_header('Server', self.version_string())
+                if 'date' not in header_keys:
+                    self.send_header('Date', self.date_time_string())
                 self.end_headers()
 
             assert type(data) is str, 'applications must write bytes'
@@ -149,10 +162,25 @@
             self.server.log('error', 'Error on request:\n%s',
                             traceback.plaintext)
 
-    def __getattr__(self, name):
-        if name.startswith('do_'):
-            return self.run_wsgi
-        raise AttributeError(name)
+    def handle_one_request(self):
+        """Handle a single HTTP request."""
+        self.raw_requestline = self.rfile.readline()
+        if not self.raw_requestline:
+            self.close_connection = 1
+        elif self.parse_request():
+            return self.run_wsgi()
+
+    def send_response(self, code, message=None):
+        """Send the response header and log the response code."""
+        self.log_request(code)
+        if message is None:
+            message = code in self.responses and self.responses[code][0] or ''
+        if self.request_version != 'HTTP/0.9':
+            self.wfile.write("%s %d %s\r\n" %
+                             (self.protocol_version, code, message))
+
+    def version_string(self):
+        return BaseHTTPRequestHandler.version_string(self).strip()
 
 
 class BaseWSGIServer(HTTPServer):