Handle COPY verb in account quota middleware

Since COPY verb allow to copy an existing object
we must check the size of the source object before
allowing the copy.

Fixes bug: #1201884

Change-Id: Ia37bc716be0c3e5a3174dc4370bb5084f81073ad
This commit is contained in:
Fabien Boucher 2013-10-15 17:46:01 +02:00
parent 2b639f5ecc
commit 6342cb387a
2 changed files with 51 additions and 5 deletions

View File

@ -63,7 +63,7 @@ class AccountQuotaMiddleware(object):
@wsgify
def __call__(self, request):
if request.method not in ("POST", "PUT"):
if request.method not in ("POST", "PUT", "COPY"):
return self.app
try:
@ -98,7 +98,11 @@ class AccountQuotaMiddleware(object):
if obj and request.method == "POST" or not obj:
return self.app
copy_from = request.headers.get('X-Copy-From')
if request.method == 'COPY':
copy_from = container + '/' + obj
else:
copy_from = request.headers.get('X-Copy-From')
content_length = (request.content_length or 0)
if obj and copy_from:

View File

@ -186,9 +186,23 @@ class TestAccountQuota(unittest.TestCase):
res = req.get_response(app)
self.assertEquals(res.status_int, 413)
def test_exceed_bytes_quota_copy_verb(self):
headers = [('x-account-bytes-used', '500'),
('x-account-meta-quota-bytes', '1000'),
('content-length', '1000')]
app = account_quotas.AccountQuotaMiddleware(FakeApp(headers))
cache = FakeCache(None)
req = Request.blank('/v1/a/c2/o2',
environ={'REQUEST_METHOD': 'COPY',
'swift.cache': cache},
headers={'Destination': '/c/o'})
res = req.get_response(app)
self.assertEquals(res.status_int, 413)
def test_not_exceed_bytes_quota_copy_from(self):
headers = [('x-account-bytes-used', '0'),
('x-account-meta-quota-bytes', '1000')]
('x-account-meta-quota-bytes', '1000'),
('content-length', '1000')]
app = account_quotas.AccountQuotaMiddleware(FakeApp(headers))
cache = FakeCache(None)
req = Request.blank('/v1/a/c/o',
@ -198,6 +212,19 @@ class TestAccountQuota(unittest.TestCase):
res = req.get_response(app)
self.assertEquals(res.status_int, 200)
def test_not_exceed_bytes_quota_copy_verb(self):
headers = [('x-account-bytes-used', '0'),
('x-account-meta-quota-bytes', '1000'),
('content-length', '1000')]
app = account_quotas.AccountQuotaMiddleware(FakeApp(headers))
cache = FakeCache(None)
req = Request.blank('/v1/a/c2/o2',
environ={'REQUEST_METHOD': 'COPY',
'swift.cache': cache},
headers={'Destination': '/c/o'})
res = req.get_response(app)
self.assertEquals(res.status_int, 200)
def test_quota_copy_from_no_src(self):
headers = [('x-account-bytes-used', '0'),
('x-account-meta-quota-bytes', '1000')]
@ -223,8 +250,9 @@ class TestAccountQuota(unittest.TestCase):
self.assertEquals(res.status_int, 200)
def test_exceed_bytes_quota_reseller_copy_from(self):
headers = [('x-account-bytes-used', '1000'),
('x-account-meta-quota-bytes', '0')]
headers = [('x-account-bytes-used', '500'),
('x-account-meta-quota-bytes', '1000'),
('content-length', '1000')]
app = account_quotas.AccountQuotaMiddleware(FakeApp(headers))
cache = FakeCache(None)
req = Request.blank('/v1/a/c/o',
@ -235,6 +263,20 @@ class TestAccountQuota(unittest.TestCase):
res = req.get_response(app)
self.assertEquals(res.status_int, 200)
def test_exceed_bytes_quota_reseller_copy_verb(self):
headers = [('x-account-bytes-used', '500'),
('x-account-meta-quota-bytes', '1000'),
('content-length', '1000')]
app = account_quotas.AccountQuotaMiddleware(FakeApp(headers))
cache = FakeCache(None)
req = Request.blank('/v1/a/c2/o2',
environ={'REQUEST_METHOD': 'COPY',
'swift.cache': cache,
'reseller_request': True},
headers={'Destination': 'c/o'})
res = req.get_response(app)
self.assertEquals(res.status_int, 200)
def test_bad_application_quota(self):
headers = []
app = account_quotas.AccountQuotaMiddleware(FakeBadApp(headers))