Index: lib/python/mod_python/publisher.py =================================================================== --- lib/python/mod_python/publisher.py (revision 240397) +++ lib/python/mod_python/publisher.py (working copy) @@ -113,6 +113,7 @@ if req.method not in ["GET", "POST", "HEAD"]: raise apache.SERVER_RETURN, apache.HTTP_METHOD_NOT_ALLOWED + """ if exists(req.filename): # The file or directory exists, so we have a request of the form : @@ -182,7 +183,96 @@ # We remove the last dot if any if func_path[-1:] == ".": func_path = func_path[:-1] + """ + + # Derive the name of the actual module which will be + # loaded. In older version of mod_python.publisher + # you can't actually have a code file name which has + # an embedded '.' in it except for that used by the + # extension. This is because the standard Python + # module import system which is used will think that + # you are importing a submodule of a package. In + # this code, because the standard Python module + # import system isn't used and the actual file is + # opened directly by name, an embedded '.' besides + # that used for the extension will technically work. + + path,module_name = os.path.split(req.filename) + + # If the request is against a directory, fallback to + # looking for the 'index' module. This is determined + # by virtue of the fact that Apache will always add + # a trailing slash to 'req.filename' when it matches + # a directory. This will mean that the calculated + # module name will be empty. + + if not module_name: + module_name = 'index' + + # Now need to strip off any special extension which + # was used to trigger this handler in the first place. + + suffixes = ['py'] + suffixes += req.get_addhandler_exts().split() + if req.extension: + suffixes.append(req.extension[1:]) + + exp = '\\.' + '$|\\.'.join(suffixes) + '$' + suff_matcher = re.compile(exp) + module_name = suff_matcher.sub('',module_name) + + # Next need to determine the path for the function + # which will be called from 'req.path_info'. The + # leading slash and possibly any trailing slash are + # eliminated. There would normally be at most one + # trailing slash as Apache eliminates duplicates + # from the original URI. + + func_path = '' + + if req.path_info: + func_path = req.path_info[1:] + if func_path[-1:] == '/': + func_path = func_path[:-1] + + # Now determine the actual Python module code file + # to load. This will first try looking for the file + # '/path/.py'. If this doesn't exist, + # will try fallback of using the 'index' module, + # ie., look for '/path/index.py'. In doing this, the + # 'func_path' gets adjusted so the lead part is what + # 'module_name' was set to. + + req.filename = path + '/' + module_name + '.py' + + if not exists(req.filename): + if func_path: + func_path = module_name + '/' + func_path + else: + func_path = module_name + + module_name = 'index' + req.filename = path + '/' + module_name + '.py' + + if not exists(req.filename): + raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND + + # Default to looking for the 'index' function if no + # function path definition was supplied. + + if not func_path: + func_path = 'index' + + # Turn slashes into dots. + + func_path = func_path.replace('/', '.') + + # Normalise req.filename to avoid Win32 issues. + + req.filename = normpath(req.filename) + + # We use the page cache to load the module module = page_cache[req]