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 unicodedata
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
from six.moves import urllib
|
||||||
|
|
||||||
from oslo_utils._i18n import _
|
from oslo_utils._i18n import _
|
||||||
from oslo_utils import encodeutils
|
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)s.") % {'name': name, 'length': length,
|
||||||
'max_length': max_length}
|
'max_length': max_length}
|
||||||
raise ValueError(msg)
|
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,
|
self.assertRaises(TypeError,
|
||||||
strutils.check_string_length,
|
strutils.check_string_length,
|
||||||
dict(), max_length=255)
|
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