summaryrefslogtreecommitdiff
path: root/Mailman/Cgi/wsgi_app.py
diff options
context:
space:
mode:
authortkikuchi2006-11-09 01:13:59 +0000
committertkikuchi2006-11-09 01:13:59 +0000
commit28690731c0e6b13d60629223a7a9dbccc442f8ee (patch)
tree76576c9d8f0bf748dd38c37879f0c51a4a4f3a46 /Mailman/Cgi/wsgi_app.py
parentcf6448420c10aaf4cd7a8af27058df852017cb7c (diff)
downloadmailman-28690731c0e6b13d60629223a7a9dbccc442f8ee.tar.gz
mailman-28690731c0e6b13d60629223a7a9dbccc442f8ee.tar.zst
mailman-28690731c0e6b13d60629223a7a9dbccc442f8ee.zip
Diffstat (limited to 'Mailman/Cgi/wsgi_app.py')
-rw-r--r--Mailman/Cgi/wsgi_app.py40
1 files changed, 39 insertions, 1 deletions
diff --git a/Mailman/Cgi/wsgi_app.py b/Mailman/Cgi/wsgi_app.py
index 8e77352d6..402745e3b 100644
--- a/Mailman/Cgi/wsgi_app.py
+++ b/Mailman/Cgi/wsgi_app.py
@@ -16,8 +16,10 @@
# USA.
import os
+import re
import sys
+from urlparse import urlparse
from cStringIO import StringIO
from email import message_from_string
@@ -25,6 +27,9 @@ from Mailman.configuration import config
# XXX Should this be configurable in Defaults.py?
STEALTH_MODE = False
+MOVED_RESPONSE = '302 Found'
+# Above is for debugging convenience. We should use:
+# MOVED_RESPONSE = '301 Moved Permanently'
@@ -35,11 +40,15 @@ def websafe(s):
SCRIPTS = ['admin', 'admindb', 'confirm', 'create',
'edithtml', 'listinfo', 'options', 'private',
'rmlist', 'roster', 'subscribe']
+ARCHVIEW = ['private']
SLASH = '/'
NL2 = '\n\n'
CRLF2 = '\r\n\r\n'
+dotonly = re.compile(r'^\.+$')
+
+SCRIPT_BASE = urlparse(config.DEFAULT_URL_PATTERN)[2]
# WSGI to CGI wrapper. Mostly copied from scripts/driver.
@@ -62,11 +71,40 @@ def mailman_app(environ, start_response):
path = environ['PATH_INFO']
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'
+ start_response(MOVED_RESPONSE, [('Location', newpath)])
+ return 'Location: ' + newpath
script = paths[1]
if script in SCRIPTS:
environ['SCRIPT_NAME'] = script
if len(paths) > 2:
- environ['PATH_INFO'] = SLASH + SLASH.join(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.