Ticket #2625: 2625.3.patch

File 2625.3.patch, 8.4 KB (added by danben, 4 years ago)
  • twisted/test/test_paths.py

     
    10061006class URLPathTestCase(unittest.TestCase): 
    10071007    def setUp(self): 
    10081008        self.path = urlpath.URLPath.fromString("http://example.com/foo/bar?yes=no&no=yes#footer") 
     1009        self.quotedpath = urlpath.URLPath.fromStringQuote("http://example.com/foo/hello there?yes=no&no=yes#footer") 
    10091010 
    1010     def testStringConversion(self): 
     1011    def test_stringConversion(self): 
    10111012        self.assertEquals(str(self.path), "http://example.com/foo/bar?yes=no&no=yes#footer") 
    10121013 
    1013     def testChildString(self): 
     1014    def test_childString(self): 
    10141015        self.assertEquals(str(self.path.child('hello')), "http://example.com/foo/bar/hello") 
    10151016        self.assertEquals(str(self.path.child('hello').child('')), "http://example.com/foo/bar/hello/") 
    10161017 
    1017     def testSiblingString(self): 
     1018    def test_siblingString(self): 
    10181019        self.assertEquals(str(self.path.sibling('baz')), 'http://example.com/foo/baz') 
    10191020 
    10201021        # The sibling of http://example.com/foo/bar/ 
     
    10231024        # http://example.com/foo/bar/index.html 
    10241025        self.assertEquals(str(self.path.child('').sibling('baz')), 'http://example.com/foo/bar/baz') 
    10251026 
    1026     def testParentString(self): 
     1027    def test_parentString(self): 
    10271028        # parent should be equivalent to '..' 
    10281029        # 'foo' is the current directory, '/' is the parent directory 
    10291030        self.assertEquals(str(self.path.parent()), 'http://example.com/') 
     
    10311032        self.assertEquals(str(self.path.child('baz').parent()), 'http://example.com/foo/') 
    10321033        self.assertEquals(str(self.path.parent().parent().parent().parent().parent()), 'http://example.com/') 
    10331034 
    1034     def testHereString(self): 
     1035    def test_hereString(self): 
    10351036        # here should be equivalent to '.' 
    10361037        self.assertEquals(str(self.path.here()), 'http://example.com/foo/') 
    10371038        self.assertEquals(str(self.path.child('').here()), 'http://example.com/foo/bar/') 
    1038  
     1039         
     1040    def test_fromStringQuote(self): 
     1041        """ 
     1042        Test that an URLPath constructed using C{fromStringQuote} is properly escaped. 
     1043        """ 
     1044        self.assertEquals(str(self.quotedpath), "http://example.com/foo/hello%20there?yes=no&no=yes#footer") 
     1045         
     1046    def test_childQuotedString(self):  
     1047        """ 
     1048        This test checks if child path with spaces and slashes is handled in least surprising way: 
     1049        properly escaped and result in single segment path amendment. 
     1050        """  
     1051        #child() with quotes (",') and slashes  should be properly escaped 
     1052        self.assertEquals(str(self.path.childQuote("hello/ there")), 'http://example.com/foo/bar/hello%2F%20there')  
     1053         
     1054    def test_siblingQuotedString(self):  
     1055        """ 
     1056        This test checks if sibling path with spaces and slashes is handled in least surprising way: 
     1057        properly escaped and result in single segment path amendment. 
     1058        """  
     1059        #child() with quotes (",') and slashes  should be properly escaped 
     1060        self.assertEquals(str(self.path.siblingQuote("hello/ there")), 'http://example.com/foo/hello%2F%20there') 
  • twisted/python/urlpath.py

     
    1919    _qpathlist = None 
    2020    _uqpathlist = None 
    2121     
    22     def pathList(self, unquote=0, copy=1): 
     22    def pathList(self, unquote=False, copy=True): 
    2323        if self._qpathlist is None: 
    2424            self._qpathlist = self.path.split('/') 
    2525            self._uqpathlist = map(urllib.unquote, self._qpathlist) 
     
    3333            return result 
    3434 
    3535    def fromString(klass, st): 
     36        """ 
     37        Create a new URLPath from a url string. 
     38         
     39        @param st: the url string.  Path segments should be quoted already. 
     40        @type st: C{str}  
     41         
     42        @return: A new L{URLPath} object  
     43        @rtype: L{URLPath}  
     44        """ 
    3645        t = urlparse.urlsplit(st) 
    3746        u = klass(*t) 
    3847        return u 
    3948 
    4049    fromString = classmethod(fromString) 
     50     
     51    def fromStringQuote(klass, st): 
     52        """ 
     53        Create a new URLPath from a url string. 
     54         
     55        @param st: the url string.  Path segments should not be quoted. 
     56        @type st: C{str}  
     57         
     58        @return: A new L{URLPath} object  
     59        @rtype: L{URLPath}  
     60        """ 
     61        t = urlparse.urlsplit(st) 
     62         
     63        # Quote each path segment 
     64        quotedpathparts = [urllib.quote(segment, '')  
     65                           for segment in t.path.split('/')] 
     66        newpath = '/'.join(quotedpathparts) 
     67        u = klass(scheme=t.scheme, netloc=t.netloc, path=newpath,  
     68                  query=t.query, fragment=t.fragment) 
     69        return u 
     70     
     71    fromStringQuote = classmethod(fromStringQuote) 
    4172 
    4273    def fromRequest(klass, request): 
    4374        return klass.fromString(request.prePathURL()) 
     
    5485                        '/'.join(newpathsegs), 
    5586                        query) 
    5687 
    57     def sibling(self, path, keepQuery=0): 
     88    def sibling(self, path, keepQuery=False): 
     89        """  
     90        Create a new URLPath with the last path segment replaced.   
     91      
     92        @param path: new path segment. The path argument should be quoted already.  
     93        @type path: C{str}  
     94        @param keepQuery: if set to True, will keep the query part of URL,   
     95                          else (and by default) will strip the query part.  
     96        @type keepQuery: C{bool}  
     97        @return: A new L{URLPath} object with the new last path segment 
     98        @rtype: L{URLPath}  
     99        """  
    58100        l = self.pathList() 
    59101        l[-1] = path 
    60102        return self._pathMod(l, keepQuery) 
     103     
     104    def siblingQuote(self, path, keepQuery=False): 
     105        """  
     106        Create a new URLPath with the last path segment replaced.   
     107      
     108        @param path: new path segment. The path argument should not be quoted.  
     109        @type path: C{str}  
     110        @param keepQuery: if set to True, will keep the query part of URL,   
     111                          else (and by default) will strip the query part.  
     112        @type keepQuery: C{bool}  
     113        @return: A new L{URLPath} object with the new last path segment 
     114        @rtype: L{URLPath}  
     115        """  
     116        #Clean up path with urlescaped version  
     117        quotedPath = urllib.quote(path,'') 
     118        l = self.pathList() 
     119        l[-1] = quotedPath 
     120        return self._pathMod(l, keepQuery) 
    61121 
    62     def child(self, path, keepQuery=0): 
     122    def child(self, path, keepQuery=False): 
     123        """  
     124        Create a new URLPath with an added child segment.   
     125      
     126        @param path: path segment to add. The path argument should be quoted already.  
     127        @type path: C{str}  
     128        @param keepQuery: if set to True, will keep the query part of URL,   
     129                          else (and by default) will strip the query part.  
     130        @type keepQuery: C{bool}  
     131        @return: A new L{URLPath} object with path appended to current object  
     132        @rtype: L{URLPath}  
     133        """  
    63134        l = self.pathList() 
    64135        if l[-1] == '': 
    65136            l[-1] = path 
    66137        else: 
    67138            l.append(path) 
    68139        return self._pathMod(l, keepQuery) 
     140     
     141    def childQuote(self, path, keepQuery=False): 
     142        """  
     143        Create a new URLPath with an added child segment.   
     144      
     145        @param path: path segment to add. The path argument should not be quoted.  
     146        @type path: C{str}  
     147        @param keepQuery: if set to True, will keep the query part of URL,   
     148                          else (and by default) will strip the query part.  
     149        @type keepQuery: C{bool}  
     150        @return: A new L{URLPath} object with path appended to current object  
     151        @rtype: L{URLPath}  
     152        """  
     153        #Clean up path with urlescaped version  
     154        quotedPath = urllib.quote(path,'') 
     155        l = self.pathList() 
     156        if l[-1] == '': 
     157            l[-1] = quotedPath 
     158        else: 
     159            l.append(quotedPath) 
     160        return self._pathMod(l, keepQuery) 
    69161 
    70     def parent(self, keepQuery=0): 
     162    def parent(self, keepQuery=False): 
    71163        l = self.pathList() 
    72164        if l[-1] == '': 
    73165            del l[-2] 
     
    78170            l[-1] = '' 
    79171        return self._pathMod(l, keepQuery) 
    80172 
    81     def here(self, keepQuery=0): 
     173    def here(self, keepQuery=False): 
    82174        l = self.pathList() 
    83175        if l[-1] != '': 
    84176            l[-1] = ''