httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@locus.apache.org
Subject cvs commit: apache-2.0/src/modules/experimental mod_charset_lite.c
Date Tue, 26 Sep 2000 15:08:31 GMT
trawick     00/09/26 08:08:28

  Modified:    src/modules/experimental mod_charset_lite.c
  Log:
  Sanity-check the use of multiple instances of XLATEOUT in a
  filter chain.  If the translation performed by an instance
  being run for the first time clashes with an instance already
  in place, disable the new instance.
  
  Revision  Changes    Path
  1.20      +108 -0    apache-2.0/src/modules/experimental/mod_charset_lite.c
  
  Index: mod_charset_lite.c
  ===================================================================
  RCS file: /home/cvs/apache-2.0/src/modules/experimental/mod_charset_lite.c,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- mod_charset_lite.c	2000/09/25 11:31:14	1.19
  +++ mod_charset_lite.c	2000/09/26 15:08:26	1.20
  @@ -119,9 +119,12 @@
    */
   typedef struct charset_filter_ctx_t {
       apr_xlate_t *xlate;
  +    charset_dir_t *dc;
       ees_t ees;              /* extended error status */
       apr_ssize_t saved;
       char buf[FATTEST_CHAR]; /* we want to be able to build a complete char here */
  +    int ran;                /* has filter instance run before? */
  +    int noop;               /* should we pass brigades through unchanged? */
   } charset_filter_ctx_t;
   
   /* charset_req_t is available via r->request_config if any translation is
  @@ -297,6 +300,7 @@
       output_ctx = (charset_filter_ctx_t *)(reqinfo + 1);
   
       reqinfo->dc = dc;
  +    output_ctx->dc = dc;
       ap_set_module_config(r->request_config, &charset_lite_module, reqinfo);
   
       reqinfo->output_ctx = output_ctx;
  @@ -317,6 +321,7 @@
            * of it.
            */
           input_ctx = apr_pcalloc(r->pool, sizeof(charset_filter_ctx_t));
  +        input_ctx->dc = dc;
           reqinfo->input_ctx = input_ctx;
           rv = apr_xlate_open(&input_ctx->xlate, dc->charset_source, 
                               dc->charset_default, r->pool);
  @@ -510,6 +515,100 @@
                     "%s", msg);
   }
   
  +/* chk_filter_chain() is called once per filter instance; it tries to
  + * determine if the current filter instance should be disabled because
  + * its translation is incompatible with the translation of an existing
  + * instance of the translate filter
  + *
  + * Example bad scenario:
  + *
  + *   configured filter chain for the request:
  + *     INCLUDES XLATEOUT(8859-1->UTS-16)
  + *   configured filter chain for the subrequest:
  + *     XLATEOUT(8859-1->UTS-16)
  + *
  + *   When the subrequest is processed, the filter chain will be
  + *     XLATEOUT(8859-1->UTS-16) XLATEOUT(8859-1->UTS-16)
  + *   This makes no sense, so the instance of XLATEOUT added for the
  + *   subrequest will be noop-ed.
  + *
  + * Example good scenario:
  + *
  + *   configured filter chain for the request:
  + *     INCLUDES XLATEOUT(8859-1->UTS-16)
  + *   configured filter chain for the subrequest:
  + *     XLATEOUT(IBM-1047->8859-1)
  + *
  + *   When the subrequest is processed, the filter chain will be
  + *     XLATEOUT(IBM-1047->8859-1) XLATEOUT(8859-1->UTS-16)
  + *   This makes sense, so the instance of XLATEOUT added for the
  + *   subrequest will be left alone and it will translate from
  + *   IBM-1047->8859-1.
  + */
  +static void chk_filter_chain(ap_filter_t *f)
  +{
  +    ap_filter_t *curf;
  +    charset_filter_ctx_t *curctx, *last_xlate_ctx = NULL;
  +    int debug = ((charset_filter_ctx_t *)f->ctx)->dc->debug == DEBUG;
  +
  +    /* walk the filter chain; see if it makes sense for our filter to
  +     * do any translation
  +     */
  +    curf = f->r->output_filters;
  +    while (curf) {
  +        if (!strcasecmp(curf->frec->name, XLATEOUT_FILTER_NAME) &&
  +            curf->ctx) {
  +            curctx = (charset_filter_ctx_t *)curf->ctx;
  +            if (!last_xlate_ctx) {
  +                last_xlate_ctx = curctx;
  +            }
  +            else {
  +                if (strcasecmp(last_xlate_ctx->dc->charset_default,
  +                               curctx->dc->charset_source)) {
  +                    /* incompatible translation 
  +                     * if our filter instance is incompatible with an instance
  +                     * already in place, noop our instance
  +                     * Notes: 
  +                     * . We are only willing to noop our own instance.
  +                     * . It is possible to noop another instance which has not
  +                     *   yet run, but this is not currently implemented.
  +                     *   Hopefully it will not be needed.
  +                     * . It is not possible to noop an instance which has 
  +                     *   already run.
  +                     */
  +                    if (last_xlate_ctx == f->ctx) {
  +                        last_xlate_ctx->noop = 1;
  +                        if (debug) {
  +                            ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO,
  +                                          0, f->r,
  +                                          "chk_filter_chain() - disabling "
  +                                          "translation %s->%s; existing "
  +                                          "translation %s->%s",
  +                                          last_xlate_ctx->dc->charset_source,
  +                                          last_xlate_ctx->dc->charset_default,
  +                                          curctx->dc->charset_source,
  +                                          curctx->dc->charset_default);
  +                        }
  +                    }
  +                    else {
  +                        ap_log_rerror(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO,
  +                                      0, f->r,
  +                                      "chk_filter_chain() - can't disable "
  +                                      "translation %s->%s; existing "
  +                                      "translation %s->%s",
  +                                      last_xlate_ctx->dc->charset_source,
  +                                      last_xlate_ctx->dc->charset_default,
  +                                      curctx->dc->charset_source,
  +                                      curctx->dc->charset_default);
  +                    }
  +                    break;
  +                }
  +            }
  +        }
  +        curf = curf->next;
  +    }
  +}
  +
   /* xlate_filter() handles (almost) arbitrary conversions from one charset 
    * to another...
    * translation is determined in the fixup hook (find_code_page), which is
  @@ -548,6 +647,15 @@
                        (unsigned)dc,
                        dc && dc->charset_source ? dc->charset_source : "(none)",
                        dc && dc->charset_default ? dc->charset_default : "(none)");
  +    }
  +
  +    if (!ctx->ran) {  /* filter never ran before */
  +        chk_filter_chain(f);
  +        ctx->ran = 1;
  +    }
  +
  +    if (ctx->noop) {
  +        return ap_pass_brigade(f->next, bb);
       }
   
       dptr = AP_BRIGADE_FIRST(bb);
  
  
  

Mime
View raw message