Lines Matching refs:variant

183  * Record of available info on a particular variant
198 * makes the variant non-definite according to the rules
208 apr_array_header_t *content_languages; /* list of lang. for this variant */
213 * of negotiation for this variant. They are obtained from the
215 * is obtained from the variant itself (the 'qs' parameter value
216 * from the variant's mime-type). Apart from source_quality,
217 * these values are set when we find the quality for each variant
219 * of the variant description or mime type: see set_mime_fields().
221 float lang_quality; /* quality of this variant's language */
225 float source_quality; /* source quality for this variant */
233 /* Above are all written-once properties of the variant. The
271 int may_choose; /* 1 if we may choose a variant for the client */
305 /* Initializing the relevant fields of a variant record from the
321 /* Create a variant list validator in r using info from vlistr. */
325 /* Calculating the variant list validator is similar to
326 * calculating an etag for the source of the variant list
536 * return an array containing the languages of this variant
673 /* we may use any variant selection algorithm, configure
758 /* If blank, just return it --- this ends information on this variant */
1082 /* Second key is the variant name */
1265 /* Have reasonable variant --- gather notes. */
1371 * return is the variant at the highest level that the client explicitly
1433 * which is called for each variant. It sets two elements in the
1434 * variant record:
1442 * When we do the variant checking for best variant, we use language
1494 var_rec *variant = &avail_recs[j];
1495 if (variant->content_languages &&
1496 variant->content_languages->nelts) {
1506 /* Set the language_quality value in the variant record. Also
1512 * header which matches the language of this variant either fully,
1517 * When a variant has multiple languages, we find the 'best'
1518 * match for each variant language tag as above, then select the
1520 * and variant can have multiple languages, we now have a hairy
1523 * If the variant has no language and we have no Accept-Language
1526 * If the variant has no language, we use the default as set by
1537 static void set_language_quality(negotiation_state *neg, var_rec *variant)
1544 if (!variant->content_languages || !variant->content_languages->nelts) {
1545 /* This variant has no content-language, so use the default
1552 variant->lang_quality = neg->default_lang_quality;
1562 * variant description looking for a match on the
1565 * best q value from all the languages on the variant
1570 /* no accept-language header makes the variant indefinite */
1571 variant->definite = 0;
1583 for (j = 0; j < variant->content_languages->nelts; ++j) {
1588 /* lang is the variant's language-tag, which is the one
1591 lang = ((char **) (variant->content_languages->elts))[j];
1607 /* Find language. We match if either the variant
1609 * from the accept header, or a prefix of the variant
1618 * header the best match for the variant language tag
1676 /* If one of the language tags of the variant matched on *, we
1678 * on any other tag of the variant. If so the * match takes
1685 variant->definite = 0;
1688 variant->lang_quality = best ? best->quality : fiddle_q;
1697 && (variant->lang_index < 0))
1699 && !variant->lang_quality))
1704 for (j = 0; j < variant->content_languages->nelts; ++j)
1706 /* lang is the variant's language-tag, which is the one
1709 char *lang = ((char **) (variant->content_languages->elts))[j];
1722 if (variant->lang_quality) {
1724 variant->lang_index = bestidx;
1729 variant->lang_index = bestidx;
1730 variant->lang_quality = .0001f;
1731 variant->definite = 0;
1743 static apr_off_t find_content_length(negotiation_state *neg, var_rec *variant)
1747 if (variant->bytes < 0) {
1748 if ( variant->sub_req
1749 && (variant->sub_req->finfo.valid & APR_FINFO_SIZE)) {
1750 variant->bytes = variant->sub_req->finfo.size;
1754 variant->file_name);
1758 variant->bytes = statb.size;
1763 return variant->bytes;
1766 /* For a given variant, find the best matching Accept: header
1768 * mime_type_quality field of the variant, for later use in
1769 * determining the best matching variant.
1772 static void set_accept_quality(negotiation_state *neg, var_rec *variant)
1786 if (variant->mime_type && *variant->mime_type)
1787 variant->definite = 0;
1795 * looking for the 'best' match with this variant's
1797 * value (from the Accept: header) for this variant's
1809 prev_mime_stars = variant->mime_stars;
1811 if (!mime_match(type, variant)) {
1818 if (prev_mime_stars == variant->mime_stars) {
1830 variant->mime_stars == 1) {
1834 variant->mime_stars == 2) {
1841 q_definite = (variant->mime_stars == 3);
1843 variant->mime_type_quality = q;
1844 variant->definite = variant->definite && q_definite;
1848 /* For a given variant, find the 'q' value of the charset given
1852 static void set_charset_quality(negotiation_state *neg, var_rec *variant)
1856 const char *charset = variant->content_charset;
1864 variant->definite = 0;
1871 /* Charset of variant not known */
1874 if (!(!strncmp(variant->mime_type, "text/", 5)
1875 || !strcmp(variant->mime_type, INCLUDES_MAGIC_TYPE)
1876 || !strcmp(variant->mime_type, INCLUDES_MAGIC_TYPE3)
1882 * in the variant list or content-location headers.
1892 * looking for a match with this variant's charset. If none
1900 variant->charset_quality = type->quality;
1909 variant->charset_quality = star->quality;
1910 variant->definite = 0;
1913 /* If this variant is in charset iso-8859-1, the default is 1.0 */
1915 variant->charset_quality = 1.0f;
1918 variant->charset_quality = 0.0f;
1935 * variant is acceptable for the user-agent.
1939 * variant with no encoding should be preferred.
1945 static void set_encoding_quality(negotiation_state *neg, var_rec *variant)
1948 const char *enc = variant->content_encoding;
1959 variant->encoding_quality = 1.0f;
1961 variant->encoding_quality = 0.5f;
1988 variant->encoding_quality = accept_recs[i].quality;
1999 variant->encoding_quality = star->quality;
2006 variant->encoding_quality = value_if_not_found;
2010 * Possible results of the variant selection algorithm
2013 alg_choice = 1, /* choose variant */
2019 * of the variant selection algorithm. alg_list means that no best
2020 * variant was found by the algorithm, alg_choice means that a best
2021 * variant was found and should be returned. The list/choice
2023 * way here. The best variant is returned in *pbest. best_match has
2024 * two possible algorithms for determining the best variant: the
2031 * language, charset, etc quality for _every_ variant. This is needed
2040 static int is_variant_better_rvsa(negotiation_state *neg, var_rec *variant,
2048 if (variant->encoding_quality == 0.0f)
2051 q = variant->mime_type_quality *
2052 variant->source_quality *
2053 variant->charset_quality *
2054 variant->lang_quality;
2070 (variant->file_name ? variant->file_name : ""),
2071 (variant->mime_type ? variant->mime_type : ""),
2072 (variant->content_languages
2073 ? apr_array_pstrcat(neg->pool, variant->content_languages, ',')
2075 variant->source_quality,
2076 variant->mime_type_quality,
2077 variant->lang_quality,
2078 variant->charset_quality,
2079 variant->encoding_quality,
2081 variant->definite);
2092 /* If the best variant's encoding is of lesser quality than
2093 * this variant, then we prefer this variant
2095 if (variant->encoding_quality > best->encoding_quality) {
2107 static int is_variant_better(negotiation_state *neg, var_rec *variant,
2119 * This variant is worse than current best: return 0
2120 * This variant is better than the current best:
2121 * assign this variant's q to *p_bestq, and return 1
2122 * This variant is just as desirable as the current best:
2132 /* First though, eliminate this variant if it is not
2140 (variant->file_name ? variant->file_name : ""),
2141 (variant->mime_type ? variant->mime_type : ""),
2142 (variant->content_languages
2143 ? apr_array_pstrcat(neg->pool, variant->content_languages, ',')
2145 variant->source_quality,
2146 variant->mime_type_quality,
2147 variant->lang_quality,
2148 variant->lang_index,
2149 variant->charset_quality,
2150 variant->encoding_quality);
2153 if (variant->encoding_quality == 0.0f ||
2154 variant->lang_quality == 0.0f ||
2155 variant->source_quality == 0.0f ||
2156 variant->charset_quality == 0.0f ||
2157 variant->mime_type_quality == 0.0f) {
2161 q = variant->mime_type_quality * variant->source_quality;
2171 if (variant->lang_quality < best->lang_quality) {
2174 if (variant->lang_quality > best->lang_quality) {
2181 (variant->lang_index == -1 || variant->lang_index > best->lang_index)) {
2184 if (variant->lang_index != -1 &&
2185 (best->lang_index == -1 || variant->lang_index < best->lang_index)) {
2193 levcmp = level_cmp(variant, best);
2203 if (variant->charset_quality < best->charset_quality) {
2206 /* If the best variant's charset is ISO-8859-1 and this variant has
2207 * the same charset quality, then we prefer this variant
2210 if (variant->charset_quality > best->charset_quality ||
2211 ((variant->content_charset != NULL &&
2212 *variant->content_charset != '\0' &&
2213 strcmp(variant->content_charset, "iso-8859-1") != 0) &&
2223 if (variant->encoding_quality < best->encoding_quality) {
2226 if (variant->encoding_quality > best->encoding_quality) {
2232 if (find_content_length(neg, variant) >= find_content_length(neg, best)) {
2237 * we have a shorter content length, so use this variant
2243 /* figure out, whether a variant is in a specific language
2244 * it returns also false, if the variant has no language.
2246 static int variant_has_language(var_rec *variant, const char *lang)
2252 || !variant->content_languages
2253 || !(max = variant->content_languages->nelts)) {
2259 ((char **) (variant->content_languages->elts))[j])) {
2271 static int discard_variant_by_env(var_rec *variant, int discard)
2273 if ( is_identity_encoding(variant->content_encoding)
2274 || !strcmp(variant->content_encoding, "identity")) {
2280 && (!variant->mime_type
2281 || strncmp(variant->mime_type, "text/html", 9))));
2320 * Find the 'best' variant
2323 * best variant. In that case forget the preferred language and
2331 var_rec *variant = &avail_recs[j];
2333 /* if this variant is encoded somehow and there are special
2337 && discard_variant_by_env(variant, may_discard)) {
2341 /* if a language is preferred, but the current variant
2345 && !variant_has_language(variant, preferred_language)) {
2350 * Accept... headers, and store in the variant. This also
2353 * variant.
2355 set_accept_quality(neg, variant);
2360 variant->lang_quality = 1.0f;
2361 variant->definite = 1;
2364 set_language_quality(neg, variant);
2366 set_encoding_quality(neg, variant);
2367 set_charset_quality(neg, variant);
2369 /* Only do variant selection if we may actually choose a
2370 * variant for the client
2374 /* Now find out if this variant is better than the current
2382 if (is_variant_better_rvsa(neg, variant, best, &bestq)) {
2383 best = variant;
2387 if (is_variant_better(neg, variant, best, &bestq)) {
2388 best = variant;
2394 /* We now either have a best variant, or no best variant */
2398 * only a choice response if the best variant has q>0
2418 /* Returning a choice response with a non-neighboring variant is a
2420 * verify here that the variant and URI are neighbors, even though
2469 * fill it with the variant list, and then concatenate the entire array.
2484 var_rec *variant = &avail_recs[j];
2486 if (variant->content_languages && variant->content_languages->nelts) {
2487 lang = apr_array_pstrcat(r->pool, variant->content_languages, ',');
2496 sample_type = variant->mime_type;
2497 sample_charset = variant->content_charset;
2499 sample_encoding = variant->content_encoding;
2504 variant->mime_type ? variant->mime_type : "")) {
2509 variant->content_charset ?
2510 variant->content_charset : "")) {
2520 variant->content_encoding ?
2521 variant->content_encoding : "")) {
2533 *((const char **) apr_array_push(arr)) = ap_escape_path_segment(r->pool, variant->file_name);
2537 apr_snprintf(qstr, 6, "%1.3f", variant->source_quality);
2551 if (variant->mime_type && *variant->mime_type) {
2553 *((const char **) apr_array_push(arr)) = variant->mime_type;
2556 if (variant->content_charset && *variant->content_charset) {
2558 *((const char **) apr_array_push(arr)) = variant->content_charset;
2566 if (variant->content_encoding && *variant->content_encoding) {
2570 *((const char **) apr_array_push(arr)) = variant->content_encoding;
2579 * If the variant is a CGI script, find_content_length would
2585 * get the variant from a type map. This needs to be fixed
2589 if (!(variant->sub_req && variant->sub_req->handler)
2590 && (len = find_content_length(neg, variant)) >= 0) {
2639 * fill it with the variant list, and then concatenate the entire array.
2646 var_rec *variant = &((var_rec *) neg->avail_vars->elts)[i];
2647 const char *filename = variant->file_name ? variant->file_name : "";
2648 apr_array_header_t *languages = variant->content_languages;
2649 const char *description = variant->description
2650 ? variant->description
2665 if (variant->mime_type && *variant->mime_type) {
2667 *((const char **) apr_array_push(arr)) = variant->mime_type;
2674 if (variant->content_charset && *variant->content_charset) {
2676 *((const char **) apr_array_push(arr)) = variant->content_charset;
2678 if (variant->content_encoding) {
2680 *((const char **) apr_array_push(arr)) = variant->content_encoding;
2692 apr_table_setn(r->notes, "variant-list", make_variant_list(r, neg));
2695 apr_table_setn(r->main->notes, "variant-list",
2700 /* Called if we got a "Choice" response from the variant selection algorithm.
2701 * It checks the result of the chosen variant to see if it
2707 var_rec *variant)
2712 if (!variant->sub_req) {
2715 sub_req = ap_sub_req_lookup_file(variant->file_name, r, r->output_filters);
2723 variant->sub_req = sub_req;
2726 sub_req = variant->sub_req;
2729 /* The variant selection algorithm told us to return a "Choice"
2730 * response. This is the normal variant response, with
2732 * variant did or will not itself engage in transparent negotiation.
2734 * the normal variant handling
2738 * transparent multiviews resource as the best variant.
2742 * variant, because we can generate a legal negotiation response
2757 * selects, as the best variant, another type map which itself
2777 * variant list validators.
2807 ap_escape_path_segment(r->pool, variant->file_name));
2825 int alg_result; /* result of variant selection algorithm */
2846 var_rec *variant = &avail_recs[j];
2850 * non-neighboring variant. We can have a non-neighboring
2851 * variant when processing a type map.
2853 if (ap_strchr_c(variant->file_name, '/'))
2857 * of variant typemap bodies.
2859 if (variant->body) {
2877 * alg_choice: a best variant is chosen
2878 * alg_list: no best variant is chosen
2907 "no acceptable variant: %s", r->filename);
2912 /* Variant selection chose a variant */
3103 var_rec *variant = &avail_recs[j];
3104 if (variant->sub_req) {
3105 ap_destroy_sub_req(variant->sub_req);
3145 /* clean up all but our favorite variant, since that sub_req
3150 var_rec *variant = &avail_recs[j];
3151 if (variant != best && variant->sub_req) {
3152 ap_destroy_sub_req(variant->sub_req);