Author Login
Post Reply
Hi all,
I searched for that solution for hours not finding any until
Torsten posted this one.
IMHO it's worth it to put Torsten's snippet to the documentation
pages of mod_perl.
Even the book 'mod_perl 2 user's guide' leaves a big hole
in that area.
Thank you Torsten!
Best regards
Andreas Mock
-----Ursprüngliche Nachricht-----
Von: Steve Hay
Gesendet: 12.03.2010 10:58:15
An: "Torsten Förtsch" <torsten.foertsch@gmx.net>,modperl@(protected)
Betreff: RE: Setting Content-Type in a custom response (mp2)
>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)=@(protected);
>> $r->content_type($r->prev->pnotes->{ect});
>> $r->print($r->prev->pnotes->{estring}); return Apache2::Const::OK;
>> }"
>> </Location>
>>
>
>Thanks! That works a treat :-)