httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n.@apache.org
Subject cvs commit: httpd-2.0/modules/mappers mod_negotiation.c
Date Tue, 27 May 2003 20:35:47 GMT
nd          2003/05/27 13:35:47

  Modified:    .        Tag: APACHE_2_0_BRANCH CHANGES STATUS
               modules/mappers Tag: APACHE_2_0_BRANCH mod_negotiation.c
  Log:
  [Not sure whether this will be included in 2.0.46, adjust CHANGES if necessary]
  
  Introduce "prefer-language" environment variable,
  which allows to influence the negotiation process on request basis
  to prefer a certain language, e.g.:
  
  SetEnvIf Request_URI ^/manual/foo/ prefer-language=foo
  
  Reviewed by: Jeff Trawick, Will Rowe, Erik Abele
  
  Revision  Changes    Path
  No                   revision
  
  
  No                   revision
  
  
  1.988.2.111 +4 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.988.2.110
  retrieving revision 1.988.2.111
  diff -u -r1.988.2.110 -r1.988.2.111
  --- CHANGES	21 May 2003 15:47:00 -0000	1.988.2.110
  +++ CHANGES	27 May 2003 20:35:45 -0000	1.988.2.111
  @@ -1,5 +1,9 @@
   Changes with Apache 2.0.46
   
  +  *) mod_negotiation: Introduce "prefer-language" environment variable,
  +     which allows to influence the negotiation process on request basis
  +     to prefer a certain language.  [André Malo]
  +
     *) Fix for mod_dav.  Call the 'can_be_activity' callback, if provided,
        when a MKACTIVITY request comes in.
        [Ben Collins-Sussman <sussman@collab.net>]
  
  
  
  1.751.2.316 +1 -25     httpd-2.0/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/STATUS,v
  retrieving revision 1.751.2.315
  retrieving revision 1.751.2.316
  diff -u -r1.751.2.315 -r1.751.2.316
  --- STATUS	27 May 2003 16:19:36 -0000	1.751.2.315
  +++ STATUS	27 May 2003 20:35:46 -0000	1.751.2.316
  @@ -105,30 +105,6 @@
         modules/metadata/mod_setenvif.c r1.42
         +1: nd
   
  -    * port the "prefer-language" env variable.
  -      there are docs online with explanations what it does:
  -      <http://httpd.apache.org/docs-2.1/env.html#prefer-language>
  -      <http://httpd.apache.org/docs-2.1/content-negotiation.html#exceptions>
  -        (last paragraph)
  -      This feature would allow us to set up a resaonable (and distributable)
  -      config for our multilingual documentation with crosslinks between the
  -      languages, such as:
  -        Alias /manual    /path/to/manual
  -        Alias /manual/en /path/to/manual
  -        Alias /manual/de /path/to/manual
  -        SetEnvIf Request_URI ^/manual/en/ prefer-language=en
  -        SetEnvIf Request_URI ^/manual/de/ prefer-language=de
  -        :
  -      (but with regexps, see the backport proposal above). We're going to
  -      get a clever system for choosing the  language either by user's choice
  -      or language negotiation. If user's choice doesn't exist, it falls back
  -      to negotiation again.
  -      (There's a somewhat outdated example for such cross language links:
  -       <http://test.perlig.de/manual/>, done with mod_rewrite, waiting for
  -       mod_negotiation enhancement ;-))
  -      modules/mappers/mod_negotiation.c r1.110,r1.115
  -      +1: nd, trawick, wrowe
  -
       * Allow mod_dav to do weak entity comparison functions.
         modules/dav/main/util.c: r1.45
         [ This one is under review.  Don't merge.  ]
  
  
  
  No                   revision
  
  
  No                   revision
  
  
  1.108.2.4 +105 -45   httpd-2.0/modules/mappers/mod_negotiation.c
  
  Index: mod_negotiation.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/mappers/mod_negotiation.c,v
  retrieving revision 1.108.2.3
  retrieving revision 1.108.2.4
  diff -u -r1.108.2.3 -r1.108.2.4
  --- mod_negotiation.c	1 Mar 2003 21:36:19 -0000	1.108.2.3
  +++ mod_negotiation.c	27 May 2003 20:35:47 -0000	1.108.2.4
  @@ -2202,74 +2202,134 @@
       return 1;
   }
   
  +/* figure out, whether a variant is in a specific language
  + * it returns also false, if the variant has no language.
  + */
  +static int variant_has_language(var_rec *variant, const char *lang)
  +{
  +    int j, max;
  +
  +    /* fast exit */
  +    if (   !lang
  +        || !variant->content_languages
  +        || !(max = variant->content_languages->nelts)) {
  +        return 0;
  +    }
  +
  +    for (j = 0; j < max; ++j) {
  +        if (!strcmp(lang,
  +                    ((char **) (variant->content_languages->elts))[j])) {
  +            return 1;
  +        }
  +    }
  +
  +    return 0;
  +}
  +
   static int best_match(negotiation_state *neg, var_rec **pbest)
   {
       int j;
  -    var_rec *best = NULL;
  +    var_rec *best;
       float bestq = 0.0f;
       enum algorithm_results algorithm_result;
   
       var_rec *avail_recs = (var_rec *) neg->avail_vars->elts;
   
  +    const char *preferred_language = apr_table_get(neg->r->subprocess_env,
  +                                                   "prefer-language");
  +
       set_default_lang_quality(neg);
   
       /*
  -     * Find the 'best' variant
  +     * Find the 'best' variant 
  +     * We run the loop possibly twice: if "prefer-language"
  +     * environment variable is set but we did not find an appropriate
  +     * best variant. In that case forget the preferred language and
  +     * negotiate over all variants.
        */
   
  -    for (j = 0; j < neg->avail_vars->nelts; ++j) {
  -        var_rec *variant = &avail_recs[j];
  +    do {
  +        best = NULL;
   
  -        /* Find all the relevant 'quality' values from the
  -         * Accept... headers, and store in the variant.  This also
  -         * prepares for sending an Alternates header etc so we need to
  -         * do it even if we do not actually plan to find a best
  -         * variant.
  -         */
  -        set_accept_quality(neg, variant);
  -        set_language_quality(neg, variant);
  -        set_encoding_quality(neg, variant);
  -        set_charset_quality(neg, variant);
  -
  -        /* Only do variant selection if we may actually choose a
  -         * variant for the client
  -         */
  -        if (neg->may_choose) {
  -
  -            /* Now find out if this variant is better than the current
  -             * best, either using the RVSA/1.0 algorithm, or Apache's
  -             * internal server-driven algorithm. Presumably other
  -             * server-driven algorithms are possible, and could be
  -             * implemented here.
  +        for (j = 0; j < neg->avail_vars->nelts; ++j) {
  +            var_rec *variant = &avail_recs[j];
  +
  +            /* if a language is preferred, but the current variant
  +             * is not in that language, then drop it for now
                */
  +            if (   preferred_language
  +                && !variant_has_language(variant, preferred_language)) {
  +                continue;
  +            }
   
  -            if (neg->use_rvsa) {
  -                if (is_variant_better_rvsa(neg, variant, best, &bestq)) {
  -                    best = variant;
  -                }
  +            /* Find all the relevant 'quality' values from the
  +             * Accept... headers, and store in the variant.  This also
  +             * prepares for sending an Alternates header etc so we need to
  +             * do it even if we do not actually plan to find a best
  +             * variant.  
  +             */
  +            set_accept_quality(neg, variant);
  +            /* accept the preferred language, even when it's not listed within
  +             * the Accept-Language header
  +             */
  +            if (preferred_language) {
  +                variant->lang_quality = 1.0f;
  +                variant->definite = 1;
               }
               else {
  -                if (is_variant_better(neg, variant, best, &bestq)) {
  -                    best = variant;
  +                set_language_quality(neg, variant);
  +            }
  +            set_encoding_quality(neg, variant);
  +            set_charset_quality(neg, variant);
  +
  +            /* Only do variant selection if we may actually choose a
  +             * variant for the client 
  +             */
  +            if (neg->may_choose) {
  +
  +                /* Now find out if this variant is better than the current
  +                 * best, either using the RVSA/1.0 algorithm, or Apache's
  +                 * internal server-driven algorithm. Presumably other
  +                 * server-driven algorithms are possible, and could be
  +                 * implemented here.
  +                 */
  +     
  +                if (neg->use_rvsa) {
  +                    if (is_variant_better_rvsa(neg, variant, best, &bestq)) {
  +                        best = variant;
  +                    }
  +                }
  +                else {
  +                    if (is_variant_better(neg, variant, best, &bestq)) {
  +                        best = variant;
  +                    }
                   }
               }
           }
  -    }
   
  -    /* We now either have a best variant, or no best variant */
  +        /* We now either have a best variant, or no best variant */
   
  -    if (neg->use_rvsa)    {
  -        /* calculate result for RVSA/1.0 algorithm:
  -         * only a choice response if the best variant has q>0
  -         * and is definite
  -         */
  -        algorithm_result = (best && best->definite) && (bestq > 0)
?
  -                           alg_choice : alg_list;
  -    }
  -    else {
  -        /* calculate result for Apache negotiation algorithm */
  -        algorithm_result = bestq > 0 ? alg_choice : alg_list;
  -    }
  +        if (neg->use_rvsa)    {
  +            /* calculate result for RVSA/1.0 algorithm:
  +             * only a choice response if the best variant has q>0
  +             * and is definite
  +             */
  +            algorithm_result = (best && best->definite) && (bestq >
0) ?
  +                                alg_choice : alg_list;
  +        }
  +        else {
  +            /* calculate result for Apache negotiation algorithm */
  +            algorithm_result = bestq > 0 ? alg_choice : alg_list;        
  +        }
  +
  +        /* run the loop again, if the "prefer-language" got no clear result */
  +        if (preferred_language && (!best || algorithm_result != alg_choice)) {
  +            preferred_language = NULL;
  +            continue;
  +        }
  +
  +        break;
  +    } while (1);
   
       /* Returning a choice response with a non-neighboring variant is a
        * protocol security error in TCN (see rfc2295).  We do *not*
  
  
  

Mime
View raw message