Merge "Increase name-length limits for internal accounts"

This commit is contained in:
Zuul 2018-01-31 00:29:29 +00:00 committed by Gerrit Code Review
commit 8359f43079
4 changed files with 91 additions and 35 deletions

View File

@ -21,7 +21,6 @@ from swift.account.utils import account_listing_response
from swift.common.middleware.acl import parse_acl, format_acl
from swift.common.utils import public
from swift.common.constraints import check_metadata
from swift.common import constraints
from swift.common.http import HTTP_NOT_FOUND, HTTP_GONE
from swift.proxy.controllers.base import Controller, clear_info_cache, \
set_info_cache
@ -53,11 +52,11 @@ class AccountController(Controller):
def GETorHEAD(self, req):
"""Handler for HTTP GET/HEAD requests."""
if len(self.account_name) > constraints.MAX_ACCOUNT_NAME_LENGTH:
length_limit = self.get_name_length_limit()
if len(self.account_name) > length_limit:
resp = HTTPBadRequest(request=req)
resp.body = 'Account name length of %d longer than %d' % \
(len(self.account_name),
constraints.MAX_ACCOUNT_NAME_LENGTH)
(len(self.account_name), length_limit)
# Don't cache this. We know the account doesn't exist because
# the name is bad; we don't need to cache that because it's
# really cheap to recompute.
@ -117,11 +116,11 @@ class AccountController(Controller):
error_response = check_metadata(req, 'account')
if error_response:
return error_response
if len(self.account_name) > constraints.MAX_ACCOUNT_NAME_LENGTH:
length_limit = self.get_name_length_limit()
if len(self.account_name) > length_limit:
resp = HTTPBadRequest(request=req)
resp.body = 'Account name length of %d longer than %d' % \
(len(self.account_name),
constraints.MAX_ACCOUNT_NAME_LENGTH)
(len(self.account_name), length_limit)
return resp
account_partition, accounts = \
self.app.account_ring.get_nodes(self.account_name)
@ -136,11 +135,11 @@ class AccountController(Controller):
@public
def POST(self, req):
"""HTTP POST request handler."""
if len(self.account_name) > constraints.MAX_ACCOUNT_NAME_LENGTH:
length_limit = self.get_name_length_limit()
if len(self.account_name) > length_limit:
resp = HTTPBadRequest(request=req)
resp.body = 'Account name length of %d longer than %d' % \
(len(self.account_name),
constraints.MAX_ACCOUNT_NAME_LENGTH)
(len(self.account_name), length_limit)
return resp
error_response = check_metadata(req, 'account')
if error_response:

View File

@ -46,6 +46,7 @@ from swift.common.utils import Timestamp, config_true_value, \
GreenAsyncPile, quorum_size, parse_content_type, \
document_iters_to_http_response_body
from swift.common.bufferedhttp import http_connect
from swift.common import constraints
from swift.common.exceptions import ChunkReadTimeout, ChunkWriteTimeout, \
ConnectionTimeout, RangeAlreadyComplete
from swift.common.header_key_dict import HeaderKeyDict
@ -1979,3 +1980,17 @@ class Controller(object):
resp.headers = headers
return resp
def get_name_length_limit(self):
if self.account_name.startswith(self.app.auto_create_account_prefix):
multiplier = 2
else:
multiplier = 1
if self.server_type == 'Account':
return constraints.MAX_ACCOUNT_NAME_LENGTH * multiplier
elif self.server_type == 'Container':
return constraints.MAX_CONTAINER_NAME_LENGTH * multiplier
else:
raise ValueError(
"server_type can only be 'account' or 'container'")

View File

@ -18,7 +18,6 @@ from swift import gettext_ as _
from six.moves.urllib.parse import unquote
from swift.common.utils import public, csv_append, Timestamp
from swift.common.constraints import check_metadata
from swift.common import constraints
from swift.common.http import HTTP_ACCEPTED, is_success
from swift.proxy.controllers.base import Controller, delay_denial, \
cors_validation, set_info_cache, clear_info_cache
@ -151,11 +150,11 @@ class ContainerController(Controller):
if not req.environ.get('swift_owner'):
for key in self.app.swift_owner_headers:
req.headers.pop(key, None)
if len(self.container_name) > constraints.MAX_CONTAINER_NAME_LENGTH:
length_limit = self.get_name_length_limit()
if len(self.container_name) > length_limit:
resp = HTTPBadRequest(request=req)
resp.body = 'Container name length of %d longer than %d' % \
(len(self.container_name),
constraints.MAX_CONTAINER_NAME_LENGTH)
(len(self.container_name), length_limit)
return resp
account_partition, accounts, container_count = \
self.account_info(self.account_name, req)

View File

@ -7643,10 +7643,9 @@ class TestContainerController(unittest.TestCase):
def assert_status_map(self, method, statuses, expected,
raise_exc=False, missing_container=False):
with save_globals():
kwargs = {}
kwargs = {'missing_container': missing_container}
if raise_exc:
kwargs['raise_exc'] = raise_exc
kwargs['missing_container'] = missing_container
set_http_connect(*statuses, **kwargs)
self.app.memcache.store = {}
req = Request.blank('/v1/a/c', headers={'Content-Length': '0',
@ -7954,17 +7953,36 @@ class TestContainerController(unittest.TestCase):
missing_container=True)
def test_PUT_max_container_name_length(self):
with save_globals():
limit = constraints.MAX_CONTAINER_NAME_LENGTH
controller = proxy_server.ContainerController(self.app, 'account',
'1' * limit)
self.assert_status_map(controller.PUT,
(200, 201, 201, 201), 201,
missing_container=True)
controller = proxy_server.ContainerController(self.app, 'account',
'2' * (limit + 1))
self.assert_status_map(controller.PUT, (201, 201, 201), 400,
missing_container=True)
limit = constraints.MAX_CONTAINER_NAME_LENGTH
controller = proxy_server.ContainerController(self.app, 'account',
'1' * limit)
self.assert_status_map(controller.PUT, (200, 201, 201, 201), 201,
missing_container=True)
controller = proxy_server.ContainerController(self.app, 'account',
'2' * (limit + 1))
self.assert_status_map(controller.PUT, (), 400,
missing_container=True)
# internal auto-created-accounts get higher limits
limit *= 2
controller = proxy_server.ContainerController(self.app, '.account',
'3' * limit)
self.assert_status_map(controller.PUT, (200, 201, 201, 201), 201,
missing_container=True)
controller = proxy_server.ContainerController(self.app, '.account',
'4' * (limit + 1))
self.assert_status_map(controller.PUT, (), 400,
missing_container=True)
self.app.auto_create_account_prefix = 'acc'
controller = proxy_server.ContainerController(self.app, 'account',
'1' * limit)
self.assert_status_map(controller.PUT, (200, 201, 201, 201), 201,
missing_container=True)
controller = proxy_server.ContainerController(self.app, 'account',
'2' * (limit + 1))
self.assert_status_map(controller.PUT, (), 400,
missing_container=True)
def test_PUT_connect_exceptions(self):
with save_globals():
@ -9093,14 +9111,39 @@ class TestAccountController(unittest.TestCase):
test_status_map((204, 500, 404), 503)
def test_PUT_max_account_name_length(self):
with save_globals():
self.app.allow_account_management = True
limit = constraints.MAX_ACCOUNT_NAME_LENGTH
controller = proxy_server.AccountController(self.app, '1' * limit)
self.assert_status_map(controller.PUT, (201, 201, 201), 201)
controller = proxy_server.AccountController(
self.app, '2' * (limit + 1))
self.assert_status_map(controller.PUT, (201, 201, 201), 400)
self.app.allow_account_management = True
limit = constraints.MAX_ACCOUNT_NAME_LENGTH
controller = proxy_server.AccountController(self.app, '1' * limit)
self.assert_status_map(controller.PUT, (201, 201, 201), 201)
controller = proxy_server.AccountController(
self.app, '2' * (limit + 1))
self.assert_status_map(controller.PUT, (), 400)
# internal auto-created accounts get higher limits
limit *= 2
controller = proxy_server.AccountController(
self.app, '.' + '3' * (limit - 1))
self.assert_status_map(controller.PUT, (201, 201, 201), 201)
controller = proxy_server.AccountController(
self.app, '.' + '4' * limit)
self.assert_status_map(controller.PUT, (), 400)
self.app.auto_create_account_prefix = 'FOO_'
limit /= 2
controller = proxy_server.AccountController(
self.app, '.' + '5' * (limit - 1))
self.assert_status_map(controller.PUT, (201, 201, 201), 201)
controller = proxy_server.AccountController(
self.app, '.' + '6' * limit)
self.assert_status_map(controller.PUT, (), 400)
limit *= 2
controller = proxy_server.AccountController(
self.app, 'FOO_' + '7' * (limit - 4))
self.assert_status_map(controller.PUT, (201, 201, 201), 201)
controller = proxy_server.AccountController(
self.app, 'FOO_' + '8' * (limit - 3))
self.assert_status_map(controller.PUT, (), 400)
def test_PUT_connect_exceptions(self):
with save_globals():