⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod_negotiation.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 5 页
字号:
/* ==================================================================== * Copyright (c) 1995-1998 The Apache Group.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the Apache Group *    for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    apache@apache.org. * * 5. Products derived from this software may not be called "Apache" *    nor may "Apache" appear in their names without prior written *    permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the Apache Group *    for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * *//* * mod_negotiation.c: keeps track of MIME types the client is willing to * accept, and contains code to handle type arbitration. * * rst */#include "httpd.h"#include "http_config.h"#include "http_request.h"#include "http_core.h"#include "http_log.h"#include "util_script.h"/* define TCN_02 to allow for Holtman I-D transparent negotiation. * This file currently implements the draft-02, except for * anything to do with features and cache-control (max-age etc) * * Since the draft is just that, and we don't yet implement * everything, regard the transparent negotiation stuff as experimental. *//*#define TCN_02 *//* Commands --- configuring document caching on a per (virtual?) * server basis...  */typedef struct {    array_header *language_priority;} neg_dir_config;module MODULE_VAR_EXPORT negotiation_module;static char *merge_string_array(pool *p, array_header *arr, char *sep){    int i;    char *t = "";    for (i = 0; i < arr->nelts; i++) {        t = ap_pstrcat(p, t, (i ? sep : ""), ((char **) arr->elts)[i], NULL);    }    return t;}static void *create_neg_dir_config(pool *p, char *dummy){    neg_dir_config *new = (neg_dir_config *) ap_palloc(p, sizeof(neg_dir_config));    new->language_priority = ap_make_array(p, 4, sizeof(char *));    return new;}static void *merge_neg_dir_configs(pool *p, void *basev, void *addv){    neg_dir_config *base = (neg_dir_config *) basev;    neg_dir_config *add = (neg_dir_config *) addv;    neg_dir_config *new = (neg_dir_config *) ap_palloc(p, sizeof(neg_dir_config));    /* give priority to the config in the subdirectory */    new->language_priority = ap_append_arrays(p, add->language_priority,                                           base->language_priority);    return new;}static const char *set_language_priority(cmd_parms *cmd, void *n, char *lang){    array_header *arr = ((neg_dir_config *) n)->language_priority;    char **langp = (char **) ap_push_array(arr);    *langp = lang;    return NULL;}static const char *cache_negotiated_docs(cmd_parms *cmd, void *dummy,                                         char *dummy2){    void *server_conf = cmd->server->module_config;    ap_set_module_config(server_conf, &negotiation_module, "Cache");    return NULL;}static int do_cache_negotiated_docs(server_rec *s){    return (ap_get_module_config(s->module_config, &negotiation_module) != NULL);}static const command_rec negotiation_cmds[] ={    {"CacheNegotiatedDocs", cache_negotiated_docs, NULL, RSRC_CONF, NO_ARGS,     "no arguments (either present or absent)"},    {"LanguagePriority", set_language_priority, NULL, OR_FILEINFO, ITERATE,     "space-delimited list of MIME language abbreviations"},    {NULL}};/* * Record of available info on a media type specified by the client * (we also use 'em for encodings and languages) */typedef struct accept_rec {    char *type_name;		/* MUST be lowercase */    float quality;    float max_bytes;    float level;    char *charset;              /* for content-type only */} accept_rec;/* * Record of available info on a particular variant * * Note that a few of these fields are updated by the actual negotiation * code.  These are: * * level_matched --- initialized to zero.  Set to the value of level *             if the client actually accepts this media type at that *             level (and *not* if it got in on a wildcard).  See level_cmp *             below. */typedef struct var_rec {    request_rec *sub_req;       /* May be NULL (is, for map files) */    char *type_name;		/* MUST be lowercase */    char *file_name;    const char *content_encoding;    array_header *content_languages;    /* list of languages for this variant */    char *content_charset;    char *description;    /* The next five items give the quality values for the dimensions     * of negotiation for this variant. They are obtained from the     * appropriate header lines, except for accept_type_quality, which     * is obtained from the variant itself (the 'qs' parameter value     * from the variant's mime-type). Apart from type_quality,     * these values are set when we find the quality for each variant     * (see best_match()). type_quality is set from the 'qs' parameter     * of the variant description or mime type: see set_mime_fields().     */    float lang_quality;         /* quality of this variant's language */    int encoding_quality;       /* ditto encoding (1 or 0 only) */    float charset_quality;      /* ditto charset */    float accept_type_quality;  /* ditto media type */    float type_quality;         /* quality of source for this type */    /* Now some special values */    float level;                /* Auxiliary to content-type... */    float bytes;                /* content length, if known */    int lang_index;             /* pre HTTP/1.1 language priority stuff */    int is_pseudo_html;         /* text/html, *or* the INCLUDES_MAGIC_TYPEs */    /* Above are all written-once properties of the variant.  The     * three fields below are changed during negotiation:     */    float level_matched;    int mime_stars;    int definite;} var_rec;/* Something to carry around the state of negotiation (and to keep * all of this thread-safe)... */typedef struct {    pool *pool;    request_rec *r;    char *dir_name;    int accept_q;               /* 1 if an Accept item has a q= param */    float default_lang_quality; /* fiddle lang q for variants with no lang */    array_header *accepts;      /* accept_recs */    int have_accept_header;     /* 1 if Accept-Header present */    array_header *accept_encodings;     /* accept_recs */    array_header *accept_charsets;      /* accept_recs */    array_header *accept_langs; /* accept_recs */    array_header *avail_vars;   /* available variants */    int count_multiviews_variants;      /* number of variants found on disk */    int ua_can_negotiate;       /* 1 if ua can do transparent negotiate */    int use_transparent_neg;    /* 1 if we are using transparent neg */    int short_accept_headers;   /* 1 if ua does trans neg & sent short accpt */} negotiation_state;/* A few functions to manipulate var_recs. * Cleaning out the fields... */static void clean_var_rec(var_rec *mime_info){    mime_info->sub_req = NULL;    mime_info->type_name = "";    mime_info->file_name = "";    mime_info->content_encoding = NULL;    mime_info->content_languages = NULL;    mime_info->content_charset = "";    mime_info->description = "";    mime_info->is_pseudo_html = 0;    mime_info->level = 0.0f;    mime_info->level_matched = 0.0f;    mime_info->bytes = 0.0f;    mime_info->lang_index = -1;    mime_info->mime_stars = 0;    mime_info->definite = 1;    mime_info->charset_quality = 1.0f;    mime_info->type_quality = 0.0f;    mime_info->encoding_quality = 1;    mime_info->lang_quality = 1.0f;    mime_info->accept_type_quality = 1.0f;}/* Initializing the relevant fields of a variant record from the * accept_info read out of its content-type, one way or another. */static void set_mime_fields(var_rec *var, accept_rec *mime_info){    var->type_name = mime_info->type_name;    var->type_quality = mime_info->quality;    var->level = mime_info->level;    var->content_charset = mime_info->charset;    var->is_pseudo_html = (!strcmp(var->type_name, "text/html")                           || !strcmp(var->type_name, INCLUDES_MAGIC_TYPE)                           || !strcmp(var->type_name, INCLUDES_MAGIC_TYPE3));}/***************************************************************** * * Parsing (lists of) media types and their parameters, as seen in * HTTPD header lines and elsewhere. *//* * Get a single mime type entry --- one media type and parameters; * enter the values we recognize into the argument accept_rec */static const char *get_entry(pool *p, accept_rec *result, const char *accept_line){    result->quality = 1.0f;    result->max_bytes = 0.0f;    result->level = 0.0f;    result->charset = "";    /*     * Note that this handles what I gather is the "old format",     *     *    Accept: text/html text/plain moo/zot     *     * without any compatibility kludges --- if the token after the     * MIME type begins with a semicolon, we know we're looking at parms,     * otherwise, we know we aren't.  (So why all the pissing and moaning     * in the CERN server code?  I must be missing something).     */    result->type_name = ap_get_token(p, &accept_line, 0);    ap_str_tolower(result->type_name);     /* You want case-insensitive,                                         * you'll *get* case-insensitive.                                         */    /* KLUDGE!!! Default HTML to level 2.0 unless the browser     * *explicitly* says something else.     */    if (!strcmp(result->type_name, "text/html") && (result->level == 0.0)) {        result->level = 2.0f;    }    else if (!strcmp(result->type_name, INCLUDES_MAGIC_TYPE)) {        result->level = 2.0f;    }    else if (!strcmp(result->type_name, INCLUDES_MAGIC_TYPE3)) {        result->level = 3.0f;    }    while (*accept_line == ';') {        /* Parameters ... */        char *parm;        char *cp;        char *end;        ++accept_line;        parm = ap_get_token(p, &accept_line, 1);        /* Look for 'var = value' --- and make sure the var is in lcase. */        for (cp = parm; (*cp && !ap_isspace(*cp) && *cp != '='); ++cp) {            *cp = ap_tolower(*cp);        }        if (!*cp) {            continue;           /* No '='; just ignore it. */        }        *cp++ = '\0';           /* Delimit var */        while (*cp && (ap_isspace(*cp) || *cp == '=')) {            ++cp;        }        if (*cp == '"') {            ++cp;            for (end = cp;                 (*end && *end != '\n' && *end != '\r' && *end != '\"');                 end++);        }        else {            for (end = cp; (*end && !ap_isspace(*end)); end++);        }        if (*end) {            *end = '\0';        /* strip ending quote or return */        }        ap_str_tolower(cp);        if (parm[0] == 'q'            && (parm[1] == '\0' || (parm[1] == 's' && parm[2] == '\0'))) {            result->quality = atof(cp);        }        else if (parm[0] == 'm' && parm[1] == 'x' &&                 parm[2] == 'b' && parm[3] == '\0') {            result->max_bytes = atof(cp);        }        else if (parm[0] == 'l' && !strcmp(&parm[1], "evel")) {            result->level = atof(cp);        }        else if (!strcmp(parm, "charset")) {            result->charset = cp;        }    }    if (*accept_line == ',') {        ++accept_line;    }    return accept_line;}/***************************************************************** *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -