diff --git a/swift/account/server.py b/swift/account/server.py index 1c29ea84d1..005c552b1d 100644 --- a/swift/account/server.py +++ b/swift/account/server.py @@ -34,7 +34,7 @@ from swift.common.utils import get_logger, get_param, hash_path, \ from swift.common.constraints import ACCOUNT_LISTING_LIMIT, \ check_mount, check_float, check_utf8 from swift.common.db_replicator import ReplicatorRpc -from swift.common.exceptions import InvalidPathError + DATADIR = 'accounts' @@ -60,7 +60,7 @@ class AccountController(object): """Handle HTTP DELETE request.""" try: drive, part, account = split_path(unquote(req.path), 3) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if self.mount_check and not check_mount(self.root, drive): @@ -80,7 +80,7 @@ class AccountController(object): try: drive, part, account, container = split_path(unquote(req.path), 3, 4) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if self.mount_check and not check_mount(self.root, drive): @@ -135,7 +135,7 @@ class AccountController(object): try: drive, part, account, container = split_path(unquote(req.path), 3, 4) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if self.mount_check and not check_mount(self.root, drive): @@ -166,7 +166,7 @@ class AccountController(object): """Handle HTTP GET request.""" try: drive, part, account = split_path(unquote(req.path), 3) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if self.mount_check and not check_mount(self.root, drive): @@ -257,7 +257,7 @@ class AccountController(object): """ try: post_args = split_path(unquote(req.path), 3) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) drive, partition, hash = post_args @@ -275,7 +275,7 @@ class AccountController(object): """Handle HTTP POST request.""" try: drive, part, account = split_path(unquote(req.path), 3) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if 'x-timestamp' not in req.headers or \ diff --git a/swift/auth/server.py b/swift/auth/server.py index 24c1f9ce9c..2e6d2d7db0 100644 --- a/swift/auth/server.py +++ b/swift/auth/server.py @@ -30,7 +30,6 @@ from webob.exc import HTTPBadRequest, HTTPConflict, HTTPForbidden, \ from swift.common.bufferedhttp import http_connect_raw as http_connect from swift.common.db import get_db_connection from swift.common.utils import get_logger, split_path -from swift.common.exceptions import InvalidPathError class AuthController(object): @@ -416,7 +415,7 @@ YOU HAVE A FEW OPTIONS: """ try: _, token = split_path(request.path, minsegs=2) - except InvalidPathError: + except ValueError: return HTTPBadRequest() # Retrieves (TTL, account, user, cfaccount) if valid, False otherwise validation = self.validate_token(token) @@ -452,7 +451,7 @@ YOU HAVE A FEW OPTIONS: """ try: _, account_name, user_name = split_path(request.path, minsegs=3) - except InvalidPathError: + except ValueError: return HTTPBadRequest() create_reseller_admin = \ request.headers.get('x-auth-user-reseller-admin') == 'true' @@ -517,8 +516,12 @@ YOU HAVE A FEW OPTIONS: :param request: A webob.Request instance. """ - pathsegs = \ - split_path(request.path, minsegs=1, maxsegs=3, rest_with_last=True) + try: + pathsegs = \ + split_path(request.path, minsegs=1, maxsegs=3, + rest_with_last=True) + except ValueError: + return HTTPBadRequest() if pathsegs[0] == 'v1' and pathsegs[2] == 'auth': account = pathsegs[1] user = request.headers.get('x-storage-user') @@ -608,8 +611,6 @@ YOU HAVE A FEW OPTIONS: else: return HTTPBadRequest(request=env)(env, start_response) response = handler(req) - except InvalidPathError: - return HTTPNotFound()(env, start_response) except: self.logger.exception('ERROR Unhandled exception in ReST request') return HTTPServiceUnavailable(request=req)(env, start_response) diff --git a/swift/common/exceptions.py b/swift/common/exceptions.py index 504d8f7788..c498e2dae9 100644 --- a/swift/common/exceptions.py +++ b/swift/common/exceptions.py @@ -52,6 +52,3 @@ class DriveNotMounted(Exception): class LockTimeout(MessageTimeout): pass - -class InvalidPathError(Exception): - pass diff --git a/swift/common/middleware/auth.py b/swift/common/middleware/auth.py index 922e6277f7..b60c95278d 100644 --- a/swift/common/middleware/auth.py +++ b/swift/common/middleware/auth.py @@ -21,7 +21,7 @@ from webob.exc import HTTPForbidden, HTTPUnauthorized, HTTPNotFound from swift.common.bufferedhttp import http_connect_raw as http_connect from swift.common.middleware.acl import clean_acl, parse_acl, referrer_allowed from swift.common.utils import cache_from_env, split_path, TRUE_VALUES -from swift.common.exceptions import InvalidPathError + class DevAuth(object): """Auth Middleware that uses the dev auth server.""" @@ -85,7 +85,7 @@ class DevAuth(object): try: version, rest = split_path(env.get('PATH_INFO', ''), 1, 2, True) - except InvalidPathError, err: + except ValueError, err: return HTTPNotFound()(env, start_response) if rest and rest.startswith(self.reseller_prefix): # Handle anonymous access to accounts I'm the definitive @@ -148,10 +148,11 @@ class DevAuth(object): """ Returns None if the request is authorized to continue or a standard WSGI response callable if not. - - :raises: InvalidPathError (thrown by split_path) if given invalid path """ - version, account, container, obj = split_path(req.path, 1, 4, True) + try: + version, account, container, obj = split_path(req.path, 1, 4, True) + except ValueError: + return HTTPNotFound(request=req) if not account or not account.startswith(self.reseller_prefix): return self.denied_response(req) user_groups = (req.remote_user or '').split(',') diff --git a/swift/common/middleware/ratelimit.py b/swift/common/middleware/ratelimit.py index 9ba3ca06f4..707e544ae2 100644 --- a/swift/common/middleware/ratelimit.py +++ b/swift/common/middleware/ratelimit.py @@ -18,7 +18,7 @@ from webob.exc import HTTPNotFound from swift.common.utils import split_path, cache_from_env, get_logger from swift.proxy.server import get_container_memcache_key -from swift.common.exceptions import InvalidPathError + class MaxSleepTimeHit(Exception): pass @@ -207,7 +207,7 @@ class RateLimitMiddleware(object): self.memcache_client = cache_from_env(env) try: version, account, container, obj = split_path(req.path, 1, 4, True) - except InvalidPathError: + except ValueError: return HTTPNotFound()(env, start_response) ratelimit_resp = self.handle_ratelimit(req, account, container, obj) if ratelimit_resp is None: diff --git a/swift/common/utils.py b/swift/common/utils.py index 4f89a87cef..bb635725c8 100644 --- a/swift/common/utils.py +++ b/swift/common/utils.py @@ -40,8 +40,7 @@ import eventlet from eventlet import greenio, GreenPool, sleep, Timeout, listen from eventlet.green import socket, subprocess, ssl, thread, threading -from swift.common.exceptions import LockTimeout, MessageTimeout, \ - InvalidPathError +from swift.common.exceptions import LockTimeout, MessageTimeout # logging doesn't import patched as cleanly as one would like from logging.handlers import SysLogHandler @@ -209,13 +208,12 @@ def split_path(path, minsegs=1, maxsegs=None, rest_with_last=False): trailing data, raises ValueError. :returns: list of segments with a length of maxsegs (non-existant segments will return as None) - :raises: InvalidPathError if given an invalid path + :raises: ValueError if given an invalid path """ if not maxsegs: maxsegs = minsegs if minsegs > maxsegs: - raise InvalidPathError('minsegs > maxsegs: %d > %d' % (minsegs, - maxsegs)) + raise ValueError('minsegs > maxsegs: %d > %d' % (minsegs, maxsegs)) if rest_with_last: segs = path.split('/', maxsegs) minsegs += 1 @@ -223,7 +221,7 @@ def split_path(path, minsegs=1, maxsegs=None, rest_with_last=False): count = len(segs) if segs[0] or count < minsegs or count > maxsegs or \ '' in segs[1:minsegs]: - raise InvalidPathError('Invalid path: %s' % quote(path)) + raise ValueError('Invalid path: %s' % quote(path)) else: minsegs += 1 maxsegs += 1 @@ -231,7 +229,7 @@ def split_path(path, minsegs=1, maxsegs=None, rest_with_last=False): 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 InvalidPathError('Invalid path: %s' % quote(path)) + raise ValueError('Invalid path: %s' % quote(path)) segs = segs[1:maxsegs] segs.extend([None] * (maxsegs - 1 - len(segs))) return segs diff --git a/swift/container/server.py b/swift/container/server.py index a6368118c6..ff8dc76684 100644 --- a/swift/container/server.py +++ b/swift/container/server.py @@ -35,7 +35,7 @@ from swift.common.utils import get_logger, get_param, hash_path, \ from swift.common.constraints import CONTAINER_LISTING_LIMIT, \ check_mount, check_float, check_utf8 from swift.common.bufferedhttp import http_connect -from swift.common.exceptions import ConnectionTimeout, InvalidPathError +from swift.common.exceptions import ConnectionTimeout from swift.common.db_replicator import ReplicatorRpc DATADIR = 'containers' @@ -130,7 +130,7 @@ class ContainerController(object): try: drive, part, account, container, obj = split_path( unquote(req.path), 4, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if 'x-timestamp' not in req.headers or \ @@ -166,7 +166,7 @@ class ContainerController(object): try: drive, part, account, container, obj = split_path( unquote(req.path), 4, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if 'x-timestamp' not in req.headers or \ @@ -212,7 +212,7 @@ class ContainerController(object): try: drive, part, account, container, obj = split_path( unquote(req.path), 4, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if self.mount_check and not check_mount(self.root, drive): @@ -239,7 +239,7 @@ class ContainerController(object): try: drive, part, account, container, obj = split_path( unquote(req.path), 4, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if self.mount_check and not check_mount(self.root, drive): @@ -343,7 +343,7 @@ class ContainerController(object): """ try: post_args = split_path(unquote(req.path), 3) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) drive, partition, hash = post_args @@ -361,7 +361,7 @@ class ContainerController(object): """Handle HTTP POST request.""" try: drive, part, account, container = split_path(unquote(req.path), 4) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), content_type='text/plain', request=req) if 'x-timestamp' not in req.headers or \ diff --git a/swift/obj/server.py b/swift/obj/server.py index 9fda3f81ba..632a0c04cc 100644 --- a/swift/obj/server.py +++ b/swift/obj/server.py @@ -41,7 +41,7 @@ from swift.common.utils import mkdirs, normalize_timestamp, \ from swift.common.bufferedhttp import http_connect from swift.common.constraints import check_object_creation, check_mount, \ check_float, check_utf8 -from swift.common.exceptions import ConnectionTimeout, InvalidPathError +from swift.common.exceptions import ConnectionTimeout from swift.obj.replicator import get_hashes, invalidate_hash, \ recalculate_hashes @@ -313,7 +313,7 @@ class ObjectController(object): try: device, partition, account, container, obj = \ split_path(unquote(request.path), 5, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), request=request, content_type='text/plain') if 'x-timestamp' not in request.headers or \ @@ -342,7 +342,7 @@ class ObjectController(object): try: device, partition, account, container, obj = \ split_path(unquote(request.path), 5, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), request=request, content_type='text/plain') if self.mount_check and not check_mount(self.devices, device): @@ -414,7 +414,7 @@ class ObjectController(object): try: device, partition, account, container, obj = \ split_path(unquote(request.path), 5, 5, True) - except InvalidPathError, err: + except ValueError, err: return HTTPBadRequest(body=str(err), request=request, content_type='text/plain') if self.mount_check and not check_mount(self.devices, device): @@ -474,7 +474,7 @@ class ObjectController(object): try: device, partition, account, container, obj = \ split_path(unquote(request.path), 5, 5, True) - except InvalidPathError, err: + except ValueError, err: resp = HTTPBadRequest(request=request) resp.content_type = 'text/plain' resp.body = str(err) @@ -502,7 +502,7 @@ class ObjectController(object): try: device, partition, account, container, obj = \ split_path(unquote(request.path), 5, 5, True) - except InvalidPathError, e: + except ValueError, e: return HTTPBadRequest(body=str(e), request=request, content_type='text/plain') if 'x-timestamp' not in request.headers or \ @@ -537,7 +537,7 @@ class ObjectController(object): try: device, partition, suffix = split_path( unquote(request.path), 2, 3, True) - except InvalidPathError, e: + except ValueError, e: return HTTPBadRequest(body=str(e), request=request, content_type='text/plain') if self.mount_check and not check_mount(self.devices, device): diff --git a/swift/proxy/server.py b/swift/proxy/server.py index ac1f7c4c39..ca7543cc8f 100644 --- a/swift/proxy/server.py +++ b/swift/proxy/server.py @@ -39,7 +39,7 @@ from swift.common.constraints import check_metadata, check_object_creation, \ check_utf8, MAX_ACCOUNT_NAME_LENGTH, MAX_CONTAINER_NAME_LENGTH, \ MAX_FILE_SIZE from swift.common.exceptions import ChunkReadTimeout, \ - ChunkWriteTimeout, ConnectionTimeout, InvalidPathError + ChunkWriteTimeout, ConnectionTimeout def update_headers(response, headers): @@ -1260,7 +1260,7 @@ class BaseApplication(object): :param path: path from request :returns: tuple of (controller class, path dictionary) - :raises: InvalidPathError (thrown by split_path) if given invalid path + :raises: ValueError (thrown by split_path) id given invalid path """ version, account, container, obj = split_path(path, 1, 4, True) d = dict(version=version, @@ -1299,8 +1299,6 @@ class BaseApplication(object): response = self.handle_request(req)(env, start_response) self.posthooklogger(env, req) return response - except InvalidPathError: - HTTPNotFound()(env, start_response) except: print "EXCEPTION IN __call__: %s: %s" % \ (traceback.format_exc(), env) @@ -1330,7 +1328,7 @@ class BaseApplication(object): try: try: controller, path_parts = self.get_controller(req.path) - except InvalidPathError: + except ValueError: return HTTPNotFound(request=req) if not check_utf8(req.path_info): return HTTPPreconditionFailed(request=req, body='Invalid UTF8') diff --git a/swift/stats/access_processor.py b/swift/stats/access_processor.py index a21b77005a..f0ae3a023a 100644 --- a/swift/stats/access_processor.py +++ b/swift/stats/access_processor.py @@ -18,7 +18,6 @@ from urllib import unquote import copy from swift.common.utils import split_path, get_logger -from swift.common.exceptions import InvalidPathError month_map = '_ Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split() @@ -70,7 +69,7 @@ class AccessLogProcessor(object): try: (version, account, container_name, object_name) = \ split_path(request, 2, 4, True) - except InvalidPathError, e: + except ValueError, e: self.logger.debug( 'Invalid path: %s from data: %s' % (e, repr(raw_log))) return {} diff --git a/test/unit/auth/test_server.py b/test/unit/auth/test_server.py index 31e07b7cff..cb9070a22f 100644 --- a/test/unit/auth/test_server.py +++ b/test/unit/auth/test_server.py @@ -27,7 +27,6 @@ from webob import Request from swift.auth import server as auth_server from swift.common.db import DatabaseConnectionError, get_db_connection from swift.common.utils import get_logger -from swift.common.exceptions import InvalidPathError class TestException(Exception): @@ -242,8 +241,9 @@ class TestAuthServer(unittest.TestCase): len(set(repr(a) for a in cfaccounts) - set(failed)), 2) def test_auth_bad_path(self): - self.assertRaises(InvalidPathError, self.controller.handle_auth, + res = self.controller.handle_auth( Request.blank('', environ={'REQUEST_METHOD': 'GET'})) + self.assertEquals(res.status_int, 400) res = self.controller.handle_auth(Request.blank('/bad', environ={'REQUEST_METHOD': 'GET'})) self.assertEquals(res.status_int, 400) diff --git a/test/unit/common/test_utils.py b/test/unit/common/test_utils.py index f422226793..92be1077c0 100644 --- a/test/unit/common/test_utils.py +++ b/test/unit/common/test_utils.py @@ -29,7 +29,7 @@ from StringIO import StringIO from eventlet import sleep from swift.common import utils -from swift.common.exceptions import InvalidPathError + class TestUtils(unittest.TestCase): """ Tests for swift.common.utils """ @@ -87,36 +87,36 @@ class TestUtils(unittest.TestCase): def test_split_path(self): """ Test swift.common.utils.split_account_path """ - self.assertRaises(InvalidPathError, utils.split_path, '') - self.assertRaises(InvalidPathError, utils.split_path, '/') - self.assertRaises(InvalidPathError, utils.split_path, '//') + self.assertRaises(ValueError, utils.split_path, '') + self.assertRaises(ValueError, utils.split_path, '/') + self.assertRaises(ValueError, utils.split_path, '//') self.assertEquals(utils.split_path('/a'), ['a']) - self.assertRaises(InvalidPathError, utils.split_path, '//a') + self.assertRaises(ValueError, utils.split_path, '//a') self.assertEquals(utils.split_path('/a/'), ['a']) - self.assertRaises(InvalidPathError, utils.split_path, '/a/c') - self.assertRaises(InvalidPathError, utils.split_path, '//c') - self.assertRaises(InvalidPathError, utils.split_path, '/a/c/') - self.assertRaises(InvalidPathError, utils.split_path, '/a//') - self.assertRaises(InvalidPathError, utils.split_path, '/a', 2) - self.assertRaises(InvalidPathError, utils.split_path, '/a', 2, 3) - self.assertRaises(InvalidPathError, utils.split_path, '/a', 2, 3, True) + self.assertRaises(ValueError, utils.split_path, '/a/c') + self.assertRaises(ValueError, utils.split_path, '//c') + self.assertRaises(ValueError, utils.split_path, '/a/c/') + self.assertRaises(ValueError, utils.split_path, '/a//') + self.assertRaises(ValueError, utils.split_path, '/a', 2) + self.assertRaises(ValueError, utils.split_path, '/a', 2, 3) + self.assertRaises(ValueError, utils.split_path, '/a', 2, 3, True) self.assertEquals(utils.split_path('/a/c', 2), ['a', 'c']) self.assertEquals(utils.split_path('/a/c/o', 3), ['a', 'c', 'o']) - self.assertRaises(InvalidPathError, utils.split_path, '/a/c/o/r', 3, 3) + self.assertRaises(ValueError, utils.split_path, '/a/c/o/r', 3, 3) self.assertEquals(utils.split_path('/a/c/o/r', 3, 3, True), ['a', 'c', 'o/r']) self.assertEquals(utils.split_path('/a/c', 2, 3, True), ['a', 'c', None]) - self.assertRaises(InvalidPathError, utils.split_path, '/a', 5, 4) + self.assertRaises(ValueError, utils.split_path, '/a', 5, 4) self.assertEquals(utils.split_path('/a/c/', 2), ['a', 'c']) self.assertEquals(utils.split_path('/a/c/', 2, 3), ['a', 'c', '']) try: utils.split_path('o\nn e', 2) - except InvalidPathError, err: + except ValueError, err: self.assertEquals(str(err), 'Invalid path: o%0An%20e') try: utils.split_path('o\nn e', 2, 3, True) - except InvalidPathError, err: + except ValueError, err: self.assertEquals(str(err), 'Invalid path: o%0An%20e') def test_NullLogger(self):