Re: Setting Content-Type in a custom response (mp2)

Torsten Förtsch <[email protected]>
Newsgroups gmane.comp.apache.mod-perl
Message-ID <[email protected]>
On Thursday 11 March 2010 15:18:08 Steve Hay wrote:
> I have a mod_perl-2 handler that uses custom_response() to display error
> messages if something goes wrong:
> 
> $r->custom_response(Apache2::Const::SERVER_ERROR, $error);
> return Apache2::Const::SERVER_ERROR;
> 
> That almost works fine, but the trouble is that the Content-Type header
> is always set to "text/html; charset=iso-8859-1", in which the charset,
> at least, is potentially wrong: all the pages in my software produce
> UTF-8 and are normally output with Content-Type "application/xhtml+xml;
> charset=utf-8".
> 
> How do I set the Content-Type when issuing a custom_reponse()? The usual
> thing of calling
> 
> $r->content_type("application/xhtml+xml; charset=utf-8");
> 
> doesn't seem to work in this case.
> 
I think that is impossible. ap_send_error_response() contains this code:

        if (apr_table_get(r->subprocess_env,
                          "suppress-error-charset") != NULL) {
            core_request_config *request_conf =
                        ap_get_module_config(r->request_config, &core_module);
            request_conf->suppress_charset = 1; /* avoid adding default
                                                 * charset later
                                                 */
            ap_set_content_type(r, "text/html");
        }
        else {
            ap_set_content_type(r, "text/html; charset=iso-8859-1");
        }

The resulting content-type is either "text/html; charset=iso-8859-1" or 
"text/html".

But instead of passing the response text directly to $r->custom_response you 
can specify an URL. ap_die() will then create an internal redirect to this 
URL. Via $r->prev->pnotes you can then access the pnotes of the failed 
request. Putting all together a solution could look like:

  $r->pnotes->{estring}=$error;
  $r->pnotes->{ect}='my/special-content-type';
  # use an otherwise not used URL here
  $r->custom_response(Apache2::Const::SERVER_ERROR, '/-/error');

  <Location /-/error>
    SetHandler modperl
    # please insert a \ at the end of each of the following lines 
    # up to }"
    PerlResponseHandler "sub {
      my ($r)=@_;
      return Apache2::Const::NOT_FOUND unless $r->prev;
      $r->content_type($r->prev->pnotes->{ect});
      $r->print($r->prev->pnotes->{estring});
      return Apache2::Const::OK;
    }"
  </Location>

Torsten Förtsch

-- 
Need professional modperl support? Hire me! (http://foertsch.name)

Like fantasy? http://kabatinte.net
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.