XmlBodyMiddleware logic causes an unnecessary JSON to dict conversion

Bug #1270516 reported by Venkat Sundaram
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Won't Fix
Low
Venkat Sundaram

Bug Description

The XmlBodyMiddleware converts request body from XML string to JSON string and passes it on to the JsonBodyMiddleware next in chain.

Observe the following line in the XmlBodyMiddleware.process_request method:
         request.body = jsonutils.dumps(
                         serializer.from_xml(request.body))

serializer.from_xml already converts the body to a python dict, but it dumps it again as a JSON string to the request body.

Now, observe the following lines in JsonBodyMiddleware .process_request method:
        # Abort early if we don't have any work to do
        params_json = request.body
        if not params_json:
            return
 ...
        params = {}
        for k, v in params_parsed.iteritems():
            if k in ('self', 'context'):
                continue
            if k.startswith('_'):
                continue
            params[k] = v
...
        request.environ[PARAMS_ENV] = params

The JsonBodyMiddleware converts JSON string to dict and then stores the dict in request.environ (It does some additional filtering of the dict before storing, but that doesn't look like it is JSON specific)

So, if the input request body has XML and the xml_body/json_body middlware are used in the paste pipeline, the effective conversion is: XML string => dict => JSON string => dict

This may induce a performance penalty (however minor it is) due to the unnecessary JSON to dict conversion. The following is the required conversion: XML string => dict

To achieve this, the following could be done:

Refactor the following lines from JsonBodyMiddlware.process_request method and move it to a common module as a method:
        params = {}
        for k, v in params_parsed.iteritems():
            if k in ('self', 'context'):
                continue
            if k.startswith('_'):
                continue
            params[k] = v

Then, call that method from XmlBodyMiddleware.process_request method passing the serialized xml dict. Store the filtered dict as request.environ[PARAMS_ENV]. Then, set the request.body to None.

With this change, the JsonBodyMiddlware next in chain would not process the request due to the following initial check:
        # Abort early if we don't have any work to do
        params_json = request.body
        if not params_json:
            return

Tags: xml
Venkat Sundaram (tsv)
summary: - XmlBodyMiddleware logic causes an unnecessary JSON string to dict
- conversion
+ XmlBodyMiddleware logic causes an unnecessary JSON to dict conversion
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (master)

Fix proposed to branch: master
Review: https://review.openstack.org/67727

Changed in keystone:
assignee: nobody → Venkat Sundaram (tsv)
status: New → In Progress
Dolph Mathews (dolph)
Changed in keystone:
importance: Undecided → Low
Dolph Mathews (dolph)
tags: added: xml
Revision history for this message
David Stanek (dstanek) wrote :

The XML middleware has been marked as deprecated so I don't see a lot of work happening here.

Changed in keystone:
status: In Progress → Won't Fix
Revision history for this message
Lance Bragstad (lbragstad) wrote :
Revision history for this message
Lance Bragstad (lbragstad) wrote :
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.