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

📄 proxy_cache.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* get etag */    if ((etag = ap_table_get(c->hdrs, "Etag"))) {        wetag = ap_pstrcat(r->pool, "W/", etag, NULL);    }    /* check for If-Match, If-Unmodified-Since */    while (1) {        /*         * check If-Match and If-Unmodified-Since exist         *          * If neither of these exist, the request is not conditional, and we         * serve it normally         */        if (!c->im && BAD_DATE == c->ius) {            break;        }        /*         * check If-Match         *          * we check if the Etag on the cached file is in the list of Etags in         * the If-Match field. The comparison must be a strong comparison, so         * the Etag cannot be marked as weak. If the comparision fails we         * return 412 Precondition Failed.         *          * if If-Match is specified AND If-Match is not a "*" AND Etag is         * missing or weak or not in the list THEN return 412 Precondition         * Failed         */        if (c->im) {            if (strcmp(c->im, "*") &&                (!etag || (strlen(etag) > 1 && 'W' == etag[0] && '/' == etag[1]) || !ap_proxy_liststr(c->im, etag, NULL))) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it didn't - return 412");            }            else {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Match specified, and it matched");                break;            }        }        /*         * check If-Unmodified-Since         *          * if If-Unmodified-Since is specified AND Last-Modified is specified         * somewhere AND If-Unmodified-Since is in the past compared to         * Last-Modified THEN return 412 Precondition Failed         */        if (BAD_DATE != c->ius && BAD_DATE != c->lmod) {            if (c->ius < c->lmod) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, but it wasn't - return 412");            }            else {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Unmodified-Since specified, and it was unmodified");                break;            }        }        /* if cache file is being updated */        if (c->origfp) {            ap_proxy_write_headers(c, c->resp_line, c->hdrs);            ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);            ap_proxy_cache_tidy(c);        }        else            ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use your cached copy, conditional precondition failed.");        return HTTP_PRECONDITION_FAILED;    }    /* check for If-None-Match, If-Modified-Since */    while (1) {        /*         * check for existance of If-None-Match and If-Modified-Since         *          * if neither of these headers have been set, then the request is not         * conditional, and we just send the cached response and be done with         * it.         */        if (!c->inm && BAD_DATE == c->ims) {            break;        }        /*         * check If-None-Match         *          * we check if the Etag on the cached file is in the list of Etags in         * the If-None-Match field. The comparison must be a strong         * comparison, so the Etag cannot be marked as weak. If the         * comparision fails we return 412 Precondition Failed.         *          * if If-None-Match is specified: if If-None-Match is a "*" THEN 304         * else if Etag is specified AND we get a match THEN 304 else if Weak         * Etag is specified AND we get a match THEN 304 else sent the         * original object         */        if (c->inm) {            if (!strcmp(c->inm, "*")) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: * specified, return 304");            }            else if (etag && ap_proxy_liststr(c->inm, etag, NULL)) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match: specified and we got a strong match - return 304");            }            else if (wetag && ap_proxy_liststr(c->inm, wetag, NULL)) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-None-Match specified, and we got a weak match - return 304");            }            else                break;        }        /*         * check If-Modified-Since         *          * if If-Modified-Since is specified AND Last-Modified is specified         * somewhere: if last modification date is earlier than         * If-Modified-Since THEN 304 else send the original object         */        if (BAD_DATE != c->ims && BAD_DATE != c->lmod) {            if (c->ims >= c->lmod) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "If-Modified-Since specified and not modified, try return 304");            }            else                break;        }        /* are we updating the cache file? */        if (c->origfp) {            ap_proxy_write_headers(c, c->resp_line, c->hdrs);            ap_proxy_send_fb(c->origfp, r, c, c->len, 1, 0, IOBUFSIZE);            ap_proxy_cache_tidy(c);        }        else            ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Use local copy, cached file hasn't changed");        return HTTP_NOT_MODIFIED;    }    /* No conditional - just send it cousin! */    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Local copy modified, send it");    r->status_line = strchr(c->resp_line, ' ') + 1;    r->status = c->status;    /* Prepare and send headers to client */    ap_proxy_table_replace(r->headers_out, c->hdrs);    /* make sure our X-Cache header does not stomp on a previous header */    ap_table_mergen(r->headers_out, "X-Cache", c->xcache);    /* content type is already set in the headers */    r->content_type = ap_table_get(r->headers_out, "Content-Type");    ap_send_http_header(r);    /* are we rewriting the cache file? */    if (c->origfp) {        ap_proxy_write_headers(c, c->resp_line, c->hdrs);        ap_proxy_send_fb(c->origfp, r, c, c->len, r->header_only, 0, IOBUFSIZE);        ap_proxy_cache_tidy(c);        return OK;    }    /* no, we not */    if (!r->header_only) {        ap_proxy_send_fb(cachefp, r, NULL, c->len, 0, 0, IOBUFSIZE);    }    else {        ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));    }    return OK;}/* * Call this to test for a resource in the cache * Returns DECLINED if we need to check the remote host * or an HTTP status code if successful * * Functions: *   if URL is cached then *      if cached file is not expired then *         if last modified after if-modified-since then send body *         else send 304 Not modified *      else if cached file is expired then *         if last modified after if-modified-since then add *            last modified date to request */int ap_proxy_cache_check(request_rec *r, char *url, struct cache_conf * conf,                             cache_req **cr){    const char *datestr, *pragma_req = NULL, *pragma_cresp = NULL, *cc_req = NULL,        *cc_cresp = NULL;    cache_req *c;    BUFF *cachefp;    int i;    void *sconf = r->server->module_config;    proxy_server_conf *pconf =    (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);    const char *agestr = NULL;    char *val;    time_t age_c = 0;    time_t age, maxage_req, maxage_cresp, maxage, smaxage, maxstale, minfresh;    c = ap_pcalloc(r->pool, sizeof(cache_req));    *cr = c;    c->req = r;    c->url = ap_pstrdup(r->pool, url);    c->filename = NULL;    c->tempfile = NULL;    c->fp = NULL;    c->origfp = NULL;    c->version = 0;    c->len = -1;    c->req_hdrs = NULL;    c->hdrs = NULL;    c->xcache = NULL;    /* get the If-Modified-Since date of the request, if it exists */    c->ims = BAD_DATE;    datestr = ap_table_get(r->headers_in, "If-Modified-Since");    if (datestr != NULL) {        /* this may modify the value in the original table */        datestr = ap_proxy_date_canon(r->pool, datestr);        c->ims = ap_parseHTTPdate(datestr);        if (c->ims == BAD_DATE) /* bad or out of range date; remove it */            ap_table_unset(r->headers_in, "If-Modified-Since");    }/* get the If-Unmodified-Since date of the request, if it exists */    c->ius = BAD_DATE;    datestr = ap_table_get(r->headers_in, "If-Unmodified-Since");    if (datestr != NULL) {        /* this may modify the value in the original table */        datestr = ap_proxy_date_canon(r->pool, datestr);        c->ius = ap_parseHTTPdate(datestr);        if (c->ius == BAD_DATE) /* bad or out of range date; remove it */            ap_table_unset(r->headers_in, "If-Unmodified-Since");    }/* get the If-Match of the request, if it exists */    c->im = ap_table_get(r->headers_in, "If-Match");/* get the If-None-Match of the request, if it exists */    c->inm = ap_table_get(r->headers_in, "If-None-Match");/* find the filename for this cache entry */    if (conf->root != NULL) {        char hashfile[66];        ap_proxy_hash(url, hashfile, pconf->cache.dirlevels, pconf->cache.dirlength);        c->filename = ap_pstrcat(r->pool, conf->root, "/", hashfile, NULL);    }    else {        c->filename = NULL;        c->fp = NULL;        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "No CacheRoot, so no caching. Declining.");        return DECLINED;    }/* find certain cache controlling headers */    pragma_req = ap_table_get(r->headers_in, "Pragma");    cc_req = ap_table_get(r->headers_in, "Cache-Control");/* first things first - does the request allow us to return * cached information at all? If not, just decline the request. * * Note that there is a big difference between not being allowed * to cache a request (no-store) and not being allowed to return * a cached request without revalidation (max-age=0). * * Caching is forbidden under the following circumstances: * * - RFC2616 14.9.2 Cache-Control: no-store * we are not supposed to store this request at all. Behave as a tunnel. * */    if (ap_proxy_liststr(cc_req, "no-store", NULL)) {/* delete the previously cached file */        if (c->filename)            unlink(c->filename);        c->fp = NULL;        c->filename = NULL;        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "no-store forbids caching. Declining.");        return DECLINED;    }/* if the cache file exists, open it */    cachefp = NULL;    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Request for %s, pragma_req=%s, ims=%ld", url,                 (pragma_req == NULL) ? "(unset)" : pragma_req, c->ims);/* find out about whether the request can access the cache */    if (c->filename != NULL && r->method_number == M_GET &&        strlen(url) < 1024) {        cachefp = ap_proxy_open_cachefile(r, c->filename);    }    /*     * if a cache file exists, try reading body and headers from cache file     */    if (cachefp != NULL) {        i = rdcache(r, cachefp, c);        if (i == -1)            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,                          "proxy: error reading cache file %s",                          c->filename);        else if (i == 0)            ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, r,                          "proxy: bad (short?) cache file: %s", c->filename);        if (i != 1) {            ap_pclosef(r->pool, ap_bfileno(cachefp, B_WR));            cachefp = NULL;        }        if (c->hdrs) {            cc_cresp = ap_table_get(c->hdrs, "Cache-Control");            pragma_cresp = ap_table_get(c->hdrs, "Pragma");            if ((agestr = ap_table_get(c->hdrs, "Age"))) {                age_c = atoi(agestr);            }        }    }    /* if a cache file does not exist, create empty header array *//* fixed?  in this case, we want to get the headers from the remote server   it will be handled later if we don't do this (I hope ;-)    if (cachefp == NULL)        c->hdrs = ap_make_table(r->pool, 20);*/    /* FIXME: Shouldn't we check the URL somewhere? */    /*     * Check Content-Negotiation - Vary     *      * At this point we need to make sure that the object we found in the cache     * is the same object that would be delivered to the client, when the     * effects of content negotiation are taken into effect.     *      * In plain english, we want to make sure that a language-negotiated     * document in one language is not given to a client asking for a     * language negotiated document in a different language by mistake.     *      * RFC2616 13.6 and 14.44 describe the Vary mechanism.     */    if (c->hdrs && c->req_hdrs) {        char *vary = ap_pstrdup(r->pool, ap_table_get(c->hdrs, "Vary"));        while (vary && *vary) {

⌨️ 快捷键说明

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