From 1e79f828ad10918bd76ae8df6fe4c4dbf7bbf3c5 Mon Sep 17 00:00:00 2001 From: Kota Tsuyuzaki Date: Thu, 14 Sep 2017 20:57:46 +0900 Subject: [PATCH] Remove all post_as_copy related code and configes It was deprecated and we discussed on this topic in Denver PTG for Queen cycle. Main motivation for this work is that deprecated post_as_copy option and its gate blocks future symlink work. Change-Id: I411893db1565864ed5beb6ae75c38b982a574476 --- doc/manpages/proxy-server.conf.5 | 2 - doc/source/deployment_guide.rst | 1 - doc/source/development_guidelines.rst | 4 - etc/proxy-server.conf-sample | 2 - swift/common/middleware/copy.py | 68 +---- swift/common/middleware/versioned_writes.py | 3 +- test/functional/__init__.py | 9 - test/probe/common.py | 5 +- test/probe/test_container_sync.py | 14 +- test/probe/test_object_async_update.py | 6 +- .../probe/test_object_metadata_replication.py | 2 +- .../middleware/crypto/test_encryption.py | 9 - test/unit/common/middleware/test_copy.py | 250 +----------------- .../middleware/test_subrequest_logging.py | 47 +--- .../middleware/test_versioned_writes.py | 17 -- test/unit/proxy/test_server.py | 26 +- test/unit/proxy/test_sysmeta.py | 10 - 17 files changed, 30 insertions(+), 445 deletions(-) diff --git a/doc/manpages/proxy-server.conf.5 b/doc/manpages/proxy-server.conf.5 index 8081b3491d..f3d0e3060f 100644 --- a/doc/manpages/proxy-server.conf.5 +++ b/doc/manpages/proxy-server.conf.5 @@ -996,8 +996,6 @@ Error count to consider a node error limited. The default is 10. Whether account PUTs and DELETEs are even callable. If set to 'true' any authorized user may create and delete accounts; if 'false' no one, even authorized, can. The default is false. -.IP \fBobject_post_as_copy\fR -Deprecated. The default is False. .IP \fBaccount_autocreate\fR If set to 'true' authorized accounts that do not yet exist within the Swift cluster will be automatically created. The default is set to false. diff --git a/doc/source/deployment_guide.rst b/doc/source/deployment_guide.rst index 554302f30f..06c6f9b58f 100644 --- a/doc/source/deployment_guide.rst +++ b/doc/source/deployment_guide.rst @@ -1884,7 +1884,6 @@ error_suppression_limit 10 Error count to consider node error limited allow_account_management false Whether account PUTs and DELETEs are even callable -object_post_as_copy false Deprecated. account_autocreate false If set to 'true' authorized accounts that do not yet exist within the Swift cluster will diff --git a/doc/source/development_guidelines.rst b/doc/source/development_guidelines.rst index 601db80a0a..a8d2295a0b 100644 --- a/doc/source/development_guidelines.rst +++ b/doc/source/development_guidelines.rst @@ -127,9 +127,6 @@ set using environment variables: environment variable ``SWIFT_TEST_IN_PROCESS_CONF_LOADER`` to ``ec``. -- the deprecated proxy-server ``object_post_as_copy`` option may be set using - the environment variable ``SWIFT_TEST_IN_PROCESS_OBJECT_POST_AS_COPY``. - - logging to stdout may be enabled by setting ``SWIFT_TEST_DEBUG_LOGS``. For example, this command would run the in-process mode functional tests with @@ -147,7 +144,6 @@ The ``tox.ini`` file also specifies test environments for running other in-process functional test configurations, e.g.:: tox -e func-ec - tox -e func-post-as-copy To debug the functional tests, use the 'in-process test' mode and pass the ``--pdb`` flag to ``tox``:: diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index c07c48ff35..80469993c1 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -860,8 +860,6 @@ use = egg:swift#copy # requests are transformed into COPY requests where source and destination are # the same. All client-visible behavior (save response time) should be # identical. -# This option is deprecated and will be ignored in a future release. -# object_post_as_copy = false # Note: To enable encryption, add the following 2 dependent pieces of crypto # middleware to the proxy-server pipeline. They should be to the right of all diff --git a/swift/common/middleware/copy.py b/swift/common/middleware/copy.py index d3718573bb..49e85c2b1a 100644 --- a/swift/common/middleware/copy.py +++ b/swift/common/middleware/copy.py @@ -112,20 +112,6 @@ If a request is sent without the query parameter, an attempt will be made to copy the whole object but will fail if the object size is greater than 5GB. -------------------- -Object Post as Copy -------------------- -Historically, this has been a feature (and a configurable option with default -set to True) in proxy server configuration. This has been moved to server side -copy middleware and the default changed to False. - -When ``object_post_as_copy`` is set to ``true``, an incoming POST request is -morphed into a COPY request where source and destination objects are same. - -This feature was necessary because of a previous behavior where POSTS would -update the metadata on the object but not on the container. As a result, -features like container sync would not work correctly. This is no longer the -case and this option is now deprecated. It will be removed in a future release. """ import os @@ -137,8 +123,7 @@ from swift.common.utils import get_logger, \ config_true_value, FileLikeIter, read_conf_dir, close_if_possible from swift.common.swob import Request, HTTPPreconditionFailed, \ HTTPRequestEntityTooLarge, HTTPBadRequest, HTTPException -from swift.common.http import HTTP_MULTIPLE_CHOICES, HTTP_CREATED, \ - is_success, HTTP_OK +from swift.common.http import HTTP_MULTIPLE_CHOICES, is_success, HTTP_OK from swift.common.constraints import check_account_format, MAX_FILE_SIZE from swift.common.request_helpers import copy_header_subset, remove_items, \ is_sys_meta, is_sys_or_user_meta, is_object_transient_sysmeta @@ -238,13 +223,7 @@ class ServerSideCopyWebContext(WSGIContext): return app_resp def _adjust_put_response(self, req, additional_resp_headers): - if 'swift.post_as_copy' in req.environ: - # Older editions returned 202 Accepted on object POSTs, so we'll - # convert any 201 Created responses to that for compatibility with - # picky clients. - if self._get_status_int() == HTTP_CREATED: - self._response_status = '202 Accepted' - elif is_success(self._get_status_int()): + if is_success(self._get_status_int()): for header, value in additional_resp_headers.items(): self._response_headers.append((header, value)) @@ -269,17 +248,12 @@ class ServerSideCopyMiddleware(object): def __init__(self, app, conf): self.app = app self.logger = get_logger(conf, log_route="copy") - # Read the old object_post_as_copy option from Proxy app just in case - # someone has set it to false (non default). This wouldn't cause - # problems during upgrade. self._load_object_post_as_copy_conf(conf) self.object_post_as_copy = \ config_true_value(conf.get('object_post_as_copy', 'false')) if self.object_post_as_copy: - msg = ('object_post_as_copy=true is deprecated; remove all ' - 'references to it from %s to disable this warning. This ' - 'option will be ignored in a future release' % conf.get( - '__file__', 'proxy-server.conf')) + msg = ('object_post_as_copy=true is deprecated; This ' + 'option is now ignored') self.logger.warning(msg) def _load_object_post_as_copy_conf(self, conf): @@ -330,9 +304,6 @@ class ServerSideCopyMiddleware(object): elif req.method == 'COPY': req.environ['swift.orig_req_method'] = req.method return self.handle_COPY(req, start_response) - elif req.method == 'POST' and self.object_post_as_copy: - req.environ['swift.orig_req_method'] = req.method - return self.handle_object_post_as_copy(req, start_response) elif req.method == 'OPTIONS': # Does not interfere with OPTIONS response from # (account,container) servers and /info response. @@ -343,21 +314,6 @@ class ServerSideCopyMiddleware(object): return self.app(env, start_response) - def handle_object_post_as_copy(self, req, start_response): - req.method = 'PUT' - req.path_info = '/v1/%s/%s/%s' % ( - self.account_name, self.container_name, self.object_name) - req.headers['Content-Length'] = 0 - req.headers.pop('Range', None) - req.headers['X-Copy-From'] = quote('/%s/%s' % (self.container_name, - self.object_name)) - req.environ['swift.post_as_copy'] = True - params = req.params - # for post-as-copy always copy the manifest itself if source is *LO - params['multipart-manifest'] = 'get' - req.params = params - return self.handle_PUT(req, start_response) - def handle_COPY(self, req, start_response): if not req.headers.get('Destination'): return HTTPPreconditionFailed(request=req, @@ -394,11 +350,6 @@ class ServerSideCopyMiddleware(object): source_req.headers.pop('X-Backend-Storage-Policy-Index', None) source_req.path_info = quote(source_path) source_req.headers['X-Newest'] = 'true' - if 'swift.post_as_copy' in req.environ: - # We're COPYing one object over itself because of a POST; rely on - # the PUT for write authorization, don't require read authorization - source_req.environ['swift.authorize'] = lambda req: None - source_req.environ['swift.authorize_override'] = True # in case we are copying an SLO manifest, set format=raw parameter params = source_req.params @@ -470,11 +421,7 @@ class ServerSideCopyMiddleware(object): def is_object_sysmeta(k): return is_sys_meta('object', k) - if 'swift.post_as_copy' in sink_req.environ: - # Post-as-copy: ignore new sysmeta, copy existing sysmeta - remove_items(sink_req.headers, is_object_sysmeta) - copy_header_subset(source_resp, sink_req, is_object_sysmeta) - elif config_true_value(req.headers.get('x-fresh-metadata', 'false')): + if config_true_value(req.headers.get('x-fresh-metadata', 'false')): # x-fresh-metadata only applies to copy, not post-as-copy: ignore # existing user metadata, update existing sysmeta with new copy_header_subset(source_resp, sink_req, is_object_sysmeta) @@ -497,9 +444,8 @@ class ServerSideCopyMiddleware(object): params['multipart-manifest'] = 'put' if 'X-Object-Manifest' in source_resp.headers: del params['multipart-manifest'] - if 'swift.post_as_copy' not in sink_req.environ: - sink_req.headers['X-Object-Manifest'] = \ - source_resp.headers['X-Object-Manifest'] + sink_req.headers['X-Object-Manifest'] = \ + source_resp.headers['X-Object-Manifest'] sink_req.params = params # Set swift.source, data source, content length and etag diff --git a/swift/common/middleware/versioned_writes.py b/swift/common/middleware/versioned_writes.py index a21c95620c..0bac721bba 100644 --- a/swift/common/middleware/versioned_writes.py +++ b/swift/common/middleware/versioned_writes.py @@ -826,8 +826,7 @@ class VersionedWritesMiddleware(object): allow_versioned_writes) except HTTPException as error_response: return error_response(env, start_response) - elif (obj and req.method in ('PUT', 'DELETE') and - not req.environ.get('swift.post_as_copy')): + elif (obj and req.method in ('PUT', 'DELETE')): try: return self.object_request( req, api_version, account, container, obj, diff --git a/test/functional/__init__.py b/test/functional/__init__.py index 3e3c4486d7..25f1410436 100644 --- a/test/functional/__init__.py +++ b/test/functional/__init__.py @@ -505,15 +505,6 @@ def in_process_setup(the_object_server=object_server): 'password6': 'testing6' }) - # If an env var explicitly specifies the proxy-server object_post_as_copy - # option then use its value, otherwise leave default config unchanged. - object_post_as_copy = os.environ.get( - 'SWIFT_TEST_IN_PROCESS_OBJECT_POST_AS_COPY') - if object_post_as_copy is not None: - object_post_as_copy = config_true_value(object_post_as_copy) - config['object_post_as_copy'] = str(object_post_as_copy) - _debug('Setting object_post_as_copy to %r' % object_post_as_copy) - acc1lis = listen_zero() acc2lis = listen_zero() con1lis = listen_zero() diff --git a/test/probe/common.py b/test/probe/common.py index 0d00481ffe..0c1507536a 100644 --- a/test/probe/common.py +++ b/test/probe/common.py @@ -448,7 +448,7 @@ class ProbeTest(unittest.TestCase): else: os.system('sudo mount %s' % device) - def make_internal_client(self, object_post_as_copy=True): + def make_internal_client(self): tempdir = mkdtemp() try: conf_path = os.path.join(tempdir, 'internal_client.conf') @@ -464,14 +464,13 @@ class ProbeTest(unittest.TestCase): [filter:copy] use = egg:swift#copy - object_post_as_copy = %s [filter:cache] use = egg:swift#memcache [filter:catch_errors] use = egg:swift#catch_errors - """ % object_post_as_copy + """ with open(conf_path, 'w') as f: f.write(dedent(conf_body)) return internal_client.InternalClient(conf_path, 'test', 1) diff --git a/test/probe/test_container_sync.py b/test/probe/test_container_sync.py index a944dc7fee..7c3de1782b 100644 --- a/test/probe/test_container_sync.py +++ b/test/probe/test_container_sync.py @@ -93,7 +93,7 @@ class TestContainerSync(ReplProbeTest): return source['name'], dest['name'] - def _test_sync(self, object_post_as_copy): + def test_sync(self): source_container, dest_container = self._setup_synced_containers() # upload to source @@ -111,12 +111,10 @@ class TestContainerSync(ReplProbeTest): self.assertIn('x-object-meta-test', resp_headers) self.assertEqual('put_value', resp_headers['x-object-meta-test']) - # update metadata with a POST, using an internal client so we can - # vary the object_post_as_copy setting - first use post-as-copy + # update metadata with a POST post_headers = {'Content-Type': 'image/jpeg', 'X-Object-Meta-Test': 'post_value'} - int_client = self.make_internal_client( - object_post_as_copy=object_post_as_copy) + int_client = self.make_internal_client() int_client.set_object_metadata(self.account, source_container, object_name, post_headers) # sanity checks... @@ -154,12 +152,6 @@ class TestContainerSync(ReplProbeTest): self.url, self.token, dest_container, object_name) self.assertEqual(404, cm.exception.http_status) # sanity check - def test_sync_with_post_as_copy(self): - self._test_sync(True) - - def test_sync_with_fast_post(self): - self._test_sync(False) - def test_sync_slo_manifest(self): # Verify that SLO manifests are sync'd even if their segments can not # be found in the destination account at time of sync'ing. diff --git a/test/probe/test_object_async_update.py b/test/probe/test_object_async_update.py index 167f1b637e..33b7504a69 100644 --- a/test/probe/test_object_async_update.py +++ b/test/probe/test_object_async_update.py @@ -237,8 +237,7 @@ class TestUpdateOverridesEC(ECProbeTest): self.assertFalse(direct_client.direct_get_container( cnodes[0], cpart, self.account, 'c1')[1]) - # use internal client for POST so we can force fast-post mode - int_client = self.make_internal_client(object_post_as_copy=False) + int_client = self.make_internal_client() int_client.set_object_metadata( self.account, 'c1', 'o1', {'X-Object-Meta-Fruit': 'Tomato'}) self.assertEqual( @@ -296,8 +295,7 @@ class TestUpdateOverridesEC(ECProbeTest): content_type='test/ctype') meta = client.head_object(self.url, self.token, 'c1', 'o1') - # use internal client for POST so we can force fast-post mode - int_client = self.make_internal_client(object_post_as_copy=False) + int_client = self.make_internal_client() int_client.set_object_metadata( self.account, 'c1', 'o1', {'X-Object-Meta-Fruit': 'Tomato'}) self.assertEqual( diff --git a/test/probe/test_object_metadata_replication.py b/test/probe/test_object_metadata_replication.py index 042d9439fb..ca2e8dde1d 100644 --- a/test/probe/test_object_metadata_replication.py +++ b/test/probe/test_object_metadata_replication.py @@ -47,7 +47,7 @@ class Test(ReplProbeTest): policy=self.policy) self.container_brain = BrainSplitter(self.url, self.token, self.container_name) - self.int_client = self.make_internal_client(object_post_as_copy=False) + self.int_client = self.make_internal_client() def _get_object_info(self, account, container, obj, number): obj_conf = self.configs['object-server'] diff --git a/test/unit/common/middleware/crypto/test_encryption.py b/test/unit/common/middleware/crypto/test_encryption.py index e984a5f0ae..442ef40049 100644 --- a/test/unit/common/middleware/crypto/test_encryption.py +++ b/test/unit/common/middleware/crypto/test_encryption.py @@ -618,14 +618,5 @@ class TestCryptoPipelineChanges(unittest.TestCase): self._check_listing(self.crypto_app) -class TestCryptoPipelineChangesFastPost(TestCryptoPipelineChanges): - @classmethod - def setUpClass(cls): - # set proxy config to use fast post - extra_conf = {'object_post_as_copy': 'False'} - cls._test_context = setup_servers(extra_conf=extra_conf) - cls.proxy_app = cls._test_context["test_servers"][0] - - if __name__ == '__main__': unittest.main() diff --git a/test/unit/common/middleware/test_copy.py b/test/unit/common/middleware/test_copy.py index bbf74bbc1b..a7b44e4a0e 100644 --- a/test/unit/common/middleware/test_copy.py +++ b/test/unit/common/middleware/test_copy.py @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import time import mock import shutil import tempfile @@ -93,9 +92,7 @@ class TestCopyConstraints(unittest.TestCase): class TestServerSideCopyMiddleware(unittest.TestCase): def setUp(self): self.app = FakeSwift() - self.ssc = copy.filter_factory({ - 'object_post_as_copy': 'yes', - })(self.app) + self.ssc = copy.filter_factory({})(self.app) self.ssc.logger = self.app.logger def tearDown(self): @@ -166,92 +163,6 @@ class TestServerSideCopyMiddleware(unittest.TestCase): self.assertRequestEqual(req, self.authorized[0]) self.assertNotIn('swift.orig_req_method', req.environ) - def test_POST_as_COPY_simple(self): - self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, {}, 'passed') - self.app.register('PUT', '/v1/a/c/o', swob.HTTPAccepted, {}) - req = Request.blank('/v1/a/c/o', method='POST') - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - # For basic test cases, assert orig_req_method behavior - self.assertEqual(req.environ['swift.orig_req_method'], 'POST') - - def test_POST_as_COPY_201_return_202(self): - self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, {}, 'passed') - self.app.register('PUT', '/v1/a/c/o', swob.HTTPCreated, {}) - req = Request.blank('/v1/a/c/o', method='POST') - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - - def test_POST_delete_at(self): - self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, {}, 'passed') - self.app.register('PUT', '/v1/a/c/o', swob.HTTPAccepted, {}) - t = str(int(time.time() + 100)) - req = Request.blank('/v1/a/c/o', method='POST', - headers={'Content-Type': 'foo/bar', - 'X-Delete-At': t}) - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - - calls = self.app.calls_with_headers - method, path, req_headers = calls[1] - self.assertEqual('PUT', method) - self.assertTrue('X-Delete-At' in req_headers) - self.assertEqual(req_headers['X-Delete-At'], str(t)) - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - - def test_POST_as_COPY_static_large_object(self): - self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, - {'X-Static-Large-Object': True}, 'passed') - self.app.register('PUT', '/v1/a/c/o', swob.HTTPAccepted, {}) - req = Request.blank('/v1/a/c/o', method='POST', - headers={}) - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - - calls = self.app.calls_with_headers - method, path, req_headers = calls[1] - self.assertEqual('PUT', method) - self.assertNotIn('X-Static-Large-Object', req_headers) - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - - def test_POST_as_COPY_dynamic_large_object_manifest(self): - self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, - {'X-Object-Manifest': 'orig_manifest'}, 'passed') - self.app.register('PUT', '/v1/a/c/o', swob.HTTPCreated, {}) - req = Request.blank('/v1/a/c/o', method='POST', - headers={'X-Object-Manifest': 'new_manifest'}) - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - - calls = self.app.calls_with_headers - method, path, req_headers = calls[1] - self.assertEqual('PUT', method) - self.assertEqual('new_manifest', req_headers['x-object-manifest']) - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - - def test_POST_as_COPY_dynamic_large_object_no_manifest(self): - self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, - {'X-Object-Manifest': 'orig_manifest'}, 'passed') - self.app.register('PUT', '/v1/a/c/o', swob.HTTPCreated, {}) - req = Request.blank('/v1/a/c/o', method='POST', - headers={}) - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - - calls = self.app.calls_with_headers - method, path, req_headers = calls[1] - self.assertEqual('PUT', method) - self.assertNotIn('X-Object-Manifest', req_headers) - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - def test_basic_put_with_x_copy_from(self): self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, {}, 'passed') self.app.register('PUT', '/v1/a/c/o2', swob.HTTPCreated, {}) @@ -1345,100 +1256,6 @@ class TestServerSideCopyMiddleware(unittest.TestCase): req_headers.get('X-Object-Transient-Sysmeta-Test')) self.assertEqual('Not Bar', req_headers.get('X-Foo')) - def _test_POST_source_headers(self, extra_post_headers): - # helper method to perform a POST with metadata headers that should - # always be sent to the destination - post_headers = {'X-Object-Meta-Test2': 'added', - 'X-Object-Sysmeta-Test2': 'added', - 'X-Object-Transient-Sysmeta-Test2': 'added'} - post_headers.update(extra_post_headers) - get_resp_headers = { - 'X-Timestamp': '1234567890.12345', - 'X-Backend-Timestamp': '1234567890.12345', - 'Content-Type': 'text/original', - 'Content-Encoding': 'gzip', - 'Content-Disposition': 'attachment; filename=myfile', - 'X-Object-Meta-Test': 'original', - 'X-Object-Sysmeta-Test': 'original', - 'X-Object-Transient-Sysmeta-Test': 'original', - 'X-Foo': 'Bar'} - self.app.register( - 'GET', '/v1/a/c/o', swob.HTTPOk, headers=get_resp_headers) - self.app.register('PUT', '/v1/a/c/o', swob.HTTPCreated, {}) - req = Request.blank('/v1/a/c/o', method='POST', headers=post_headers) - status, headers, body = self.call_ssc(req) - self.assertEqual(status, '202 Accepted') - calls = self.app.calls_with_headers - self.assertEqual(2, len(calls)) - method, path, req_headers = calls[1] - self.assertEqual('PUT', method) - # these headers should always be applied to the destination - self.assertEqual('added', req_headers.get('X-Object-Meta-Test2')) - self.assertEqual('added', - req_headers.get('X-Object-Transient-Sysmeta-Test2')) - # POSTed sysmeta should never be applied to the destination - self.assertNotIn('X-Object-Sysmeta-Test2', req_headers) - # existing sysmeta should always be preserved - self.assertEqual('original', - req_headers.get('X-Object-Sysmeta-Test')) - return req_headers - - def test_POST_no_updates(self): - post_headers = {} - req_headers = self._test_POST_source_headers(post_headers) - self.assertEqual('text/original', req_headers.get('Content-Type')) - self.assertNotIn('X-Object-Meta-Test', req_headers) - self.assertNotIn('X-Object-Transient-Sysmeta-Test', req_headers) - self.assertNotIn('X-Timestamp', req_headers) - self.assertNotIn('X-Backend-Timestamp', req_headers) - self.assertNotIn('Content-Encoding', req_headers) - self.assertNotIn('Content-Disposition', req_headers) - self.assertNotIn('X-Foo', req_headers) - - def test_POST_with_updates(self): - post_headers = { - 'Content-Type': 'text/not_original', - 'Content-Encoding': 'not_gzip', - 'Content-Disposition': 'attachment; filename=notmyfile', - 'X-Object-Meta-Test': 'not_original', - 'X-Object-Sysmeta-Test': 'not_original', - 'X-Object-Transient-Sysmeta-Test': 'not_original', - 'X-Foo': 'Not Bar', - } - req_headers = self._test_POST_source_headers(post_headers) - self.assertEqual('text/not_original', req_headers.get('Content-Type')) - self.assertEqual('not_gzip', req_headers.get('Content-Encoding')) - self.assertEqual('attachment; filename=notmyfile', - req_headers.get('Content-Disposition')) - self.assertEqual('not_original', req_headers.get('X-Object-Meta-Test')) - self.assertEqual('not_original', - req_headers.get('X-Object-Transient-Sysmeta-Test')) - self.assertEqual('Not Bar', req_headers.get('X-Foo')) - - def test_POST_x_fresh_metadata_with_updates(self): - # post-as-copy trumps x-fresh-metadata i.e. existing user metadata - # should not be copied, sysmeta is copied *and not updated with new* - post_headers = { - 'X-Fresh-Metadata': 'true', - 'Content-Type': 'text/not_original', - 'Content-Encoding': 'not_gzip', - 'Content-Disposition': 'attachment; filename=notmyfile', - 'X-Object-Meta-Test': 'not_original', - 'X-Object-Sysmeta-Test': 'not_original', - 'X-Object-Transient-Sysmeta-Test': 'not_original', - 'X-Foo': 'Not Bar', - } - req_headers = self._test_POST_source_headers(post_headers) - self.assertEqual('text/not_original', req_headers.get('Content-Type')) - self.assertEqual('not_gzip', req_headers.get('Content-Encoding')) - self.assertEqual('attachment; filename=notmyfile', - req_headers.get('Content-Disposition')) - self.assertEqual('not_original', req_headers.get('X-Object-Meta-Test')) - self.assertEqual('not_original', - req_headers.get('X-Object-Transient-Sysmeta-Test')) - self.assertEqual('Not Bar', req_headers.get('X-Foo')) - self.assertIn('X-Fresh-Metadata', req_headers) - def test_COPY_with_single_range(self): # verify that source etag is not copied when copying a range self.app.register('GET', '/v1/a/c/o', swob.HTTPOk, @@ -1472,67 +1289,6 @@ class TestServerSideCopyConfiguration(unittest.TestCase): def tearDown(self): shutil.rmtree(self.tmpdir) - def test_post_as_copy_defaults_to_false(self): - ssc = copy.filter_factory({})("no app here") - self.assertEqual(ssc.object_post_as_copy, False) - - def test_reading_proxy_conf_when_no_middleware_conf_present(self): - proxy_conf = dedent(""" - [DEFAULT] - bind_ip = 10.4.5.6 - - [pipeline:main] - pipeline = catch_errors copy ye-olde-proxy-server - - [filter:copy] - use = egg:swift#copy - - [app:ye-olde-proxy-server] - use = egg:swift#proxy - object_post_as_copy = no - """) - - conffile = tempfile.NamedTemporaryFile() - conffile.write(proxy_conf) - conffile.flush() - - ssc = copy.filter_factory({ - '__file__': conffile.name - })("no app here") - - self.assertEqual(ssc.object_post_as_copy, False) - - def test_middleware_conf_precedence(self): - proxy_conf = dedent(""" - [DEFAULT] - bind_ip = 10.4.5.6 - - [pipeline:main] - pipeline = catch_errors copy ye-olde-proxy-server - - [filter:copy] - use = egg:swift#copy - object_post_as_copy = no - - [app:ye-olde-proxy-server] - use = egg:swift#proxy - object_post_as_copy = yes - """) - - conffile = tempfile.NamedTemporaryFile() - conffile.write(proxy_conf) - conffile.flush() - - with mock.patch('swift.common.middleware.copy.get_logger', - return_value=debug_logger('copy')): - ssc = copy.filter_factory({ - 'object_post_as_copy': 'no', - '__file__': conffile.name - })("no app here") - - self.assertEqual(ssc.object_post_as_copy, False) - self.assertFalse(ssc.logger.get_lines_for_level('warning')) - def _test_post_as_copy_emits_warning(self, conf): with mock.patch('swift.common.middleware.copy.get_logger', return_value=debug_logger('copy')): @@ -1585,9 +1341,7 @@ class TestServerSideCopyMiddlewareWithEC(unittest.TestCase): self.app = PatchedObjControllerApp( None, FakeMemcache(), account_ring=FakeRing(), container_ring=FakeRing(), logger=self.logger) - self.ssc = copy.filter_factory({ - 'object_post_as_copy': 'yes', - })(self.app) + self.ssc = copy.filter_factory({})(self.app) self.ssc.logger = self.app.logger self.policy = POLICIES.default self.app.container_info = dict(self.container_info) diff --git a/test/unit/common/middleware/test_subrequest_logging.py b/test/unit/common/middleware/test_subrequest_logging.py index 8cd002c23c..3e51efd2b8 100644 --- a/test/unit/common/middleware/test_subrequest_logging.py +++ b/test/unit/common/middleware/test_subrequest_logging.py @@ -117,23 +117,14 @@ class TestSubRequestLogging(unittest.TestCase): self._test_subrequest_logged('PUT') self._test_subrequest_logged('DELETE') - def _test_subrequest_logged_POST(self, subrequest_type, - post_as_copy=False): - # Test that subrequests made downstream from Copy POST will be logged - # with the request type of the subrequest as opposed to the GET/PUT. - - app = FakeApp({'subrequest_type': subrequest_type, - 'object_post_as_copy': post_as_copy}) + def _test_subrequest_logged_POST(self, subrequest_type): + app = FakeApp({'subrequest_type': subrequest_type}) hdrs = {'content-type': 'text/plain'} req = Request.blank(self.path, method='POST', headers=hdrs) app.register('POST', self.path, HTTPOk, headers=hdrs) expect_lines = 2 - if post_as_copy: - app.register('PUT', self.path, HTTPOk, headers=hdrs) - app.register('GET', '/v1/a/c/o', HTTPOk, headers=hdrs) - expect_lines = 4 req.get_response(app) info_log_lines = app.fake_logger.get_lines_for_level('info') @@ -142,33 +133,17 @@ class TestSubRequestLogging(unittest.TestCase): subreq_put_post = '%s %s' % (subrequest_type, SUB_PUT_POST_PATH) origpost = 'POST %s' % self.path - copyget = 'GET %s' % self.path - if post_as_copy: - # post_as_copy expect GET subreq, copy GET, PUT subreq, orig POST - subreq_get = '%s %s' % (subrequest_type, SUB_GET_PATH) - self.assertTrue(subreq_get in info_log_lines[0]) - self.assertTrue(copyget in info_log_lines[1]) - self.assertTrue(subreq_put_post in info_log_lines[2]) - self.assertTrue(origpost in info_log_lines[3]) - else: - # fast post expect POST subreq, original POST - self.assertTrue(subreq_put_post in info_log_lines[0]) - self.assertTrue(origpost in info_log_lines[1]) + # fast post expect POST subreq, original POST + self.assertTrue(subreq_put_post in info_log_lines[0]) + self.assertTrue(origpost in info_log_lines[1]) - def test_subrequest_logged_post_as_copy_with_POST_fast_post(self): - self._test_subrequest_logged_POST('HEAD', post_as_copy=False) - self._test_subrequest_logged_POST('GET', post_as_copy=False) - self._test_subrequest_logged_POST('POST', post_as_copy=False) - self._test_subrequest_logged_POST('PUT', post_as_copy=False) - self._test_subrequest_logged_POST('DELETE', post_as_copy=False) - - def test_subrequest_logged_post_as_copy_with_POST(self): - self._test_subrequest_logged_POST('HEAD', post_as_copy=True) - self._test_subrequest_logged_POST('GET', post_as_copy=True) - self._test_subrequest_logged_POST('POST', post_as_copy=True) - self._test_subrequest_logged_POST('PUT', post_as_copy=True) - self._test_subrequest_logged_POST('DELETE', post_as_copy=True) + def test_subrequest_logged_with_POST(self): + self._test_subrequest_logged_POST('HEAD') + self._test_subrequest_logged_POST('GET') + self._test_subrequest_logged_POST('POST') + self._test_subrequest_logged_POST('PUT') + self._test_subrequest_logged_POST('DELETE') if __name__ == '__main__': diff --git a/test/unit/common/middleware/test_versioned_writes.py b/test/unit/common/middleware/test_versioned_writes.py index 007859b430..a160247881 100644 --- a/test/unit/common/middleware/test_versioned_writes.py +++ b/test/unit/common/middleware/test_versioned_writes.py @@ -330,23 +330,6 @@ class VersionedWritesTestCase(VersionedWritesBaseTestCase): self.assertEqual(len(self.authorized), 1) self.assertRequestEqual(req, self.authorized[0]) - def test_put_object_post_as_copy(self): - # PUTs due to a post-as-copy should NOT cause a versioning op - self.app.register( - 'PUT', '/v1/a/c/o', swob.HTTPCreated, {}, 'passed') - - cache = FakeCache({'sysmeta': {'versions-location': 'ver_cont'}}) - req = Request.blank( - '/v1/a/c/o', - environ={'REQUEST_METHOD': 'PUT', 'swift.cache': cache, - 'CONTENT_LENGTH': '100', - 'swift.post_as_copy': True}) - status, headers, body = self.call_vw(req) - self.assertEqual(status, '201 Created') - self.assertEqual(len(self.authorized), 1) - self.assertRequestEqual(req, self.authorized[0]) - self.assertEqual(1, self.app.call_count) - def test_put_first_object_success(self): self.app.register( 'PUT', '/v1/a/c/o', swob.HTTPOk, {}, 'passed') diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index 2766ebea22..c4886e52f0 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -3192,8 +3192,6 @@ class TestReplicatedObjectController( def test_POST(self): with save_globals(): - self.app.object_post_as_copy = False - def test_status_map(statuses, expected): set_http_connect(*statuses) self.app.memcache.store = {} @@ -3218,7 +3216,6 @@ class TestReplicatedObjectController( def test_POST_backend_headers(self): # reset the router post patch_policies self.app.obj_controller_router = proxy_server.ObjectControllerRouter() - self.app.object_post_as_copy = False self.app.sort_nodes = lambda nodes, *args, **kwargs: nodes backend_requests = [] @@ -3436,7 +3433,6 @@ class TestReplicatedObjectController( def test_POST_meta_val_len(self): with save_globals(): limit = constraints.MAX_META_VALUE_LENGTH - self.app.object_post_as_copy = False ReplicatedObjectController( self.app, 'account', 'container', 'object') set_http_connect(200, 200, 202, 202, 202) @@ -3462,7 +3458,6 @@ class TestReplicatedObjectController( return with save_globals(): limit = constraints.MAX_META_VALUE_LENGTH - self.app.object_post_as_copy = False controller = ReplicatedObjectController( self.app, 'account', 'container', 'object') set_http_connect(200, 200, 202, 202, 202) @@ -3478,7 +3473,6 @@ class TestReplicatedObjectController( def test_POST_meta_key_len(self): with save_globals(): limit = constraints.MAX_META_NAME_LENGTH - self.app.object_post_as_copy = False set_http_connect(200, 200, 202, 202, 202) # acct cont obj obj obj req = Request.blank( @@ -4224,7 +4218,6 @@ class TestReplicatedObjectController( def test_PUT_POST_requires_container_exist(self): with save_globals(): - self.app.object_post_as_copy = False self.app.memcache = FakeMemcacheReturnsNone() controller = ReplicatedObjectController( self.app, 'account', 'container', 'object') @@ -4837,7 +4830,6 @@ class TestReplicatedObjectController( called[0] = True return HTTPUnauthorized(request=req) with save_globals(): - self.app.object_post_as_copy = False set_http_connect(200, 200, 201, 201, 201) controller = ReplicatedObjectController( self.app, 'account', 'container', 'object') @@ -4868,7 +4860,6 @@ class TestReplicatedObjectController( def test_POST_converts_delete_after_to_delete_at(self): with save_globals(): - self.app.object_post_as_copy = False controller = ReplicatedObjectController( self.app, 'account', 'container', 'object') set_http_connect(200, 200, 202, 202, 202) @@ -5365,7 +5356,6 @@ class TestReplicatedObjectController( def test_POST_x_container_headers_with_more_container_replicas(self): self.app.container_ring.set_replicas(4) - self.app.object_post_as_copy = False req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'POST'}, @@ -6258,21 +6248,7 @@ class BaseTestECObjectController(BaseTestObjectController): self.ec_policy.object_ring.replica_count) if method == 'POST': - # Take care fast post here! - orig_post_as_copy = getattr( - _test_servers[0], 'object_post_as_copy', None) - try: - _test_servers[0].object_post_as_copy = False - with mock.patch.object( - _test_servers[0], - 'object_post_as_copy', False): - headers = get_ring_reloaded_response(method) - finally: - if orig_post_as_copy is None: - del _test_servers[0].object_post_as_copy - else: - _test_servers[0].object_post_as_copy = \ - orig_post_as_copy + headers = get_ring_reloaded_response(method) exp = 'HTTP/1.1 20' self.assertEqual(headers[:len(exp)], exp) diff --git a/test/unit/proxy/test_sysmeta.py b/test/unit/proxy/test_sysmeta.py index 70757c63f1..0037e008ad 100644 --- a/test/unit/proxy/test_sysmeta.py +++ b/test/unit/proxy/test_sysmeta.py @@ -307,11 +307,6 @@ class TestObjectSysmeta(unittest.TestCase): # test fast-post by issuing requests to the proxy app self._test_sysmeta_not_updated_by_POST(self.app) - def test_sysmeta_not_updated_by_POST_as_copy(self): - # test post-as-copy by issuing requests to the copy middleware app - self.copy_app.object_post_as_copy = True - self._test_sysmeta_not_updated_by_POST(self.copy_app) - def test_sysmeta_updated_by_COPY(self): # check sysmeta is updated by a COPY in same way as user meta by # issuing requests to the copy middleware app @@ -482,8 +477,3 @@ class TestObjectSysmeta(unittest.TestCase): def test_transient_sysmeta_replaced_by_PUT_or_POST(self): self._test_transient_sysmeta_replaced_by_PUT_or_POST(self.app) - - def test_transient_sysmeta_replaced_by_PUT_or_POST_as_copy(self): - # test post-as-copy by issuing requests to the copy middleware app - self.copy_app.object_post_as_copy = True - self._test_transient_sysmeta_replaced_by_PUT_or_POST(self.copy_app)