199
200
charset_req_t *reqinfo;
200
201
charset_filter_ctx_t *input_ctx, *output_ctx;
202
const char *mime_type;
204
204
if (dc->debug >= DBGLVL_FLOW) {
205
205
ap_log_rerror(APLOG_MARK,APLOG_DEBUG, 0, r,
206
206
"uri: %s file: %s method: %d "
207
207
"imt: %s flags: %s%s%s %s->%s",
208
r->uri, r->filename, r->method_number,
209
r->filename ? r->filename : "(none)",
209
211
r->content_type ? r->content_type : "(unknown)",
210
212
r->main ? "S" : "", /* S if subrequest */
211
213
r->prev ? "R" : "", /* R if redirect */
228
230
/* catch proxy requests */
229
if (r->proxyreq) return DECLINED;
230
235
/* mod_rewrite indicators */
231
if (!strncmp(r->filename, "redirect:", 9)) return DECLINED;
232
if (!strncmp(r->filename, "gone:", 5)) return DECLINED;
233
if (!strncmp(r->filename, "passthrough:", 12)) return DECLINED;
234
if (!strncmp(r->filename, "forbidden:", 10)) return DECLINED;
237
&& (!strncmp(r->filename, "redirect:", 9)
238
|| !strncmp(r->filename, "gone:", 5)
239
|| !strncmp(r->filename, "passthrough:", 12)
240
|| !strncmp(r->filename, "forbidden:", 10))) {
235
244
/* no translation when server and network charsets are set to the same value */
236
if (!strcasecmp(dc->charset_source, dc->charset_default)) return DECLINED;
238
mime_type = r->content_type ? r->content_type : ap_default_type(r);
240
/* If mime type isn't text or message, bail out.
243
/* XXX When we handle translation of the request body, watch out here as
244
* 1.3 allowed additional mime types: multipart and
245
* application/x-www-form-urlencoded
248
if (strncasecmp(mime_type, "text/", 5) &&
249
#if APR_CHARSET_EBCDIC || AP_WANT_DIR_TRANSLATION
250
/* On an EBCDIC machine, be willing to translate mod_autoindex-
251
* generated output. Otherwise, it doesn't look too cool.
253
* XXX This isn't a perfect fix because this doesn't trigger us
254
* to convert from the charset of the source code to ASCII. The
255
* general solution seems to be to allow a generator to set an
256
* indicator in the r specifying that the body is coded in the
257
* implementation character set (i.e., the charset of the source
258
* code). This would get several different types of documents
259
* translated properly: mod_autoindex output, mod_status output,
260
* mod_info output, hard-coded error documents, etc.
262
strcmp(mime_type, DIR_MAGIC_TYPE) &&
264
strncasecmp(mime_type, "message/", 8)) {
265
if (dc->debug >= DBGLVL_GORY) {
266
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
267
"mime type is %s; no translation selected",
270
/* We must not bail out here (i.e., the MIME test must be in the filter
271
* itself, not in the fixup, because only then is the final MIME type known.
272
* Examples for late changes to the MIME type include CGI handling (MIME
273
* type is set in the Content-Type header produced by the CGI script), or
274
* PHP (until PHP runs, the MIME type is set to application/x-httpd-php)
278
if (dc->debug >= DBGLVL_GORY) {
279
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
280
"charset_source: %s charset_default: %s",
281
dc && dc->charset_source ? dc->charset_source : "(none)",
282
dc && dc->charset_default ? dc->charset_default : "(none)");
245
if (!strcasecmp(dc->charset_source, dc->charset_default)) {
285
249
/* Get storage for the request data and the output filter context.
297
261
reqinfo->output_ctx = output_ctx;
299
/* We must not open the xlation table here yet, because the final MIME
300
* type is not known until we are actually called in the output filter.
301
* With POST or PUT request, the case is different, because their MIME
302
* type is set in the request headers, and their data are prerequisites
303
* for actually calling, e.g., the CGI handler later on.
305
output_ctx->xlate = NULL;
307
263
switch (r->method_number) {
826
/* Opening the output translation (this used to be done in the fixup hook,
827
* but that was too early: a subsequent type modification, e.g., by a
828
* CGI script, would go unnoticed. Now we do it in the filter itself.)
785
/* Check the mime type to see if translation should be performed.
830
if (!ctx->noop && ctx->xlate == NULL)
787
if (!ctx->noop && ctx->xlate == NULL) {
832
788
const char *mime_type = f->r->content_type ? f->r->content_type : ap_default_type(f->r);
834
/* XXX When we handle translation of the request body, watch out here as
835
* 1.3 allowed additional mime types: multipart and
836
* application/x-www-form-urlencoded
838
790
if (strncasecmp(mime_type, "text/", 5) == 0 ||
839
791
#if APR_CHARSET_EBCDIC
840
792
/* On an EBCDIC machine, be willing to translate mod_autoindex-
849
801
* translated properly: mod_autoindex output, mod_status output,
850
802
* mod_info output, hard-coded error documents, etc.
852
strcmp(mime_type, DIR_MAGIC_TYPE) == 0 ||
804
strcmp(mime_type, DIR_MAGIC_TYPE) == 0 ||
854
strncasecmp(mime_type, "message/", 8) == 0) {
806
strncasecmp(mime_type, "message/", 8) == 0) {
856
808
rv = apr_xlate_open(&ctx->xlate,
857
dc->charset_default, dc->charset_source, f->r->pool);
809
dc->charset_default, dc->charset_source, f->r->pool);
858
810
if (rv != APR_SUCCESS) {
859
811
ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r,
860
812
"can't open translation %s->%s",
861
813
dc->charset_source, dc->charset_default);
817
if (apr_xlate_sb_get(ctx->xlate, &ctx->is_sb) != APR_SUCCESS) {
867
if (dc->debug >= DBGLVL_GORY)
868
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
869
"mime type is %s; no translation selected",
824
if (dc->debug >= DBGLVL_GORY) {
825
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
826
"mime type is %s; no translation selected",
874
832
if (dc->debug >= DBGLVL_GORY) {
875
833
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
876
"xlate_out_filter() - "
877
"charset_source: %s charset_default: %s",
878
dc && dc->charset_source ? dc->charset_source : "(none)",
879
dc && dc->charset_default ? dc->charset_default : "(none)");
834
"xlate_out_filter() - "
835
"charset_source: %s charset_default: %s",
836
dc && dc->charset_source ? dc->charset_source : "(none)",
837
dc && dc->charset_default ? dc->charset_default : "(none)");
882
840
if (!ctx->ran) { /* filter never ran before */
883
841
chk_filter_chain(f);
843
if (!ctx->noop && !ctx->is_sb) {
844
/* We're not converting between two single-byte charsets, so unset
845
* Content-Length since it is unlikely to remain the same.
847
apr_table_unset(f->r->headers_out, "Content-Length");
1040
1004
if (!ctx->ran) { /* filter never ran before */
1041
1005
chk_filter_chain(f);
1007
if (!ctx->noop && !ctx->is_sb
1008
&& apr_table_get(f->r->headers_in, "Content-Length")) {
1009
/* A Content-Length header is present, but it won't be valid after
1010
* conversion because we're not converting between two single-byte
1011
* charsets. This will affect most CGI scripts and may affect
1013
* Content-Length can't be unset here because that would break
1014
* being able to read the request body.
1015
* Processing of chunked request bodies is not impacted by this
1016
* filter since the the length was not declared anyway.
1018
if (dc->debug >= DBGLVL_PMC) {
1019
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, f->r,
1020
"Request body length may change, resulting in "
1021
"misprocessing by some modules or scripts");
1045
1026
if (ctx->noop) {