Description

The standalone server doesn't work when using it behind a proxy that doesn't map to a root directory.

It also doesn't support HTTP authentication in Apache reverse proxy setups.

-- Marc-Andre Lemburg <mal@egenix.com>

Steps to reproduce

  1. Running a standalone server as http://localhost:4200/mywiki/ causes the root page to be names "mywiki"

  2. Using authmodule.http doesn't work in such a setup

Example

No example available.

Details

This patch against Moin 1.5.6 fixes both problems:

--- /usr/local/src/moin-1.5.6/MoinMoin/request.py       2006-10-08 15:50:08.000000000 +0200
+++ request.py  2006-11-01 21:38:54.067887397 +0100
@@ -5,11 +5,11 @@
     @copyright: 2001-2003 by Jürgen Hermann <jh@web.de>
     @copyright: 2003-2006 by Thomas Waldmann
     @license: GNU GPL, see COPYING for details.
 """

-import os, re, time, sys, cgi, StringIO
+import os, re, time, sys, cgi, StringIO, base64
 import copy
 from MoinMoin import config, wikiutil, user, caching
 from MoinMoin import error, multiconfig
 from MoinMoin.util import MoinMoinNoFooter, IsWin9x

@@ -495,22 +495,25 @@ class RequestBase(object):
         TODO: does not work for Apache 1 and others that do not allow
         setting custom headers per request.

         @param env: dict like object containing cgi meta variables or http headers.
         """
+        scriptAndPath = self.script_name + self.path_info
+
+        # Adjust .script_name
         location = (env.get(self.moin_location) or
                     env.get(cgiMetaVariable(self.moin_location)))
-        if location is None:
-            return
-
-        scriptAndPath = self.script_name + self.path_info
-        location = location.rstrip('/')
-        self.script_name = location
-
-        # This may happen when using mod_python
-        if scriptAndPath.startswith(location):
-            self.path_info = scriptAndPath[len(location):]
+        if location is not None:
+            location = location.rstrip('/')
+            self.script_name = location
+            # This may happen when using mod_python
+            if scriptAndPath.startswith(location):
+                self.path_info = scriptAndPath[len(location):]
+
+        # Remove .script_name from .path_info
+        if self.path_info.startswith(self.script_name):
+            self.path_info = self.path_info[len(self.script_name):]

         # Recreate the URI from the modified parts
         if self.request_uri:
             self.request_uri = self.makeURI()

@@ -1678,11 +1681,13 @@ class RequestStandAlone(RequestBase):
         """
         try:
             self.sareq = sa
             self.wfile = sa.wfile
             self.rfile = sa.rfile
-            self.headers = sa.headers
+            env = sa.headers
+            self.headers = env
+            self.env = env
             self.is_ssl = 0

             # Copy headers
             self.http_accept_language = (sa.headers.getheader('accept-language')
                                          or self.http_accept_language)
@@ -1690,23 +1695,38 @@ class RequestStandAlone(RequestBase):
             co = filter(None, sa.headers.getheaders('cookie'))
             self.saved_cookie = ', '.join(co) or ''
             self.if_modified_since = sa.headers.getheader('if-modified-since')
             self.if_none_match = sa.headers.getheader('if-none-match')

+            # Get path
+            path = sa.path
+            script_name = properties.get('script_name', '')
+            if script_name and path.startswith(script_name):
+                path = path[len(script_name):]
+
             # Copy rest from standalone request
             self.server_name = sa.server.server_name
             self.server_port = str(sa.server.server_port)
             self.request_method = sa.command
-            self.request_uri = sa.path
+            self.request_uri = path
+            self.script_name = script_name
             self.remote_addr = sa.client_address[0]

-            # Values that need more work
-            self.path_info, self.query_string = self.splitURI(sa.path)
+            # Values that need more work
+            self.path_info, self.query_string = self.splitURI(path)
             self.setHttpReferer(sa.headers.getheader('referer'))
             self.setHost(sa.headers.getheader('host'))
             self.setURL(sa.headers)

+            # Decode authorization (from Apache reverse proxy)
+            auth = sa.headers.get('authorization', None)
+            if auth is not None:
+                auth_type, credentials = auth.split()
+                env['AUTH_TYPE'] = auth_type
+                if auth_type == 'Basic':
+                    env['REMOTE_USER'] = base64.decodestring(credentials).split(':')[0]
+
             ##self.debugEnvironment(sa.headers)

             RequestBase.__init__(self, properties)

         except Exception, err:

Workaround

Discussion

Plan


CategoryMoinMoinBug

MoinMoin: MoinMoinBugs/Standalone Server behind Proxy (last edited 2007-10-29 19:08:32 by localhost)