Move method split_path into oslo.utils
Method split_path was used in project keystonemiddleware, sahara. So it's good to accept it by oslo.utils. http://git.openstack.org/cgit/openstack/keystonemiddleware/tree/keystonemiddleware/s3_token.py#n50 http://git.openstack.org/cgit/openstack/sahara/tree/sahara/openstack/commons.py#n24 Change-Id: I8507a7c406d12e459809442601f3ecf919e62311
This commit is contained in:
parent
406c753a72
commit
daf4681766
@ -22,6 +22,7 @@ import re
|
||||
import unicodedata
|
||||
|
||||
import six
|
||||
from six.moves import urllib
|
||||
|
||||
from oslo_utils._i18n import _
|
||||
from oslo_utils import encodeutils
|
||||
@ -412,3 +413,52 @@ def check_string_length(value, name=None, min_length=0, max_length=None):
|
||||
"%(max_length)s.") % {'name': name, 'length': length,
|
||||
'max_length': max_length}
|
||||
raise ValueError(msg)
|
||||
|
||||
|
||||
def split_path(path, minsegs=1, maxsegs=None, rest_with_last=False):
|
||||
"""Validate and split the given HTTP request path.
|
||||
|
||||
**Examples**::
|
||||
|
||||
['a'] = _split_path('/a')
|
||||
['a', None] = _split_path('/a', 1, 2)
|
||||
['a', 'c'] = _split_path('/a/c', 1, 2)
|
||||
['a', 'c', 'o/r'] = _split_path('/a/c/o/r', 1, 3, True)
|
||||
|
||||
:param path: HTTP Request path to be split
|
||||
:param minsegs: Minimum number of segments to be extracted
|
||||
:param maxsegs: Maximum number of segments to be extracted
|
||||
:param rest_with_last: If True, trailing data will be returned as part
|
||||
of last segment. If False, and there is
|
||||
trailing data, raises ValueError.
|
||||
:returns: list of segments with a length of maxsegs (non-existent
|
||||
segments will return as None)
|
||||
:raises: ValueError if given an invalid path
|
||||
|
||||
.. versionadded:: 3.9
|
||||
"""
|
||||
if not maxsegs:
|
||||
maxsegs = minsegs
|
||||
if minsegs > maxsegs:
|
||||
raise ValueError(_('minsegs > maxsegs: %(min)d > %(max)d)') %
|
||||
{'min': minsegs, 'max': maxsegs})
|
||||
if rest_with_last:
|
||||
segs = path.split('/', maxsegs)
|
||||
minsegs += 1
|
||||
maxsegs += 1
|
||||
count = len(segs)
|
||||
if (segs[0] or count < minsegs or count > maxsegs or
|
||||
'' in segs[1:minsegs]):
|
||||
raise ValueError(_('Invalid path: %s') % urllib.parse.quote(path))
|
||||
else:
|
||||
minsegs += 1
|
||||
maxsegs += 1
|
||||
segs = path.split('/', maxsegs)
|
||||
count = len(segs)
|
||||
if (segs[0] or count < minsegs or count > maxsegs + 1 or
|
||||
'' in segs[1:minsegs] or
|
||||
(count == maxsegs + 1 and segs[maxsegs])):
|
||||
raise ValueError(_('Invalid path: %s') % urllib.parse.quote(path))
|
||||
segs = segs[1:maxsegs]
|
||||
segs.extend([None] * (maxsegs - 1 - len(segs)))
|
||||
return segs
|
||||
|
@ -694,3 +694,42 @@ class StringLengthTestCase(test_base.BaseTestCase):
|
||||
self.assertRaises(TypeError,
|
||||
strutils.check_string_length,
|
||||
dict(), max_length=255)
|
||||
|
||||
|
||||
class SplitPathTestCase(test_base.BaseTestCase):
|
||||
def test_split_path_failed(self):
|
||||
self.assertRaises(ValueError, strutils.split_path, '')
|
||||
self.assertRaises(ValueError, strutils.split_path, '/')
|
||||
self.assertRaises(ValueError, strutils.split_path, '//')
|
||||
self.assertRaises(ValueError, strutils.split_path, '//a')
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a/c')
|
||||
self.assertRaises(ValueError, strutils.split_path, '//c')
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a/c/')
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a//')
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a', 2)
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a', 2, 3)
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a', 2, 3, True)
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a/c/o/r', 3, 3)
|
||||
self.assertRaises(ValueError, strutils.split_path, '/a', 5, 4)
|
||||
|
||||
def test_split_path_success(self):
|
||||
self.assertEqual(strutils.split_path('/a'), ['a'])
|
||||
self.assertEqual(strutils.split_path('/a/'), ['a'])
|
||||
self.assertEqual(strutils.split_path('/a/c', 2), ['a', 'c'])
|
||||
self.assertEqual(strutils.split_path('/a/c/o', 3), ['a', 'c', 'o'])
|
||||
self.assertEqual(strutils.split_path('/a/c/o/r', 3, 3, True),
|
||||
['a', 'c', 'o/r'])
|
||||
self.assertEqual(strutils.split_path('/a/c', 2, 3, True),
|
||||
['a', 'c', None])
|
||||
self.assertEqual(strutils.split_path('/a/c/', 2), ['a', 'c'])
|
||||
self.assertEqual(strutils.split_path('/a/c/', 2, 3), ['a', 'c', ''])
|
||||
|
||||
def test_split_path_invalid_path(self):
|
||||
try:
|
||||
strutils.split_path('o\nn e', 2)
|
||||
except ValueError as err:
|
||||
self.assertEqual(str(err), 'Invalid path: o%0An%20e')
|
||||
try:
|
||||
strutils.split_path('o\nn e', 2, 3, True)
|
||||
except ValueError as err:
|
||||
self.assertEqual(str(err), 'Invalid path: o%0An%20e')
|
||||
|
Loading…
x
Reference in New Issue
Block a user