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

📄 proxy_cache.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 5 页
字号:
    dates = ap_table_get(resp_hdrs, "Date");    if (dates != NULL)        date = ap_parseHTTPdate(dates);    else        date = BAD_DATE;    now = time(NULL);    if (date == BAD_DATE) {     /* No, or bad date *//* no date header! *//* add one; N.B. use the time _now_ rather than when we were checking the cache */        date = now;        dates = ap_gm_timestr_822(r->pool, now);        ap_table_set(resp_hdrs, "Date", dates);        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Added date header");    }/* set response_time for HTTP/1.1 age calculations */    c->resp_time = now;/* check last-modified date */    if (lmod != BAD_DATE && lmod > date)/* if its in the future, then replace by date */    {        lmod = date;        lmods = dates;        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Last modified is in the future, replacing with now");    }/* if the response did not contain the header, then use the cached version */    if (lmod == BAD_DATE && c->fp != NULL) {        lmod = c->lmod;        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Reusing cached last modified");    }/* we now need to calculate the expire data for the object. */    if (expire == NULL && c->fp != NULL) {      /* no expiry data sent in                                                 * response */        expire = ap_table_get(c->hdrs, "Expires");        if (expire != NULL)            expc = ap_parseHTTPdate(expire);    }/* so we now have the expiry date *//* if no expiry date then *   if lastmod *      expiry date = now + min((date - lastmod) * factor, maxexpire) *   else *      expire date = now + defaultexpire */    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date is %ld", (long)expc);    if (expc == BAD_DATE) {        if (lmod != BAD_DATE) {            double x = (double)(date - lmod) * conf->cache.lmfactor;            double maxex = conf->cache.maxexpire;            if (x > maxex)                x = maxex;            expc = now + (int)x;        }        else            expc = now + conf->cache.defaultexpire;        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Expiry date calculated %ld", (long)expc);    }/* get the content-length header */    clen = ap_table_get(resp_hdrs, "Content-Length");    if (clen == NULL)        c->len = -1;    else        c->len = ap_strtol(clen, NULL, 10);/* we have all the header information we need - write it to the cache file */    c->version++;    ap_proxy_sec2hex(date, buff + 17 * (0));    buff[17 * (1) - 1] = ' ';    ap_proxy_sec2hex(lmod, buff + 17 * (1));    buff[17 * (2) - 1] = ' ';    ap_proxy_sec2hex(expc, buff + 17 * (2));    buff[17 * (3) - 1] = ' ';    ap_proxy_sec2hex(c->version, buff + 17 * (3));    buff[17 * (4) - 1] = ' ';    ap_proxy_sec2hex(c->req_time, buff + 17 * (4));    buff[17 * (5) - 1] = ' ';    ap_proxy_sec2hex(c->resp_time, buff + 17 * (5));    buff[17 * (6) - 1] = ' ';    ap_proxy_sec2hex(c->len, buff + 17 * (6));    buff[17 * (7) - 1] = '\n';    buff[17 * (7)] = '\0';/* Was the server response a 304 Not Modified? * * If it was, it means that we requested a revalidation, and that * the result of that revalidation was that the object was fresh. * *//* if response from server 304 not modified */    if (r->status == HTTP_NOT_MODIFIED) {/* Have the headers changed? * * if not - we fulfil the request and return now. */        if (c->hdrs) {            /* recall at this point that c->len is already set from resp_hdrs.               If Content-Length was NULL, then c->len is -1, otherwise it's               set to whatever the value was. */            if (c->len == 0 || c->len == -1) {                const char *c_clen_str;                off_t c_clen;                if ( (c_clen_str = ap_table_get(c->hdrs, "Content-Length")) &&                   ( (c_clen = ap_strtol(c_clen_str, NULL, 10)) > 0) ) {                        ap_table_set(resp_hdrs, "Content-Length", c_clen_str);                        c->len = c_clen;                        ap_proxy_sec2hex(c->len, buff + 17 * (6));                        buff[17 * (7) - 1] = '\n';                        buff[17 * (7)] = '\0';                }            }            if (!ap_proxy_table_replace(c->hdrs, resp_hdrs)) {                c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), " (with revalidation)", NULL);                return ap_proxy_cache_conditional(r, c, c->fp);            }        }        else            c->hdrs = resp_hdrs;/* if we get here - the headers have changed. Go through the motions * of creating a new temporary cache file below, we'll then serve * the request like we would have in ap_proxy_cache_conditional() * above, and at the same time we will also rewrite the contents * to the new temporary file. */    }/* * Ok - lets prepare and open the cached file * * If a cached file (in c->fp) is already open, then we want to * update that cached file. Copy the c->fp to c->origfp and open * up a new one. * * If the cached file (in c->fp) is NULL, we must open a new cached * file from scratch. * * The new cache file will be moved to it's final location in the * directory tree later, overwriting the old cache file should it exist. *//* if a cache file was already open */    if (c->fp != NULL) {        c->origfp = c->fp;    }    while (1) {/* create temporary filename */#ifndef TPF#define TMPFILESTR    "/tmpXXXXXX"        if (conf->cache.root == NULL) {            c = ap_proxy_cache_error(c);            break;        }        c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + sizeof(TMPFILESTR));        strcpy(c->tempfile, conf->cache.root);        strcat(c->tempfile, TMPFILESTR);#undef TMPFILESTR        p = mktemp(c->tempfile);#else        if (conf->cache.root == NULL) {            c = ap_proxy_cache_error(c);            break;        }        c->tempfile = ap_palloc(r->pool, strlen(conf->cache.root) + 1 + L_tmpnam);        strcpy(c->tempfile, conf->cache.root);        strcat(c->tempfile, "/");        p = tmpnam(NULL);        strcat(c->tempfile, p);#endif        if (p == NULL) {            c = ap_proxy_cache_error(c);            break;        }        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Create temporary file %s", c->tempfile);/* create the new file */        c->fp = ap_proxy_create_cachefile(r, c->tempfile);        if (NULL == c->fp) {            c = ap_proxy_cache_error(c);            break;        }/* write away the cache header and the URL */        if (ap_bvputs(c->fp, buff, "X-URL: ", c->url, "\n", NULL) == -1) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, r,                        "proxy: error writing cache file(%s)", c->tempfile);            c = ap_proxy_cache_error(c);            break;        }/* get original request headers */        if (c->req_hdrs)            req_hdrs = ap_copy_table(r->pool, c->req_hdrs);        else            req_hdrs = ap_copy_table(r->pool, r->headers_in);/* remove hop-by-hop headers */        ap_proxy_clear_connection(r->pool, req_hdrs);/* save original request headers */        if (c->req_hdrs)            ap_table_do(ap_proxy_send_hdr_line, c, c->req_hdrs, NULL);        else            ap_table_do(ap_proxy_send_hdr_line, c, r->headers_in, NULL);        if (ap_bputs(CRLF, c->fp) == -1) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,                          "proxy: error writing request headers terminating CRLF to %s", c->tempfile);            c = ap_proxy_cache_error(c);            break;        }        break;    }/* Was the server response a 304 Not Modified? * * If so, we have some work to do that we didn't do when we first * checked above. We need to fulfil the request, and we need to * copy the body from the old object to the new one. *//* if response from server 304 not modified */    if (r->status == HTTP_NOT_MODIFIED) {/* fulfil the request */        c->xcache = ap_pstrcat(r->pool, "HIT from ", ap_get_server_name(r), " (with revalidation)", NULL);        return ap_proxy_cache_conditional(r, c, c->fp);    }    return DECLINED;}void ap_proxy_cache_tidy(cache_req *c){    server_rec *s;    long int bc;    if (!c || !c->fp)        return;    s = c->req->server;/* don't care how much was sent, but rather how much was written to cache    ap_bgetopt(c->req->connection->client, BO_BYTECT, &bc); */    bc = c->written;    if (c->len != -1) {/* file lengths don't match; don't cache it */        if (bc != c->len) {            ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));  /* no need to flush */            unlink(c->tempfile);            return;        }    }/* don't care if aborted, cache it if fully retrieved from host!    else if (c->req->connection->aborted) {        ap_pclosef(c->req->pool, c->fp->fd);    / no need to flush /        unlink(c->tempfile);        return;    }*/    else {/* update content-length of file */        char buff[17];        off_t curpos;        c->len = bc;        ap_bflush(c->fp);        ap_proxy_sec2hex(c->len, buff);        curpos = lseek(ap_bfileno(c->fp, B_WR), 17 * 6, SEEK_SET);        if (curpos == -1)            ap_log_error(APLOG_MARK, APLOG_ERR, s,                      "proxy: error seeking on cache file %s", c->tempfile);        else if (write(ap_bfileno(c->fp, B_WR), buff, sizeof(buff) - 1) == -1)            ap_log_error(APLOG_MARK, APLOG_ERR, s,                         "proxy: error updating cache file %s", c->tempfile);    }    if (ap_bflush(c->fp) == -1) {        ap_log_error(APLOG_MARK, APLOG_ERR, s,                     "proxy: error writing to cache file %s",                     c->tempfile);        ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR));        unlink(c->tempfile);        return;    }    if (ap_pclosef(c->req->pool, ap_bfileno(c->fp, B_WR))== -1) {        ap_log_error(APLOG_MARK, APLOG_ERR, s,                     "proxy: error closing cache file %s", c->tempfile);        unlink(c->tempfile);        return;    }    if (unlink(c->filename) == -1 && errno != ENOENT) {        ap_log_error(APLOG_MARK, APLOG_ERR, s,                     "proxy: error deleting old cache file %s",                     c->filename);        (void)unlink(c->tempfile);    }    else {        char *p;        proxy_server_conf *conf =        (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module);        for (p = c->filename + strlen(conf->cache.root) + 1;;) {            p = strchr(p, '/');            if (!p)                break;            *p = '\0';#if defined(WIN32) || defined(NETWARE)            if (mkdir(c->filename) < 0 && errno != EEXIST)#elif defined(__TANDEM)                if (mkdir(c->filename, S_IRWXU | S_IRWXG | S_IRWXO) < 0 && errno != EEXIST)#else            if (mkdir(c->filename, S_IREAD | S_IWRITE | S_IEXEC) < 0 && errno != EEXIST)#endif                          /* WIN32 */                ap_log_error(APLOG_MARK, APLOG_ERR, s,                             "proxy: error creating cache directory %s",                             c->filename);            *p = '/';            ++p;        }#if defined(OS2) || defined(WIN32) || defined(NETWARE) || defined(MPE)        /* Under OS/2 use rename. */        if (rename(c->tempfile, c->filename) == -1) {            ap_log_error(APLOG_MARK, APLOG_ERR, s,                         "proxy: error renaming cache file %s to %s",                         c->tempfile, c->filename);            (void)unlink(c->tempfile);        }#else        if (link(c->tempfile, c->filename) == -1)            ap_log_error(APLOG_MARK, APLOG_INFO, s,                         "proxy: error linking cache file %s to %s",                         c->tempfile, c->filename);        if (unlink(c->tempfile) == -1)            ap_log_error(APLOG_MARK, APLOG_ERR, s,                         "proxy: error deleting temp file %s", c->tempfile);#endif    }}

⌨️ 快捷键说明

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