]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Import request_id middleware bug fix from oslo
authorAkihiro Motoki <motoki@da.jp.nec.com>
Wed, 26 Mar 2014 14:28:49 +0000 (23:28 +0900)
committerAkihiro Motoki <motoki@da.jp.nec.com>
Wed, 26 Mar 2014 14:35:55 +0000 (23:35 +0900)
There is a bug in request-id middleware that a subsequent API request will
overwrite a request-id of a previous request when multiple API calls are
processed in parallel in request_id middleware.
This commit imports the fix in oslo.

cherry-picked from oslo-incubator d7bd9dc37ac3d6bc171cd2e290c772633ad20a32
Closes-Bug: #1289696
----
Don't store the request ID value in middleware as class variable

The original version of the request_id middleware generates a request ID during
process_request() and stores the value in a variable, so it can be attached as
header in process_request(). This is pretty dangerous, since subsequent
requests will overwrite this value, and the wrong request ID may be attached to
some responses. This is particularly apparent when requests arrive in parallel.

This change replaces process_request() and process_response() with an override
of __call__(). This allows the generated req_id to be used in the response
header without needing to save it as a class-level variable.
----

Change-Id: Ic20047f604394f1ce4900c3b6a00595223804cba

neutron/openstack/common/middleware/request_id.py

index d442faf4f10f9755aaa3338f417cb48c3508cb74..5c2620cce42f54f2073fa11bf27667723803de0b 100644 (file)
@@ -19,6 +19,8 @@ It ensures to assign request ID for each API request and set it to
 request environment. The request ID is also added to API response.
 """
 
+import webob.dec
+
 from neutron.openstack.common import context
 from neutron.openstack.common.middleware import base
 
@@ -29,10 +31,11 @@ HTTP_RESP_HEADER_REQUEST_ID = 'x-openstack-request-id'
 
 class RequestIdMiddleware(base.Middleware):
 
-    def process_request(self, req):
-        self.req_id = context.generate_request_id()
-        req.environ[ENV_REQUEST_ID] = self.req_id
-
-    def process_response(self, response):
-        response.headers.add(HTTP_RESP_HEADER_REQUEST_ID, self.req_id)
+    @webob.dec.wsgify
+    def __call__(self, req):
+        req_id = context.generate_request_id()
+        req.environ[ENV_REQUEST_ID] = req_id
+        response = req.get_response(self.application)
+        if HTTP_RESP_HEADER_REQUEST_ID not in response.headers:
+            response.headers.add(HTTP_RESP_HEADER_REQUEST_ID, req_id)
         return response