~ubuntu-branches/ubuntu/hardy/apache2/hardy-proposed

« back to all changes in this revision

Viewing changes to modules/filters/mod_charset_lite.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Fritsch
  • Date: 2008-01-17 20:27:56 UTC
  • mto: This revision was merged to the branch mainline in revision 26.
  • Revision ID: james.westby@ubuntu.com-20080117202756-hv38rjknhwa2ilwi
Tags: upstream-2.2.8
ImportĀ upstreamĀ versionĀ 2.2.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
85
85
 */
86
86
typedef struct charset_filter_ctx_t {
87
87
    apr_xlate_t *xlate;
 
88
    int is_sb;              /* single-byte translation? */
88
89
    charset_dir_t *dc;
89
90
    ees_t ees;              /* extended error status */
90
91
    apr_size_t saved;
188
189
    return NULL;
189
190
}
190
191
 
191
 
/* find_code_page() is a fixup hook that decides if translation should be
192
 
 * enabled; if so, it sets up request data for use by the filter registration
193
 
 * hook so that it knows what to do
 
192
/* find_code_page() is a fixup hook that checks if the module is
 
193
 * configured and the input or output potentially need to be translated.
 
194
 * If so, context is initialized for the filters.
194
195
 */
195
196
static int find_code_page(request_rec *r)
196
197
{
199
200
    charset_req_t *reqinfo;
200
201
    charset_filter_ctx_t *input_ctx, *output_ctx;
201
202
    apr_status_t rv;
202
 
    const char *mime_type;
203
203
 
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,
 
208
                      r->uri,
 
209
                      r->filename ? r->filename : "(none)",
 
210
                      r->method_number,
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 */
226
228
    }
227
229
 
228
230
    /* catch proxy requests */
229
 
    if (r->proxyreq) return DECLINED;
 
231
    if (r->proxyreq) {
 
232
        return DECLINED;
 
233
    }
 
234
 
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;
 
236
    if (r->filename
 
237
        && (!strncmp(r->filename, "redirect:", 9)
 
238
            || !strncmp(r->filename, "gone:", 5)
 
239
            || !strncmp(r->filename, "passthrough:", 12)
 
240
            || !strncmp(r->filename, "forbidden:", 10))) {
 
241
        return DECLINED;
 
242
    }
 
243
 
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;
237
 
 
238
 
    mime_type = r->content_type ? r->content_type : ap_default_type(r);
239
 
 
240
 
    /* If mime type isn't text or message, bail out.
241
 
     */
242
 
 
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
246
 
 */
247
 
 
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.
252
 
         *
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.
261
 
         */
262
 
        strcmp(mime_type, DIR_MAGIC_TYPE) &&
263
 
#endif
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",
268
 
                          mime_type);
269
 
        }
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)
275
 
         */
276
 
    }
277
 
 
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)) {
 
246
        return DECLINED;
283
247
    }
284
248
 
285
249
    /* Get storage for the request data and the output filter context.
296
260
 
297
261
    reqinfo->output_ctx = output_ctx;
298
262
 
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.
304
 
     */
305
 
    output_ctx->xlate = NULL;
306
 
 
307
263
    switch (r->method_number) {
308
264
    case M_PUT:
309
265
    case M_POST:
325
281
                          dc->charset_default, dc->charset_source);
326
282
            return HTTP_INTERNAL_SERVER_ERROR;
327
283
        }
 
284
        if (apr_xlate_sb_get(input_ctx->xlate, &input_ctx->is_sb) != APR_SUCCESS) {
 
285
            input_ctx->is_sb = 0;
 
286
        }
328
287
    }
329
288
 
330
289
    return DECLINED;
823
782
        }
824
783
    }
825
784
 
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.
829
786
     */
830
 
    if (!ctx->noop && ctx->xlate == NULL)
831
 
    {
 
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);
833
789
 
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
837
 
         */
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.
851
803
         */
852
 
        strcmp(mime_type, DIR_MAGIC_TYPE) == 0 ||
 
804
            strcmp(mime_type, DIR_MAGIC_TYPE) == 0 ||
853
805
#endif
854
 
        strncasecmp(mime_type, "message/", 8) == 0) {
 
806
            strncasecmp(mime_type, "message/", 8) == 0) {
855
807
 
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);
862
814
                ctx->noop = 1;
863
815
            }
 
816
            else {
 
817
                if (apr_xlate_sb_get(ctx->xlate, &ctx->is_sb) != APR_SUCCESS) {
 
818
                    ctx->is_sb = 0;
 
819
                }
 
820
            }
864
821
        }
865
822
        else {
866
 
                ctx->noop = 1;
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",
870
 
                                  mime_type);
 
823
            ctx->noop = 1;
 
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",
 
827
                              mime_type);
871
828
            }
 
829
        }
872
830
    }
873
831
 
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)");
880
838
    }
881
839
 
882
840
    if (!ctx->ran) {  /* filter never ran before */
883
841
        chk_filter_chain(f);
884
842
        ctx->ran = 1;
 
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.
 
846
             */
 
847
            apr_table_unset(f->r->headers_out, "Content-Length");
 
848
        }
885
849
    }
886
850
 
887
851
    if (ctx->noop) {
1040
1004
    if (!ctx->ran) {  /* filter never ran before */
1041
1005
        chk_filter_chain(f);
1042
1006
        ctx->ran = 1;
 
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
 
1012
             * some modules.
 
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.
 
1017
             */
 
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");
 
1022
            }
 
1023
        }
1043
1024
    }
1044
1025
 
1045
1026
    if (ctx->noop) {