default_renderer overrides explicit content_type

Bug #1465688 reported by Alfredo Deza
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
pecan
Fix Released
Medium
Ryan Petrello

Bug Description

In a web service that has a `default_renderer = 'json'` because most/all of its controllers render JSON responses I had an issue where one controller method is supposed to serve a download file.

The controller looks roughly like:

    @expose(content_type='application/octet-stream', generic=True)
    def index(self):
        response.headers['Content-Disposition'] = 'attachment; filename=%s' % str(self.binary.name)
        f = open(self.binary.path, 'rb')
        response.app_iter = FileIter(f)

But when testing out the endpoint, the file was just a 4 byte file with 'null' in it. Investigating this a bit further, and stepping through the whole request, in pecan/core.py in invoke_controller there is a check to override templates (Note that I am being explicit about the content type) that it does various checks like:

        # check if for controller override of template
        template = pecan_state.get('override_template', template) or (
            'json' if self.default_renderer == 'json' else None
        )

Which will make `template` be 'json' because it is the default one (which is fine). However, it ignores that I am setting a specific content_type in my controller method and changes it to "application/json" which is no longer correct:

        # if there is a template, render it
        if template:
            if template == 'json':
                pecan_state['content_type'] = 'application/json'
            result = self.render(template, result)

I am using the `default_renderer` flag to JSON because that is what this application is using in almost every controller. Removing that flag fixes this issue for the download not working, but forces me to specify "json" as the template engine for every controller.

I couldn't see anything in the docs that defined this behavior (which only happens for 'json') and that content-types will get overridden regardless if they are being set explicitly.

Looking at custom_renderers also seems like just a workaround: implementing a custom_renderer that doesn't do anything to prevent the trigger on the check for default_renderer to json when the template engine is not specified.

Changed in pecan:
importance: Undecided → Medium
assignee: nobody → Ryan Petrello (ryan-petrello)
status: New → Confirmed
Changed in pecan:
status: Confirmed → Fix Committed
Changed in pecan:
status: Fix Committed → Fix Released
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.