1515import re
1616import sys
1717
18+ from collections import defaultdict
19+ from urllib .parse import unquote
1820from warnings import warn
1921
2022from HTTPExceptions import HTTPNotFound , HTTPMovedPermanently
2123from MiscUtils .ParamFactory import ParamFactory
22- from WebUtils .Funcs import urlDecode
2324
2425debug = False
2526
@@ -249,7 +250,7 @@ def parse(self, trans, requestPath):
249250 through `Request.serverSidePath` and `Request.contextName`).
250251 """
251252 # This is a hack... should probably go in the Transaction class:
252- trans ._fileParserInitSeen = {}
253+ trans ._fileParserInitSeen = defaultdict ( set )
253254 # If there is no path, redirect to the root path:
254255 req = trans .request ()
255256 if not requestPath :
@@ -259,7 +260,7 @@ def parse(self, trans, requestPath):
259260 p += "?" + q
260261 raise HTTPMovedPermanently (location = p )
261262 # Determine the context name:
262- context = [_f for _f in requestPath .split ('/' ) if _f ]
263+ context = [p for p in requestPath .split ('/' ) if p ]
263264 if requestPath .endswith ('/' ):
264265 context .append ('' )
265266 parts = []
@@ -345,7 +346,9 @@ def parse(self, trans, requestPath):
345346 req = trans .request ()
346347
347348 # First decode the URL, since we are dealing with filenames here:
348- requestPath = urlDecode (requestPath )
349+ # We must use unquote instead of unquote_plus, because decoding
350+ # the plus sign should only happen for the query string.
351+ requestPath = unquote (requestPath )
349352
350353 result = self .parseInit (trans , requestPath )
351354 if result is not None :
@@ -620,7 +623,7 @@ def parseInit(self, trans, requestPath):
620623 self ._initModule = self .initModule ()
621624 mod = self ._initModule
622625
623- seen = trans ._fileParserInitSeen . setdefault ( self ._path , set ())
626+ seen = trans ._fileParserInitSeen [ self ._path ]
624627
625628 if ('urlTransactionHook' not in seen
626629 and hasattr (mod , 'urlTransactionHook' )):
0 commit comments