Torsten Förtsch wrote on 2010-03-11: > 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> >
Thanks! That works a treat :-)