Merge "Last-Modified header support on HEAD/GET container"
This commit is contained in:
commit
9d29ca1c76
@ -17,6 +17,7 @@ import json
|
||||
import os
|
||||
import time
|
||||
import traceback
|
||||
import math
|
||||
from swift import gettext_ as _
|
||||
from xml.etree.cElementTree import Element, SubElement, tostring
|
||||
|
||||
@ -433,7 +434,9 @@ class ContainerController(BaseStorageServer):
|
||||
if value != '' and (key.lower() in self.save_headers or
|
||||
is_sys_or_user_meta('container', key)))
|
||||
headers['Content-Type'] = out_content_type
|
||||
return HTTPNoContent(request=req, headers=headers, charset='utf-8')
|
||||
resp = HTTPNoContent(request=req, headers=headers, charset='utf-8')
|
||||
resp.last_modified = math.ceil(float(headers['X-PUT-Timestamp']))
|
||||
return resp
|
||||
|
||||
def update_data_record(self, record):
|
||||
"""
|
||||
@ -530,6 +533,7 @@ class ContainerController(BaseStorageServer):
|
||||
if not container_list:
|
||||
return HTTPNoContent(request=req, headers=resp_headers)
|
||||
ret.body = '\n'.join(rec[0] for rec in container_list) + '\n'
|
||||
ret.last_modified = math.ceil(float(resp_headers['X-PUT-Timestamp']))
|
||||
return ret
|
||||
|
||||
@public
|
||||
|
@ -625,7 +625,8 @@ class Container(Base):
|
||||
|
||||
if self.conn.response.status == 204:
|
||||
required_fields = [['bytes_used', 'x-container-bytes-used'],
|
||||
['object_count', 'x-container-object-count']]
|
||||
['object_count', 'x-container-object-count'],
|
||||
['last_modified', 'last-modified']]
|
||||
optional_fields = [
|
||||
['versions', 'x-versions-location'],
|
||||
['tempurl_key', 'x-container-meta-temp-url-key'],
|
||||
|
@ -851,6 +851,45 @@ class TestContainer(Base):
|
||||
file_item = cont.file(Utils.create_name())
|
||||
file_item.write_random()
|
||||
|
||||
def testContainerLastModified(self):
|
||||
container = self.env.account.container(Utils.create_name())
|
||||
self.assertTrue(container.create())
|
||||
info = container.info()
|
||||
t0 = info['last_modified']
|
||||
# last modified header is in date format which supports in second
|
||||
# so we need to wait to increment a sec in the header.
|
||||
eventlet.sleep(1)
|
||||
|
||||
# POST container change last modified timestamp
|
||||
self.assertTrue(
|
||||
container.update_metadata({'x-container-meta-japan': 'mitaka'}))
|
||||
info = container.info()
|
||||
t1 = info['last_modified']
|
||||
self.assertNotEqual(t0, t1)
|
||||
eventlet.sleep(1)
|
||||
|
||||
# PUT container (overwrite) also change last modified
|
||||
self.assertTrue(container.create())
|
||||
info = container.info()
|
||||
t2 = info['last_modified']
|
||||
self.assertNotEqual(t1, t2)
|
||||
eventlet.sleep(1)
|
||||
|
||||
# PUT object doesn't change container last modified timestamp
|
||||
obj = container.file(Utils.create_name())
|
||||
self.assertTrue(
|
||||
obj.write("aaaaa", hdrs={'Content-Type': 'text/plain'}))
|
||||
info = container.info()
|
||||
t3 = info['last_modified']
|
||||
self.assertEqual(t2, t3)
|
||||
|
||||
# POST object also doesn't change container last modified timestamp
|
||||
self.assertTrue(
|
||||
obj.sync_metadata({'us': 'austin'}))
|
||||
info = container.info()
|
||||
t4 = info['last_modified']
|
||||
self.assertEqual(t2, t4)
|
||||
|
||||
|
||||
class TestContainerUTF8(Base2, TestContainer):
|
||||
set_up = False
|
||||
|
@ -180,12 +180,7 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(response.headers.get('x-container-write'),
|
||||
'account:user')
|
||||
|
||||
def test_HEAD(self):
|
||||
start = int(time.time())
|
||||
ts = (Timestamp(t).internal for t in itertools.count(start))
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers={
|
||||
'x-timestamp': next(ts)})
|
||||
req.get_response(self.controller)
|
||||
def _test_head(self, start, ts):
|
||||
req = Request.blank('/sda1/p/a/c', method='HEAD')
|
||||
response = req.get_response(self.controller)
|
||||
self.assertEqual(response.status_int, 204)
|
||||
@ -213,6 +208,9 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertTrue(created_at_header >= start)
|
||||
self.assertEqual(response.headers['x-put-timestamp'],
|
||||
Timestamp(start).normal)
|
||||
self.assertEqual(
|
||||
response.last_modified.strftime("%a, %d %b %Y %H:%M:%S GMT"),
|
||||
time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(start)))
|
||||
|
||||
# backend headers
|
||||
self.assertEqual(int(response.headers
|
||||
@ -227,6 +225,22 @@ class TestContainerController(unittest.TestCase):
|
||||
self.assertEqual(response.headers['x-backend-status-changed-at'],
|
||||
Timestamp(start).internal)
|
||||
|
||||
def test_HEAD(self):
|
||||
start = int(time.time())
|
||||
ts = (Timestamp(t).internal for t in itertools.count(start))
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers={
|
||||
'x-timestamp': next(ts)})
|
||||
req.get_response(self.controller)
|
||||
self._test_head(Timestamp(start), ts)
|
||||
|
||||
def test_HEAD_timestamp_with_offset(self):
|
||||
start = int(time.time())
|
||||
ts = (Timestamp(t, offset=1).internal for t in itertools.count(start))
|
||||
req = Request.blank('/sda1/p/a/c', method='PUT', headers={
|
||||
'x-timestamp': next(ts)})
|
||||
req.get_response(self.controller)
|
||||
self._test_head(Timestamp(start, offset=1), ts)
|
||||
|
||||
def test_HEAD_not_found(self):
|
||||
req = Request.blank('/sda1/p/a/c', method='HEAD')
|
||||
resp = req.get_response(self.controller)
|
||||
@ -241,6 +255,8 @@ class TestContainerController(unittest.TestCase):
|
||||
Timestamp(0).internal)
|
||||
self.assertEqual(resp.headers['x-backend-delete-timestamp'],
|
||||
Timestamp(0).internal)
|
||||
self.assertIsNone(resp.last_modified)
|
||||
|
||||
for header in ('x-container-object-count', 'x-container-bytes-used',
|
||||
'x-timestamp', 'x-put-timestamp'):
|
||||
self.assertEqual(resp.headers[header], None)
|
||||
@ -264,6 +280,7 @@ class TestContainerController(unittest.TestCase):
|
||||
req = Request.blank('/sda1/p/a/c', method=method)
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.status_int, 404)
|
||||
self.assertIsNone(resp.last_modified)
|
||||
# backend headers
|
||||
self.assertEqual(int(resp.headers[
|
||||
'X-Backend-Storage-Policy-Index']),
|
||||
@ -2021,6 +2038,9 @@ class TestContainerController(unittest.TestCase):
|
||||
environ={'REQUEST_METHOD': 'GET'})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.content_type, 'application/json')
|
||||
self.assertEqual(
|
||||
resp.last_modified.strftime("%a, %d %b %Y %H:%M:%S GMT"),
|
||||
time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(0)))
|
||||
self.assertEqual(json.loads(resp.body), json_body)
|
||||
self.assertEqual(resp.charset, 'utf-8')
|
||||
|
||||
@ -2082,6 +2102,9 @@ class TestContainerController(unittest.TestCase):
|
||||
environ={'REQUEST_METHOD': 'GET'})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.content_type, 'text/plain')
|
||||
self.assertEqual(
|
||||
resp.last_modified.strftime("%a, %d %b %Y %H:%M:%S GMT"),
|
||||
time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(0)))
|
||||
self.assertEqual(resp.body, plain_body)
|
||||
self.assertEqual(resp.charset, 'utf-8')
|
||||
|
||||
@ -2212,6 +2235,9 @@ class TestContainerController(unittest.TestCase):
|
||||
environ={'REQUEST_METHOD': 'GET'})
|
||||
resp = req.get_response(self.controller)
|
||||
self.assertEqual(resp.content_type, 'application/xml')
|
||||
self.assertEqual(
|
||||
resp.last_modified.strftime("%a, %d %b %Y %H:%M:%S GMT"),
|
||||
time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(0)))
|
||||
self.assertEqual(resp.body, xml_body)
|
||||
self.assertEqual(resp.charset, 'utf-8')
|
||||
|
||||
|
@ -6229,6 +6229,9 @@ class TestContainerController(unittest.TestCase):
|
||||
if expected < 400:
|
||||
self.assertIn('x-works', res.headers)
|
||||
self.assertEqual(res.headers['x-works'], 'yes')
|
||||
if expected < 300:
|
||||
self.assertIn('last-modified', res.headers)
|
||||
self.assertEqual(res.headers['last-modified'], '1')
|
||||
if c_expected:
|
||||
self.assertIn('container/a/c', infocache)
|
||||
self.assertEqual(
|
||||
@ -6254,6 +6257,9 @@ class TestContainerController(unittest.TestCase):
|
||||
if expected < 400:
|
||||
self.assertTrue('x-works' in res.headers)
|
||||
self.assertEqual(res.headers['x-works'], 'yes')
|
||||
if expected < 300:
|
||||
self.assertIn('last-modified', res.headers)
|
||||
self.assertEqual(res.headers['last-modified'], '1')
|
||||
if c_expected:
|
||||
self.assertIn('container/a/c', infocache)
|
||||
self.assertEqual(
|
||||
|
Loading…
Reference in New Issue
Block a user