Skip to content

Commit ef75e14

Browse files
Jenkinsopenstack-gerrit
Jenkins
authored andcommitted
Merge "Fixing bug with x-trans-id. Will now be set on all incoming requests to proxy and trans-ids will not be reused."
2 parents bb8c4ea + 215b3eb commit ef75e14

File tree

8 files changed

+50
-39
lines changed

8 files changed

+50
-39
lines changed

swift/common/middleware/catch_errors.py

+8-5
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,21 @@
2222

2323
class CatchErrorMiddleware(object):
2424
"""
25-
Middleware that provides high-level error handling.
25+
Middleware that provides high-level error handling and ensures that a
26+
transaction id will be set for every request.
2627
"""
2728

2829
def __init__(self, app, conf):
2930
self.app = app
3031
self.logger = get_logger(conf, log_route='catch-errors')
3132

3233
def __call__(self, env, start_response):
33-
trans_id = env.get('HTTP_X_TRANS_ID')
34-
if not trans_id:
35-
trans_id = 'tx' + uuid.uuid4().hex
36-
env['HTTP_X_TRANS_ID'] = trans_id
34+
"""
35+
If used, this should be the first middleware in pipeline.
36+
"""
37+
trans_id = 'tx' + uuid.uuid4().hex
38+
env['swift.trans_id'] = trans_id
39+
self.logger.txn_id = trans_id
3740
try:
3841

3942
def my_start_response(status, response_headers, exc_info=None):

swift/common/middleware/staticweb.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def _get_escalated_env(self, env):
214214
"""
215215
new_env = {'REQUEST_METHOD': 'GET',
216216
'HTTP_USER_AGENT': '%s StaticWeb' % env.get('HTTP_USER_AGENT')}
217-
for name in ('eventlet.posthooks', 'HTTP_X_CF_TRANS_ID', 'REMOTE_USER',
217+
for name in ('eventlet.posthooks', 'swift.trans_id', 'REMOTE_USER',
218218
'SCRIPT_NAME', 'SERVER_NAME', 'SERVER_PORT',
219219
'SERVER_PROTOCOL', 'swift.cache'):
220220
if name in env:
@@ -532,7 +532,7 @@ def _log_response(self, env, status_int):
532532
'-',
533533
'-',
534534
env.get('HTTP_ETAG', '-'),
535-
env.get('HTTP_X_CF_TRANS_ID', '-'),
535+
env.get('swift.trans_id', '-'),
536536
logged_headers or '-',
537537
trans_time)))
538538

swift/common/middleware/tempauth.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ def posthooklogger(self, env, req):
465465
getattr(req, 'bytes_transferred', 0) or '-',
466466
getattr(response, 'bytes_transferred', 0) or '-',
467467
req.headers.get('etag', '-'),
468-
req.headers.get('x-trans-id', '-'), logged_headers or '-',
468+
req.environ.get('swift.trans_id', '-'), logged_headers or '-',
469469
trans_time)))
470470

471471

swift/common/utils.py

+7-8
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,7 @@ class LogAdapter(logging.LoggerAdapter, object):
303303
client ip.
304304
"""
305305

306-
_txn_id = threading.local()
307-
_client_ip = threading.local()
306+
_cls_thread_local = threading.local()
308307

309308
def __init__(self, logger, server):
310309
logging.LoggerAdapter.__init__(self, logger, {})
@@ -313,21 +312,21 @@ def __init__(self, logger, server):
313312

314313
@property
315314
def txn_id(self):
316-
if hasattr(self._txn_id, 'value'):
317-
return self._txn_id.value
315+
if hasattr(self._cls_thread_local, 'txn_id'):
316+
return self._cls_thread_local.txn_id
318317

319318
@txn_id.setter
320319
def txn_id(self, value):
321-
self._txn_id.value = value
320+
self._cls_thread_local.txn_id = value
322321

323322
@property
324323
def client_ip(self):
325-
if hasattr(self._client_ip, 'value'):
326-
return self._client_ip.value
324+
if hasattr(self._cls_thread_local, 'client_ip'):
325+
return self._cls_thread_local.client_ip
327326

328327
@client_ip.setter
329328
def client_ip(self, value):
330-
self._client_ip.value = value
329+
self._cls_thread_local.client_ip = value
331330

332331
def getEffectiveLevel(self):
333332
return self.logger.getEffectiveLevel()

swift/common/wsgi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ def make_pre_authed_request(env, method, path, body=None, headers=None,
207207
(Stolen from Swauth: https://github.com/gholt/swauth)
208208
"""
209209
newenv = {'REQUEST_METHOD': method, 'HTTP_USER_AGENT': agent}
210-
for name in ('swift.cache', 'HTTP_X_TRANS_ID'):
210+
for name in ('swift.cache', 'swift.trans_id'):
211211
if name in env:
212212
newenv[name] = env[name]
213213
newenv['swift.authorize'] = lambda req: None

swift/proxy/server.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -1632,8 +1632,13 @@ def handle_request(self, req):
16321632
return HTTPPreconditionFailed(request=req, body='Bad URL')
16331633

16341634
controller = controller(self, **path_parts)
1635-
controller.trans_id = req.headers.get('x-trans-id', '-')
1636-
self.logger.txn_id = req.headers.get('x-trans-id', None)
1635+
if 'swift.trans_id' not in req.environ:
1636+
# if this wasn't set by an earlier middleware, set it now
1637+
trans_id = 'tx' + uuid.uuid4().hex
1638+
req.environ['swift.trans_id'] = trans_id
1639+
self.logger.txn_id = trans_id
1640+
req.headers['x-trans-id'] = req.environ['swift.trans_id']
1641+
controller.trans_id = req.environ['swift.trans_id']
16371642
self.logger.client_ip = get_remote_client(req)
16381643
try:
16391644
handler = getattr(controller, req.method)
@@ -1708,10 +1713,12 @@ def posthooklogger(self, env, req):
17081713
getattr(req, 'bytes_transferred', 0) or '-',
17091714
getattr(response, 'bytes_transferred', 0) or '-',
17101715
req.headers.get('etag', '-'),
1711-
req.headers.get('x-trans-id', '-'),
1716+
req.environ.get('swift.trans_id', '-'),
17121717
logged_headers or '-',
17131718
trans_time,
17141719
)))
1720+
# done with this transaction
1721+
self.access_logger.txn_id = None
17151722

17161723

17171724
def app_factory(global_conf, **local_conf):

test/unit/common/middleware/test_except.py

+20-18
Original file line numberDiff line numberDiff line change
@@ -15,58 +15,60 @@
1515

1616
import unittest
1717

18-
from webob import Request
18+
from webob import Request, Response
1919

2020
from swift.common.middleware import catch_errors
21+
from swift.common.utils import get_logger
2122

2223
class FakeApp(object):
2324
def __init__(self, error=False):
2425
self.error = error
2526

2627
def __call__(self, env, start_response):
28+
if 'swift.trans_id' not in env:
29+
raise Exception('Trans id should always be in env')
2730
if self.error:
28-
raise Exception('augh!')
29-
return "FAKE APP"
31+
raise Exception('An error occurred')
32+
return ["FAKE APP"]
3033

3134
def start_response(*args):
3235
pass
3336

3437
class TestCatchErrors(unittest.TestCase):
3538

39+
def setUp(self):
40+
self.logger = get_logger({})
41+
self.logger.txn_id = None
42+
3643
def test_catcherrors_passthrough(self):
3744
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
3845
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'})
3946
resp = app(req.environ, start_response)
40-
self.assertEquals(resp, 'FAKE APP')
47+
self.assertEquals(resp, ['FAKE APP'])
4148

4249
def test_catcherrors(self):
4350
app = catch_errors.CatchErrorMiddleware(FakeApp(True), {})
4451
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'})
4552
resp = app(req.environ, start_response)
4653
self.assertEquals(resp, ['An error occurred'])
4754

48-
def test_trans_id_header(self):
49-
55+
def test_trans_id_header_pass(self):
56+
self.assertEquals(self.logger.txn_id, None)
5057
def start_response(status, headers):
5158
self.assert_('x-trans-id' in (x[0] for x in headers))
5259
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
53-
req = Request.blank('/v1/a')
54-
app(req.environ, start_response)
55-
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
56-
req = Request.blank('/v1/a/c')
57-
app(req.environ, start_response)
58-
app = catch_errors.CatchErrorMiddleware(FakeApp(), {})
5960
req = Request.blank('/v1/a/c/o')
6061
app(req.environ, start_response)
61-
app = catch_errors.CatchErrorMiddleware(FakeApp(True), {})
62-
req = Request.blank('/v1/a')
63-
app(req.environ, start_response)
64-
app = catch_errors.CatchErrorMiddleware(FakeApp(True), {})
65-
req = Request.blank('/v1/a/c')
66-
app(req.environ, start_response)
62+
self.assertEquals(len(self.logger.txn_id), 34) # 32 hex + 'tx'
63+
64+
def test_trans_id_header_fail(self):
65+
self.assertEquals(self.logger.txn_id, None)
66+
def start_response(status, headers):
67+
self.assert_('x-trans-id' in (x[0] for x in headers))
6768
app = catch_errors.CatchErrorMiddleware(FakeApp(True), {})
6869
req = Request.blank('/v1/a/c/o')
6970
app(req.environ, start_response)
71+
self.assertEquals(len(self.logger.txn_id), 34)
7072

7173
if __name__ == '__main__':
7274
unittest.main()

test/unit/common/test_wsgi.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ class FakeReq(object):
179179
@classmethod
180180
def fake_blank(cls, path, environ={}, body='', headers={}):
181181
self.assertEquals(environ['swift.authorize']('test'), None)
182-
self.assertEquals(environ['HTTP_X_TRANS_ID'], '1234')
182+
self.assertFalse('HTTP_X_TRANS_ID' in environ)
183183
was_blank = Request.blank
184184
Request.blank = FakeReq.fake_blank
185185
wsgi.make_pre_authed_request({'HTTP_X_TRANS_ID': '1234'},

0 commit comments

Comments
 (0)