[z3-checkins] r40151 - in z3/deliverance/DeliveranceVHoster/trunk: . docs dvhoster

ianb at codespeak.net ianb at codespeak.net
Sat Mar 10 00:27:03 CET 2007


Author: ianb
Date: Sat Mar 10 00:26:59 2007
New Revision: 40151

Modified:
   z3/deliverance/DeliveranceVHoster/trunk/development.ini
   z3/deliverance/DeliveranceVHoster/trunk/docs/example_init_domain.py
   z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py
   z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py
Log:
Added a request headers override, with example for openplans for setting the header X-Openplans-Project to the project name.  Also added a request header scrubber, so we can scrub all X-Openplans headers on the way in.

Modified: z3/deliverance/DeliveranceVHoster/trunk/development.ini
==============================================================================
--- z3/deliverance/DeliveranceVHoster/trunk/development.ini	(original)
+++ z3/deliverance/DeliveranceVHoster/trunk/development.ini	Sat Mar 10 00:26:59 2007
@@ -22,6 +22,9 @@
 #debug_bodies = true
 # To disable the rewriting of links:
 #rewrite_links = false
+# Use this to remove certain headers from any request:
+#   (note: this matches the *environmental key*, not the original header)
+#clean_environ_headers_regex = ^HTTP_X_OPENPLANS
 
 # WARNING: *THE LINE BELOW MUST BE UNCOMMENTED ON A PRODUCTION ENVIRONMENT*
 # Debug mode will enable the interactive debugging tool, allowing ANYONE to

Modified: z3/deliverance/DeliveranceVHoster/trunk/docs/example_init_domain.py
==============================================================================
--- z3/deliverance/DeliveranceVHoster/trunk/docs/example_init_domain.py	(original)
+++ z3/deliverance/DeliveranceVHoster/trunk/docs/example_init_domain.py	Sat Mar 10 00:26:59 2007
@@ -32,6 +32,8 @@
     domain_info.theme_uri = app_conf['default_theme_uri']
     domain_info.set_rule_file(
         'rule.xml', rule_data)
-    
+    domain_info.additional_request_headers = [
+        ('X-Openplans-Project', project),
+        ]
     
     

Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py
==============================================================================
--- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py	(original)
+++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dataprovider.py	Sat Mar 10 00:26:59 2007
@@ -184,6 +184,10 @@
     redirects = descriptors.json_converter(
         persist.file_property('redirects.txt', default=()))
 
+    additional_request_headers = descriptors.json_converter(
+        persist.file_property('additional_request_headers.txt'),
+        default=())
+
     def aliases__rename(self, old_aliases, new_aliases):
         dropped = list(old_aliases)
         added = list(new_aliases)
@@ -273,6 +277,24 @@
     optional_keys = ('path', 'prefix', 'comment')
     trail_slash_keys = ('prefix', 'rewrite')
 
+class HeaderValidator(validators.FancyValidator):
+    header_name_re = re.compile(r'^[a-zA-Z][a-zA-Z0-9-]+$')
+    header_value_re = re.compile(r'^[^\n\r\000-\037\200-\377]*$')
+    
+    def validate_python(self, value, state=None):
+        assert isinstance(value, list), (
+            "Value must be a list (not %r)" % value)
+        for item in list:
+            assert isinstance(value, (list, tuple)), (
+                "Item must be a list or tuple (not %r)" % value)
+            assert len(item) == 2, (
+                "Item must be a two-tuple (not %r)" % value)
+            header, value = item
+            assert header_name_re.search(header), (
+                "Header name invalid: %r" % header)
+            assert header_value_re.search(value), (
+                "Header value invalid: %r" % value)
+
 class ProviderApp(server.ApplicationWrapper):
 
     theme_uri = server.Setter(
@@ -285,6 +307,8 @@
         validator=RemoteURIValidator())
     redirects = server.JSONSetter(
         validator=RewriteValidator())
+    additional_request_headers = server.JSONSetter(
+        validator=HeaderValidator())
 
     @server.appfactory()
     def rules(self):

Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py
==============================================================================
--- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py	(original)
+++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py	Sat Mar 10 00:26:59 2007
@@ -1,3 +1,4 @@
+import re
 import posixpath
 import os
 import urlparse
@@ -32,16 +33,20 @@
         self.app_conf = app_conf
         self.provider = DataProvider(data_dir)
         self.rewrite_links = asbool(app_conf.get('rewrite_links', True))
+        if app_conf.get('clean_environ_headers_regex'):
+            self.clean_environ_headers_regex = re.compile(app_conf['clean_environ_headers_regex'])
+        else:
+            self.clean_environ_headers_regex = None
 
     def __call__(self, environ, start_response):
         if 'paste.registry' in environ:
             environ['paste.registry'].register(current_environ, environ)
+        self.clean_environ_headers(environ)
         domain = environ['HTTP_HOST']
         if ':' in domain:
             domain = domain.split(':', 1)[0]
         domain = self.provider.normalize(domain)
         domain_info = self.provider.domain(domain)
-        print domain_info, domain_info.initialized
         if not domain_info.initialized:
             domain_info.initialize()
             if self.init_domain:
@@ -116,7 +121,11 @@
                     exc = httpexceptions.HTTPMovedPermanently(
                         headers=[('Location', new_uri)])
                     return exc(environ, start_response)
-                    
+
+        for header_name, header_value in domain_info.additional_request_headers:
+            header_name = 'HTTP_%s' % header_name.upper().replace('-', '_')
+            environ[header_name] = header_value
+        
         for remote_uri_info in remote_uris:
             path = remote_uri_info['path']
             if not path.endswith('/'):
@@ -162,3 +171,11 @@
         if os.path.exists(path):
             return path
         return None
+
+    def clean_environ_headers(self, environ):
+        if not self.clean_environ_headers_regex:
+            return
+        for key in environ.keys():
+            if self.clean_environ_headers_regex.search(key):
+                # @@: Should log this
+                del environ[key]


More information about the z3-checkins mailing list