Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Ticket #1071 (closed defect: invalid)

Opened 13 years ago

Last modified 12 years ago

let the controller handler define response header Content-Type

Reported by: dalke Owned by: anonymous
Priority: normal Milestone: 1.5
Component: TurboGears Version: 0.9a5
Severity: normal Keywords:
Cc:

Description (last modified by jorge.vargas) (diff)

As mentioned in ticket #1070, I have controllers which can respond in a format selected by a URL parameter. (This parameter is named "format" and cannot be changed to use "tg_format" or con-neg.)

Sometimes it's plain text. In that case I do something like

def format_as_raw_text():
  cherrypy.response.headers["Content-Type"] = "text/plain"
  def response():
      yield "Perhaps this is over kill.  Doing it this way "
      yield "so I know the header is set before I return anything.\n"
      yield "I should read the cherrypy docs on this.\n"
  return response()

I expected that I could do the same when I choose to respond via XML

def format_as_das2xml():
  cherrypy.response.headers["Content-Type"] = "application/x-das2text+xml"
  return dict(question="What's the capital of Florida?",
              answer="Umm.... 'F'!",
              tg_format="xml",
              tg_template="das2.templates.q_and_a")

With patch 1070 the "tg_format" works so the returned template is correct. Rather, it generates a correct byte stream in the HTTP payload. The header is not correct. It shows a content-type of "text/xml; charset='utf-8'".

In more details, the content-type before calling my handler is "text/html". My handler sets it to "application/x-...+xml". Then turbogears.view.base.render looks as the @expose setting, sees there is no "content_type", and the response header to the "text/html; charset='utf-8'".

This is annoying. I didn't set the @expose content_type because there is no meaningful value at that point, but I do have one later on.

I came up with two solutions. First, I could use the approach of "tg_template" (and "tg_format" in patch 1070) and return a "tg_content_type" in the dictionary. I rejected this because it's different than what I would do with the plain text solution, where I set the response header myself. I want the two to be structurally similar so if one sets cherrypy.headers[...] then the other should as well.

Second I could set the initial response Content-Type to None. If after calling the user-defined controller handler the Content-Type is set then use the new value. Here's the relevant change to controller.py:_execute_func

    old_content_type = cherrypy.response.headers["Content-Type"]
    cherrypy.response.headers["Content-Type"] = None
    output = errorhandling.try_call(func, *args, **kw)
    if cherrypy.response.headers["Content-Type"] is not None:
        content_type = cherrypy.response.headers["Content-Type"]
    else:
        content_type = old_content_type

I think of this as a hack. If this is the right approach then I think TurboGears should set "server.default_content_type" to None (is that possible?) so CherryPy?'s response header starts off being None instead of "text/html". Only after the controller handler is run should TG check the content-type and if it's still None then set it based on the various other settings.

Or not. Who gets to override whom? Does the controller function override the @expose or vice versa? In my case the @expose's content_type is None so it doesn't matter.

Attachments

controllers.py.diff Download (2.4 KB) - added by dalke 13 years ago.
the hackish solution to ticket 1071; includes patches for 1066 and 1077

Change History

Changed 13 years ago by dalke

the hackish solution to ticket 1071; includes patches for 1066 and 1077

comment:1 Changed 13 years ago by dalke

Err, that should read "1070" and not "1077"

comment:2 Changed 13 years ago by jorge.vargas

  • Description modified (diff)
  • Milestone set to 1.0

if you take this to the mailing list it may get more replies :)

comment:3 Changed 13 years ago by fumanchu@…

  • Component changed from CherryPy to TurboGears

CherryPy isn't going to change for this, since it already supplies plenty of mechanisms for either TG or the OP to resolve it.

comment:4 Changed 12 years ago by alberto

  • Milestone changed from 1.0 to 1.1

comment:5 Changed 12 years ago by jorge.vargas

  • Status changed from new to closed
  • Resolution set to invalid

all patches refered to here have been applied some with different implementations please test if this is no longer happening.

Note: See TracTickets for help on using tickets.