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

📄 proxy_cache.c

📁 apache简化版
💻 C
📖 第 1 页 / 共 3 页
字号:
    struct dirent *ent;#endif    struct gc_ent *fent;    int nfiles = 0;    ap_snprintf(cachedir, sizeof(cachedir), "%s%s", cachebasedir, cachesubdir);    Explain1("GC Examining directory %s", cachedir);    dir = opendir(cachedir);    if (dir == NULL) {	ap_log_error(APLOG_MARK, APLOG_ERR, r->server,		     "proxy gc: opendir(%s)", cachedir);	return 0;    }    while ((ent = readdir(dir)) != NULL) {	if (ent->d_name[0] == '.')	    continue;	sprintf(filename, "%s%s", cachedir, ent->d_name);	Explain1("GC Examining file %s", filename);/* is it a temporary file? */	if (strncmp(ent->d_name, "tmp", 3) == 0) {/* then stat it to see how old it is; delete temporary files > 1 day old */	    if (stat(filename, &buf) == -1) {		if (errno != ENOENT)		    ap_log_error(APLOG_MARK, APLOG_ERR, r->server,				 "proxy gc: stat(%s)", filename);	    }	    else if (garbage_now != -1 && buf.st_atime < garbage_now - SEC_ONE_DAY &&		     buf.st_mtime < garbage_now - SEC_ONE_DAY) {		Explain1("GC unlink %s", filename);		ap_log_error(APLOG_MARK, APLOG_INFO|APLOG_NOERRNO, r->server,			     "proxy gc: deleting orphaned cache file %s", filename);#if TESTING		fprintf(stderr, "Would unlink %s\n", filename);#else		unlink(filename);#endif	    }	    continue;	}	++nfiles;/* is it another file? */	/* FIXME: Shouldn't any unexpected files be deleted? */	/*      if (strlen(ent->d_name) != HASH_LEN) continue; *//* under OS/2 use dirent's d_attr to identify a diretory */#ifdef OS2/* is it a directory? */	if (ent->d_attr & A_DIR) {	    char newcachedir[HUGE_STRING_LEN];	    ap_snprintf(newcachedir, sizeof(newcachedir),			"%s%s/", cachesubdir, ent->d_name);	    if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) {		ap_snprintf(newcachedir, sizeof(newcachedir),			    "%s%s", cachedir, ent->d_name);#if TESTING		fprintf(stderr, "Would remove directory %s\n", newcachedir);#else		rmdir(newcachedir);#endif		--nfiles;	    }	    continue;	}#endif/* read the file */	fd = open(filename, O_RDONLY | O_BINARY);	if (fd == -1) {	    if (errno != ENOENT)		ap_log_error(APLOG_MARK, APLOG_ERR, r->server,			     "proxy gc: open(%s)", filename);	    continue;	}	if (fstat(fd, &buf) == -1) {	    ap_log_error(APLOG_MARK, APLOG_ERR, r->server,			 "proxy gc: fstat(%s)", filename);	    close(fd);	    continue;	}/* In OS/2 this has already been done above */#ifndef OS2	if (S_ISDIR(buf.st_mode)) {	    char newcachedir[HUGE_STRING_LEN];	    close(fd);	    ap_snprintf(newcachedir, sizeof(newcachedir),			"%s%s/", cachesubdir, ent->d_name);	    if (!sub_garbage_coll(r, files, cachebasedir, newcachedir)) {		ap_snprintf(newcachedir, sizeof(newcachedir),			    "%s%s", cachedir, ent->d_name);#if TESTING		fprintf(stderr, "Would remove directory %s\n", newcachedir);#else		rmdir(newcachedir);#endif		--nfiles;	    } else {		/* Directory is not empty. Account for its size: */		add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));	    }	    continue;	}#endif	i = read(fd, line, 26);	close(fd);	if (i == -1) {	    ap_log_error(APLOG_MARK, APLOG_ERR, r->server,			 "proxy gc: read(%s)", filename);	    continue;	}	line[i] = '\0';	garbage_expire = ap_proxy_hex2sec(line + 18);	if (!ap_checkmask(line, "&&&&&&&& &&&&&&&& &&&&&&&&") ||	    garbage_expire == BAD_DATE) {	    /* bad file */	    if (garbage_now != -1 && buf.st_atime > garbage_now + SEC_ONE_DAY &&		buf.st_mtime > garbage_now + SEC_ONE_DAY) {		ap_log_error(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, r->server,			     "proxy: deleting bad cache file with future date: %s", filename);#if TESTING		fprintf(stderr, "Would unlink bad file %s\n", filename);#else		unlink(filename);#endif	    }	    continue;	}/* * we need to calculate an 'old' factor, and remove the 'oldest' files * so that the space requirement is met; sort by the expires date of the * file. * */	fent = (struct gc_ent *) ap_push_array(files);	fent->len = buf.st_size;	fent->expire = garbage_expire;	strcpy(fent->file, cachesubdir);	strcat(fent->file, ent->d_name);/* accumulate in blocks, to cope with directories > 4Gb */	add_long61(&curbytes, ROUNDUP2BLOCKS(buf.st_size));    }    closedir(dir);    return nfiles;}/* * read a cache file; * returns 1 on success, *         0 on failure (bad file or wrong URL) *        -1 on UNIX error */static int rdcache(request_rec *r, BUFF *cachefp, cache_req *c){    char urlbuff[1034], *strp;    int len;/* read the data from the cache file *//* format * date SP lastmod SP expire SP count SP content-length CRLF * dates are stored as hex seconds since 1970 */    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);    if (len == -1)	return -1;    if (len == 0 || urlbuff[len - 1] != '\n')	return 0;    urlbuff[len - 1] = '\0';    if (!ap_checkmask(urlbuff,		   "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&"))	return 0;    c->date = ap_proxy_hex2sec(urlbuff);    c->lmod = ap_proxy_hex2sec(urlbuff + 9);    c->expire = ap_proxy_hex2sec(urlbuff + 18);    c->version = ap_proxy_hex2sec(urlbuff + 27);    c->len = ap_proxy_hex2sec(urlbuff + 36);/* check that we have the same URL */    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);    if (len == -1)	return -1;    if (len == 0 || strncmp(urlbuff, "X-URL: ", 7) != 0 ||	urlbuff[len - 1] != '\n')	return 0;    urlbuff[len - 1] = '\0';    if (strcmp(urlbuff + 7, c->url) != 0)	return 0;/* What follows is the message */    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);    if (len == -1)	return -1;    if (len == 0 || urlbuff[len - 1] != '\n')	return 0;    urlbuff[--len] = '\0';    c->resp_line = ap_pstrdup(r->pool, urlbuff);    strp = strchr(urlbuff, ' ');    if (strp == NULL)	return 0;    c->status = atoi(strp);    c->hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);    if (c->hdrs == NULL)	return -1;    if (c->len != -1) {		/* add a content-length header */	if (ap_table_get(c->hdrs, "Content-Length") == NULL) {	    ap_table_set(c->hdrs, "Content-Length",			 ap_psprintf(r->pool, "%lu", (unsigned long)c->len));	}    }    return 1;}/* * 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 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){    char hashfile[66];    const char *imstr, *pragma, *auth;    cache_req *c;    time_t now;    BUFF *cachefp;    int cfd, i;    const long int zero = 0L;    void *sconf = r->server->module_config;    proxy_server_conf *pconf =    (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module);    c = ap_pcalloc(r->pool, sizeof(cache_req));    *cr = c;    c->req = r;    c->url = ap_pstrdup(r->pool, url);/* get the If-Modified-Since date of the request */    c->ims = BAD_DATE;    imstr = ap_table_get(r->headers_in, "If-Modified-Since");    if (imstr != NULL) {/* this may modify the value in the original table */	imstr = ap_proxy_date_canon(r->pool, imstr);	c->ims = ap_parseHTTPdate(imstr);	if (c->ims == BAD_DATE)	/* bad or out of range date; remove it */	    ap_table_unset(r->headers_in, "If-Modified-Since");    }/* find the filename for this cache entry */    ap_proxy_hash(url, hashfile, pconf->cache.dirlevels, pconf->cache.dirlength);    if (conf->root != NULL)	c->filename = ap_pstrcat(r->pool, conf->root, "/", hashfile, NULL);    else	c->filename = NULL;    cachefp = NULL;/* find out about whether the request can access the cache */    pragma = ap_table_get(r->headers_in, "Pragma");    auth = ap_table_get(r->headers_in, "Authorization");    Explain5("Request for %s, pragma=%s, auth=%s, ims=%ld, imstr=%s", url,	     pragma, auth, c->ims, imstr);    if (c->filename != NULL && r->method_number == M_GET &&	strlen(url) < 1024 && !ap_proxy_liststr(pragma, "no-cache") &&	auth == NULL) {	Explain1("Check file %s", c->filename);	cfd = open(c->filename, O_RDWR | O_BINARY);	if (cfd != -1) {	    ap_note_cleanups_for_fd(r->pool, cfd);	    cachefp = ap_bcreate(r->pool, B_RD | B_WR);	    ap_bpushfd(cachefp, cfd, cfd);	}	else if (errno != ENOENT)	    ap_log_rerror(APLOG_MARK, APLOG_ERR, r,			 "proxy: error opening cache file %s",			 c->filename);#ifdef EXPLAIN	else	    Explain1("File %s not found", c->filename);#endif    }    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, cachefp->fd);	    cachefp = NULL;	}    }/* 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? */    now = time(NULL);/* Ok, have we got some un-expired data? */    if (cachefp != NULL && c->expire != BAD_DATE && now < c->expire) {	Explain0("Unexpired data available");/* check IMS */	if (c->lmod != BAD_DATE && c->ims != BAD_DATE && c->ims >= c->lmod) {/* has the cached file changed since this request? */	    if (c->date == BAD_DATE || c->date > c->ims) {/* No, but these header values may have changed, so we send them with the * 304 HTTP_NOT_MODIFIED response */		const char *q;		if ((q = ap_table_get(c->hdrs, "Expires")) != NULL)		    ap_table_set(r->headers_out, "Expires", q);	    }	    ap_pclosef(r->pool, cachefp->fd);	    Explain0("Use local copy, cached file hasn't changed");	    return HTTP_NOT_MODIFIED;	}/* Ok, has been modified */	Explain0("Local copy modified, send it");	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(cachefp, r, NULL);	ap_pclosef(r->pool, cachefp->fd);	return OK;    }/* if we already have data and a last-modified date, and it is not a head * request, then add an If-Modified-Since */    if (cachefp != NULL && c->lmod != BAD_DATE && !r->header_only) {/* * use the later of the one from the request and the last-modified date * from the cache */	if (c->ims == BAD_DATE || c->ims < c->lmod) {	    const char *q;	    if ((q = ap_table_get(c->hdrs, "Last-Modified")) != NULL)		ap_table_set(r->headers_in, "If-Modified-Since",			  (char *) q);	}    }    c->fp = cachefp;    Explain0("Local copy not present or expired. Declining.");    return DECLINED;

⌨️ 快捷键说明

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