Setting Content-Type in a custom response (mp2)

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=3Diso-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=3Dutf-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=3Dutf-8");

doesn't seem to work in this case.
Steve Hay [ Do, 11 März 2010 15:18 ] [ ID #2034697 ]

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

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=3Diso-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=3Dutf-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=3Dutf-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") !=3D NULL) {
core_request_config *request_conf =3D
ap_get_module_config(r->request_config, &core_modul=
e);
request_conf->suppress_charset =3D 1; /* avoid adding default
* charset later
*/
ap_set_content_type(r, "text/html");
}
else {
ap_set_content_type(r, "text/html; charset=3Diso-8859-1");
}

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

But instead of passing the response text directly to $r->custom_response yo=
u
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}=3D$error;
$r->pnotes->{ect}=3D'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)=3D [at] _;
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

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

Like fantasy? http://kabatinte.net
torsten.foertsch [ Do, 11 März 2010 17:22 ] [ ID #2034698 ]

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=3Diso-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=3Dutf-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=3Dutf-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") !=3D NULL) {
> core_request_config *request_conf =3D
> ap_get_module_config(r->request_config,
> &core_module);
> request_conf->suppress_charset =3D 1; /* avoid adding =
default
> * charset later
> */
> ap_set_content_type(r, "text/html");
> }
> else {
> ap_set_content_type(r, "text/html; charset=3Diso-8859-1");
> }
> The resulting content-type is either "text/html; =
charset=3Diso-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}=3D$error;
> $r->pnotes->{ect}=3D'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)=3D [at] _; 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 :-)
Steve Hay [ Fr, 12 März 2010 10:58 ] [ ID #2034846 ]

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

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=C3=BCngliche Nachricht-----
Von: Steve Hay
Gesendet: 12.03.2010 10:58:15
An: "Torsten F=C3=B6rtsch" <torsten.foertsch [at] gmx.net>,modperl [at] perl.apache.o=
rg
Betreff: RE: Setting Content-Type in a custom response (mp2)

>Torsten F=C3=B6rtsch 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=3Diso-8859-1", in which the charse=
t,
>>> 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=3Dutf-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=3Dutf-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") !=3D NULL) {
>> core_request_config *request_conf =3D
>> ap_get_module_config(r->request_config,
>> &core_module);
>> request_conf->suppress_charset =3D 1; /* avoid adding defaul=
t
>> * charset later
>> */
>> ap_set_content_type(r, "text/html");
>> }
>> else {
>> ap_set_content_type(r, "text/html; charset=3Diso-8859-1");
>> }
>> The resulting content-type is either "text/html; charset=3Diso-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}=3D$error;
>> $r->pnotes->{ect}=3D'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)=3D [at] _; 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 :-)
Andreas Mock [ Fr, 12 März 2010 11:25 ] [ ID #2034847 ]
Webserver » gmane.comp.apache.mod-perl » Setting Content-Type in a custom response (mp2)

Vorheriges Thema: Upgrading chained response handlers to mod_perl2
Nächstes Thema: Error: `PL_sv_yes' can not be used when making a shared object; recompile with -fPIC