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

📄 proxy_cache.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 3 页
字号:
}/* * Having read the response from the client, decide what to do * If the response is not cachable, then delete any previously cached * response, and copy data from remote server to client. * Functions: *  parse dates *  check for an uncachable response *  calculate an expiry date, if one is not provided *  if the remote file has not been modified, then return the document *  from the cache, maybe updating the header line *  otherwise, delete the old cached file and open a new temporary file */int ap_proxy_cache_update(cache_req *c, table *resp_hdrs,		       const int is_HTTP1, int nocache){#ifdef ULTRIX_BRAIN_DEATH  extern char *mktemp(char *template);#endif     request_rec *r = c->req;    char *p;    int i;    const char *expire, *lmods, *dates, *clen;    time_t expc, date, lmod, now;    char buff[46];    void *sconf = r->server->module_config;    proxy_server_conf *conf =    (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);    const long int zero = 0L;    c->tempfile = NULL;/* we've received the response *//* read expiry date; if a bad date, then leave it so the client can * read it */    expire = ap_table_get(resp_hdrs, "Expires");    if (expire != NULL)	expc = ap_parseHTTPdate(expire);    else	expc = BAD_DATE;/* * read the last-modified date; if the date is bad, then delete it */    lmods = ap_table_get(resp_hdrs, "Last-Modified");    if (lmods != NULL) {	lmod = ap_parseHTTPdate(lmods);	if (lmod == BAD_DATE) {/* kill last modified date */	    lmods = NULL;	}    }    else	lmod = BAD_DATE;/* * what responses should we not cache? * Unknown status responses and those known to be uncacheable * 304 HTTP_NOT_MODIFIED response when we have no valid cache file, or * 200 HTTP_OK response from HTTP/1.0 and up without a Last-Modified header, or * HEAD requests, or * requests with an Authorization header, or * protocol requests nocache (e.g. ftp with user/password) *//* @@@ XXX FIXME: is the test "r->status != HTTP_MOVED_PERMANENTLY" corerct? * or shouldn't it be "ap_is_HTTP_REDIRECT(r->status)" ? -MnKr */    if ((r->status != HTTP_OK && r->status != HTTP_MOVED_PERMANENTLY && r->status != HTTP_NOT_MODIFIED) ||	(expire != NULL && expc == BAD_DATE) ||	(r->status == HTTP_NOT_MODIFIED && (c == NULL || c->fp == NULL)) ||	(r->status == HTTP_OK && lmods == NULL && is_HTTP1) ||	r->header_only ||	ap_table_get(r->headers_in, "Authorization") != NULL ||	nocache) {	Explain1("Response is not cacheable, unlinking %s", c->filename);/* close the file */	if (c->fp != NULL) {	    ap_pclosef(r->pool, c->fp->fd);	    c->fp = NULL;	}/* delete the previously cached file */        if (c->filename)            unlink(c->filename);	return DECLINED;	/* send data to client but not cache */    }/* otherwise, we are going to cache the response *//* * Read the date. Generate one if one is not supplied */    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);	Explain0("Added date header");    }/* check last-modified date */    if (lmod != BAD_DATE && lmod > date)/* if its in the future, then replace by date */    {	lmod = date;	lmods = dates;	Explain0("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;	Explain0("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 */    Explain1("Expiry date is %ld", 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;	Explain1("Expiry date calculated %ld", expc);    }/* get the content-length header */    clen = ap_table_get(resp_hdrs, "Content-Length");    if (clen == NULL)	c->len = -1;    else	c->len = atoi(clen);    ap_proxy_sec2hex(date, buff);    buff[8] = ' ';    ap_proxy_sec2hex(lmod, buff + 9);    buff[17] = ' ';    ap_proxy_sec2hex(expc, buff + 18);    buff[26] = ' ';    ap_proxy_sec2hex(c->version++, buff + 27);    buff[35] = ' ';    ap_proxy_sec2hex(c->len, buff + 36);    buff[44] = '\n';    buff[45] = '\0';/* if file not modified */    if (r->status == HTTP_NOT_MODIFIED) {	if (c->ims != BAD_DATE && lmod != BAD_DATE && lmod <= c->ims) {/* set any changed headers somehow *//* update dates and version, but not content-length */	    if (lmod != c->lmod || expc != c->expire || date != c->date) {		off_t curpos = lseek(c->fp->fd, 0, SEEK_SET);		if (curpos == -1)		    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,				 "proxy: error seeking on cache file %s",				 c->filename);		else if (write(c->fp->fd, buff, 35) == -1)		    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,				 "proxy: error updating cache file %s",				 c->filename);	    }	    ap_pclosef(r->pool, c->fp->fd);	    Explain0("Remote document not modified, use local copy");	    /* CHECKME: Is this right? Shouldn't we check IMS again here? */	    return HTTP_NOT_MODIFIED;	}	else {/* return the whole document */	    Explain0("Remote document updated, sending");	    r->status_line = strchr(c->resp_line, ' ') + 1;	    r->status = c->status;	    if (!r->assbackwards) {		ap_soft_timeout("proxy send headers", r);		ap_proxy_send_headers(r, c->resp_line, c->hdrs);		ap_kill_timeout(r);	    }	    ap_bsetopt(r->connection->client, BO_BYTECT, &zero);	    r->sent_bodyct = 1;	    if (!r->header_only)		ap_proxy_send_fb(c->fp, r, NULL);/* set any changed headers somehow *//* update dates and version, but not content-length */	    if (lmod != c->lmod || expc != c->expire || date != c->date) {		off_t curpos = lseek(c->fp->fd, 0, SEEK_SET);		if (curpos == -1)		    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,				 "proxy: error seeking on cache file %s",				 c->filename);		else if (write(c->fp->fd, buff, 35) == -1)		    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,				 "proxy: error updating cache file %s",				 c->filename);	    }	    ap_pclosef(r->pool, c->fp->fd);	    return OK;	}    }/* new or modified file */    if (c->fp != NULL) {	ap_pclosef(r->pool, c->fp->fd);	c->fp->fd = -1;    }    c->version = 0;    ap_proxy_sec2hex(0, buff + 27);    buff[35] = ' ';/* open temporary file */#define TMPFILESTR	"/tmpXXXXXX"    if (conf->cache.root == NULL)	return DECLINED;    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);    if (p == NULL)	return DECLINED;    Explain1("Create temporary file %s", c->tempfile);    i = open(c->tempfile, O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0622);    if (i == -1) {	ap_log_rerror(APLOG_MARK, APLOG_ERR, r,		     "proxy: error creating cache file %s",		     c->tempfile);	return DECLINED;    }    ap_note_cleanups_for_fd(r->pool, i);    c->fp = ap_bcreate(r->pool, B_WR);    ap_bpushfd(c->fp, -1, i);    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);	ap_pclosef(r->pool, c->fp->fd);	unlink(c->tempfile);	c->fp = NULL;    }    return DECLINED;}void ap_proxy_cache_tidy(cache_req *c){    server_rec *s;    long int bc;    if (c == NULL || c->fp == NULL)	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, c->fp->fd);	/* 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[9];	off_t curpos;	c->len = bc;	ap_bflush(c->fp);	ap_proxy_sec2hex(c->len, buff);	curpos = lseek(c->fp->fd, 36, 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(c->fp->fd, buff, 8) == -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, c->fp->fd);	unlink(c->tempfile);	return;    }    if (ap_pclosef(c->req->pool, c->fp->fd) == -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->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';#ifdef WIN32	    if (mkdir(c->filename) < 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)	/* 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);    }#else	if (link(c->tempfile, c->filename) == -1)	    ap_log_error(APLOG_MARK, APLOG_ERR, 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 + -