Revision: 8092
          http://svn.sourceforge.net/mailman/?rev=8092&view=rev
Author:   tkikuchi
Date:     2006-11-13 04:29:34 -0800 (Mon, 13 Nov 2006)

Log Message:
-----------
Fix environ['SCRIPT_NAME'] to match CGI spec.
Also, the now scripts can be accessed by arbitrary script base.
E.g. /listinfo can be accessed by /mailman/listinfo or /mailman/blah/listinfo
etc. etc.  This is useful in testing wsgi directly without apache frontend
but we may have to limit the length or depth of prefixed script base.

Modified Paths:
--------------
    trunk/mailman/Mailman/Cgi/Auth.py
    trunk/mailman/Mailman/Cgi/wsgi_app.py
    trunk/mailman/Mailman/SecurityManager.py

Modified: trunk/mailman/Mailman/Cgi/Auth.py
===================================================================
--- trunk/mailman/Mailman/Cgi/Auth.py   2006-11-12 03:14:00 UTC (rev 8091)
+++ trunk/mailman/Mailman/Cgi/Auth.py   2006-11-13 12:29:34 UTC (rev 8092)
@@ -38,7 +38,7 @@
     if frontpage:
         actionurl = url
     else:
-        request = Utils.GetRequestURI(url)
+        request = Utils.GetRequestURI(url).lstrip('/')
         up = '../' * request.count('/')
         actionurl = up + request
     if msg:

Modified: trunk/mailman/Mailman/Cgi/wsgi_app.py
===================================================================
--- trunk/mailman/Mailman/Cgi/wsgi_app.py       2006-11-12 03:14:00 UTC (rev 
8091)
+++ trunk/mailman/Mailman/Cgi/wsgi_app.py       2006-11-13 12:29:34 UTC (rev 
8092)
@@ -48,9 +48,7 @@
 
 dotonly = re.compile(r'^\.+$')
 
-SCRIPT_BASE = urlparse(config.DEFAULT_URL_PATTERN)[2]
 
-
 
 # WSGI to CGI wrapper.  Mostly copied from scripts/driver.
 def mailman_app(environ, start_response):
@@ -74,89 +72,81 @@
         paths = path.split(SLASH)
         # sanity check for paths
         spaths = [ i for i in paths[1:] if i and not dotonly.match(i) ]
-        # Do some path mangling here because someone may access with
-        # trailing slash for script.  (Eg., /mailman/listinfo/ ->
-        # /mailman/listinfo)  Use of SCRIPT_BASE breaks relative
-        # URI principle but we do believe mailman WSGI should NOT exposed
-        # to the Internet.
-        if spaths != paths[1:]:
-            if path == SLASH:
-                newpath = SCRIPT_BASE + 'listinfo'
-            else:
-                # Sanitize URI by spaths
-                if paths[1] not in ARCHVIEW:
-                    newpath = SCRIPT_BASE + SLASH.join(spaths)
-                else:
-                    # 'private' is different because, if trailing slash is
-                    # present, it silently redirecte to index.html.
-                    # Let's make it explicit here.
-                    newpath = SCRIPT_BASE + SLASH.join(spaths) + '/index.html'
+        if spaths and spaths != paths[1:]:
+            newpath = SLASH + SLASH.join(spaths)
             start_response(MOVED_RESPONSE, [('Location', newpath)])
             return 'Location: ' + newpath
-        script = paths[1]
-        if script in SCRIPTS:
-            environ['SCRIPT_NAME'] = script
-            if len(paths) > 2:
-                path_info = SLASH + SLASH.join(paths[2:])
-                if script in ARCHVIEW \
-                   and len(paths) in (3,4) \
-                   and not paths[-1].split('.')[-1] in ('html', 'txt', 'gz'):
-                    # /private/listname or /private/listname/YYYYmm
-                    newpath = SCRIPT_BASE + SLASH.join(spaths) + '/index.html'
-                    start_response(MOVED_RESPONSE, [('Location', newpath)])
-                    return 'Location: ' + newpath
-                environ['PATH_INFO'] = path_info
-            else:
-                environ['PATH_INFO'] = ''
-            # Reverse proxy environment.
-            if environ.has_key('HTTP_X_FORWARDED_HOST'):
-                environ['HTTP_HOST'] = environ['HTTP_X_FORWARDED_HOST']
-            if environ.has_key('HTTP_X_FORWARDED_FOR'):
-                environ['REMOTE_HOST'] = environ['HTTP_X_FORWARDED_FOR']
-            modname = 'Mailman.Cgi.' + script
-            # Clear previous cookie before setting new one.
-            os.environ['HTTP_COOKIE'] = ''
-            for k, v in environ.items():
-                os.environ[k] = str(v)
-            # Prepare for redirection
-            save_stdin = sys.stdin
-            # CGI writes its output to sys.stdout, while wsgi app should
-            # return (list of) strings.
-            save_stdout = sys.stdout
-            save_stderr = sys.stderr
-            tmpstdout = StringIO()
-            tmpstderr = StringIO()
-            response = ''
+        # find script name
+        for script in SCRIPTS:
+            if script in spaths:
+                # Get script position in spaths and break.
+                scrpos = spaths.index(script)
+                break
+        else:
+            # Can't find valid script.
+            start_response('404 Not Found', [])
+            return '404 Not Found'
+        # Conpose CGI SCRIPT_NAME and PATH_INFO from WSGI path
+        script_name = SLASH + SLASH.join(spaths[:scrpos+1])
+        environ['SCRIPT_NAME'] = script_name
+        if len(paths) > scrpos+2:
+            path_info = SLASH + SLASH.join(paths[scrpos+2:])
+            if script in ARCHVIEW \
+               and path_info.count('/') in (1,2) \
+               and not paths[-1].split('.')[-1] in ('html', 'txt', 'gz'):
+                # Add index.html if /private/listname or
+                # /private/listname/YYYYmm is requested.
+                newpath = script_name + path_info + '/index.html'
+                start_response(MOVED_RESPONSE, [('Location', newpath)])
+                return 'Location: ' + newpath
+            environ['PATH_INFO'] = path_info
+        else:
+            environ['PATH_INFO'] = ''
+        # Reverse proxy environment.
+        if environ.has_key('HTTP_X_FORWARDED_HOST'):
+            environ['HTTP_HOST'] = environ['HTTP_X_FORWARDED_HOST']
+        if environ.has_key('HTTP_X_FORWARDED_FOR'):
+            environ['REMOTE_HOST'] = environ['HTTP_X_FORWARDED_FOR']
+        modname = 'Mailman.Cgi.' + script
+        # Clear previous cookie before setting new one.
+        os.environ['HTTP_COOKIE'] = ''
+        for k, v in environ.items():
+            os.environ[k] = str(v)
+        # Prepare for redirection
+        save_stdin = sys.stdin
+        # CGI writes its output to sys.stdout, while wsgi app should
+        # return (list of) strings.
+        save_stdout = sys.stdout
+        save_stderr = sys.stderr
+        tmpstdout = StringIO()
+        tmpstderr = StringIO()
+        response = ''
+        try:
             try:
-                try:
-                    sys.stdin  = environ['wsgi.input']
-                    sys.stdout = tmpstdout
-                    sys.stderr = tmpstderr
-                    __import__(modname)
-                    sys.modules[modname].main()
-                    response = sys.stdout.getvalue()
-                finally:
-                    sys.stdin  = save_stdin
-                    sys.stdout = save_stdout
-                    sys.stderr = save_stderr
-            except SystemExit:
-                sys.stdout.write(tmpstdout.getvalue())
-            if response:
-                try:
-                    head, content = response.split(NL2, 1)
-                except ValueError:
-                    head, content = response.split(CRLF2, 1)
-                m = message_from_string(head + CRLF2)
-                start_response('200 OK', m.items())
-                return [content]
-            else:
-                # TBD: Error Code/Message
-                start_response('500 Server Error', [])
-                return '500 Internal Server Error'
+                sys.stdin  = environ['wsgi.input']
+                sys.stdout = tmpstdout
+                sys.stderr = tmpstderr
+                __import__(modname)
+                sys.modules[modname].main()
+                response = sys.stdout.getvalue()
+            finally:
+                sys.stdin  = save_stdin
+                sys.stdout = save_stdout
+                sys.stderr = save_stderr
+        except SystemExit:
+            sys.stdout.write(tmpstdout.getvalue())
+        if response:
+            try:
+                head, content = response.split(NL2, 1)
+            except ValueError:
+                head, content = response.split(CRLF2, 1)
+            m = message_from_string(head + CRLF2)
+            start_response('200 OK', m.items())
+            return [content]
         else:
-             # TBD: Error Message
-             start_response('404 Not Found', [])
-             return '404 Not Found'
+            # TBD: Error Code/Message
+            start_response('500 Server Error', [])
+            return '500 Internal Server Error'
     except:
         start_response('200 OK', [('Content-Type', 'text/html')])
         retstring = print_traceback(log)

Modified: trunk/mailman/Mailman/SecurityManager.py
===================================================================
--- trunk/mailman/Mailman/SecurityManager.py    2006-11-12 03:14:00 UTC (rev 
8091)
+++ trunk/mailman/Mailman/SecurityManager.py    2006-11-13 12:29:34 UTC (rev 
8092)
@@ -95,7 +95,7 @@
         # AuthUser, but the user isn't a member of this mailing list, a
         # NotAMemberError will be raised.  If the user's secret is None, raise
         # a MMBadUserError.
-        key = self.internal_name() + '+'
+        key = urllib.quote(self.fqdn_listname) + '+'
         if authcontext == Defaults.AuthUser:
             if user is None:
                 # A bad system error
@@ -236,7 +236,7 @@
         # way to do it -- the original uri that's proxied to us is not
         # included in the backend request.  XXX what happens when Apache 2.2's
         # ProxyPassReverseCookiePath is set?
-        target = '/%s/%s' % (os.environ['SCRIPT_NAME'], self.fqdn_listname)
+        target = '%s/%s' % (os.environ['SCRIPT_NAME'], self.fqdn_listname)
         referer = os.environ.get('HTTP_REFERER')
         if not referer:
             return target
@@ -305,7 +305,7 @@
                 usernames = [user]
             else:
                 usernames = []
-                prefix = self.internal_name() + '+user+'
+                prefix = urllib.quote(self.fqdn_listname) + '+user+'
                 for k in c.keys():
                     if k.startswith(prefix):
                         usernames.append(k[len(prefix):])


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe: 
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org

Reply via email to