From 5fca0d07a873106b2175bcb3b5bfbee1cbd04a31 Mon Sep 17 00:00:00 2001 From: Samuel Merritt Date: Wed, 5 Feb 2014 11:57:20 -0800 Subject: [PATCH] Ensure swift.source is set for DLO/SLO requests SLO was setting it sometimes (the PUT path), but not others (the GET path), and DLO just wasn't doing it at all. One could already distinguish DLO/SLO internal requests by the user agent, but we should set swift.source too. Change-Id: I5d5b7dd49bd1522a9c830d0abd21fff92ae79a39 --- swift/common/middleware/dlo.py | 2 ++ swift/common/middleware/slo.py | 3 +++ swift/common/utils.py | 7 ++++++- test/unit/common/middleware/helpers.py | 2 ++ test/unit/common/middleware/test_dlo.py | 4 ++++ test/unit/common/middleware/test_slo.py | 6 +++++- 6 files changed, 22 insertions(+), 2 deletions(-) diff --git a/swift/common/middleware/dlo.py b/swift/common/middleware/dlo.py index 21bee2f704..491e8324dd 100644 --- a/swift/common/middleware/dlo.py +++ b/swift/common/middleware/dlo.py @@ -37,6 +37,7 @@ class GetContext(WSGIContext): prefix, marker=''): con_req = req.copy_get() con_req.script_name = '' + con_req.environ['swift.source'] = 'DLO' con_req.range = None con_req.path_info = '/'.join(['', version, account, container]) con_req.query_string = 'format=json&prefix=%s' % quote(prefix) @@ -197,6 +198,7 @@ class GetContext(WSGIContext): app_iter=SegmentedIterable( req, self.dlo.app, listing_iter, ua_suffix="DLO MultipartGET", + swift_source="DLO", name=req.path, logger=self.logger, max_get_time=self.dlo.max_get_time)) resp.app_iter.response = resp diff --git a/swift/common/middleware/slo.py b/swift/common/middleware/slo.py index be82dcceef..c0d51aae53 100644 --- a/swift/common/middleware/slo.py +++ b/swift/common/middleware/slo.py @@ -217,6 +217,7 @@ class SloGetContext(WSGIContext): sub_req = req.copy_get() sub_req.range = None sub_req.environ['PATH_INFO'] = '/'.join(['', version, acc, con, obj]) + sub_req.environ['swift.source'] = 'SLO' sub_req.user_agent = "%s SLO MultipartGET" % sub_req.user_agent sub_resp = sub_req.get_response(self.slo.app) @@ -346,6 +347,7 @@ class SloGetContext(WSGIContext): get_req = req.copy_get() get_req.range = None + get_req.environ['swift.source'] = 'SLO' get_req.user_agent = "%s SLO MultipartGET" % get_req.user_agent resp_iter = self._app_call(get_req.environ) @@ -425,6 +427,7 @@ class SloGetContext(WSGIContext): req, self.slo.app, segment_listing_iter, name=req.path, logger=self.slo.logger, ua_suffix="SLO MultipartGET", + swift_source="SLO", max_get_time=self.slo.max_get_time)) if req.range: response.headers.pop('Etag') diff --git a/swift/common/utils.py b/swift/common/utils.py index 8814fc5b11..6186422ce4 100644 --- a/swift/common/utils.py +++ b/swift/common/utils.py @@ -2593,19 +2593,23 @@ class SegmentedIterable(object): or (object-path, None, None) to fetch the whole thing. :param max_get_time: maximum permitted duration of a GET request (seconds) :param logger: logger object + :param swift_source: value of swift.source in subrequest environ + (just for logging) :param ua_suffix: string to append to user-agent. :param name: name of manifest (used in logging only) :param response: optional response object for the response being sent to the client. Only affects logs. """ def __init__(self, req, app, listing_iter, max_get_time, - logger, ua_suffix, name='', response=None): + logger, ua_suffix, swift_source, + name='', response=None): self.req = req self.app = app self.listing_iter = listing_iter self.max_get_time = max_get_time self.logger = logger self.ua_suffix = " " + ua_suffix + self.swift_source = swift_source self.name = name self.response = response @@ -2633,6 +2637,7 @@ class SegmentedIterable(object): seg_req = self.req.copy_get() seg_req.range = None seg_req.environ['PATH_INFO'] = seg_path + seg_req.environ['swift.source'] = self.swift_source seg_req.user_agent = "%s %s" % (seg_req.user_agent, self.ua_suffix) if first_byte is not None or last_byte is not None: diff --git a/test/unit/common/middleware/helpers.py b/test/unit/common/middleware/helpers.py index fc37b5612e..0ea957b534 100644 --- a/test/unit/common/middleware/helpers.py +++ b/test/unit/common/middleware/helpers.py @@ -29,6 +29,7 @@ class FakeSwift(object): def __init__(self): self._calls = [] self.req_method_paths = [] + self.swift_sources = [] self.uploaded = {} # mapping of (method, path) --> (response class, headers, body) self._responses = {} @@ -43,6 +44,7 @@ class FakeSwift(object): headers = swob.Request(env).headers self._calls.append((method, path, headers)) + self.swift_sources.append(env.get('swift.source')) try: resp_class, raw_headers, body = self._responses[(method, path)] diff --git a/test/unit/common/middleware/test_dlo.py b/test/unit/common/middleware/test_dlo.py index 52fb4f5897..6763775163 100644 --- a/test/unit/common/middleware/test_dlo.py +++ b/test/unit/common/middleware/test_dlo.py @@ -292,6 +292,10 @@ class TestDloGetManifest(DloTestCase): self.assertFalse( "DLO MultipartGET" in self.app.calls_with_headers[0][2]) + # we set swift.source for everything but the first request + self.assertEqual(self.app.swift_sources, + [None, 'DLO', 'DLO', 'DLO', 'DLO', 'DLO', 'DLO']) + def test_get_non_manifest_passthrough(self): req = swob.Request.blank('/v1/AUTH_test/c/catpicture.jpg', environ={'REQUEST_METHOD': 'GET'}) diff --git a/test/unit/common/middleware/test_slo.py b/test/unit/common/middleware/test_slo.py index b6eb02c9b5..093b8459ec 100644 --- a/test/unit/common/middleware/test_slo.py +++ b/test/unit/common/middleware/test_slo.py @@ -838,8 +838,9 @@ class TestSloGetManifest(SloTestCase): self.assertTrue("SLO MultipartGET" in ua) self.assertFalse("SLO MultipartGET SLO MultipartGET" in ua) # the first request goes through unaltered + first_ua = self.app.calls_with_headers[0][2].get("User-Agent") self.assertFalse( - "SLO MultipartGET" in self.app.calls_with_headers[0][2]) + "SLO MultipartGET" in first_ua) def test_get_manifest_with_submanifest(self): req = Request.blank( @@ -884,6 +885,9 @@ class TestSloGetManifest(SloTestCase): self.assertEqual(headers[3].get('Range'), None) self.assertEqual(headers[4].get('Range'), None) self.assertEqual(headers[5].get('Range'), 'bytes=0-2') + # we set swift.source for everything but the first request + self.assertEqual(self.app.swift_sources, + [None, 'SLO', 'SLO', 'SLO', 'SLO', 'SLO']) def test_range_get_manifest_on_segment_boundaries(self): req = Request.blank(