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

📄 proxy_cache.c

📁 apache 安装教程 apache 安装教程
💻 C
📖 第 1 页 / 共 5 页
字号:
        fprintf(stderr, "Would unlink %s\n", filename);#else        if (unlink(filename) == -1) {            if (errno != ENOENT)                ap_log_error(APLOG_MARK, APLOG_ERR, r->server,                             "proxy gc: unlink(%s)", filename);        }        else#endif        {            sub_long61(&curbytes, ROUNDUP2BLOCKS(fent->len));            if (cmp_long61(&curbytes, &cachesize) < 0)                break;        }    }    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server,                 "proxy GC: Cache is %ld%% full (%d deleted)",                 (long)(((curbytes.upper << 20) | (curbytes.lower >> 10)) * 100 / conf->space), i);    ap_unblock_alarms();}static int sub_garbage_coll(request_rec *r, array_header *files,                          const char *cachebasedir, const char *cachesubdir){    char line[17 * (3)];    char cachedir[HUGE_STRING_LEN];    struct stat buf;    int fd, i;    DIR *dir;#if defined(NEXT) || defined(WIN32)    struct DIR_TYPE *ent;#else    struct dirent *ent;#endif    struct gc_ent *fent;    int nfiles = 0;    char *filename;    ap_snprintf(cachedir, sizeof(cachedir), "%s%s", cachebasedir, cachesubdir);    filename = ap_palloc(r->pool, strlen(cachedir) + HASH_LEN + 2);    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "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);        ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "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) {                ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "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 *//* under TPF use stat to identify a directory */#if defined(OS2) || defined(TPF)/* is it a directory? */#ifdef OS2        if (ent->d_attr & A_DIR)#elif defined(TPF)            if (stat(filename, &buf) == -1) {                if (errno != ENOENT)                    ap_log_error(APLOG_MARK, APLOG_ERR, r->server,                                 "proxy gc: stat(%s)", filename);            }        if (S_ISDIR(buf.st_mode))#endif        {            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 */#if defined(WIN32)        /*         * On WIN32 open does not work for directories, so we us stat instead         * of fstat to determine if the file is a directory         */        if (stat(filename, &buf) == -1) {            ap_log_error(APLOG_MARK, APLOG_ERR, r->server,                         "proxy gc: stat(%s)", filename);            continue;        }        fd = -1;#else        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;        }#endif/* In OS/2 and TPF this has already been done above */#if !defined(OS2) && !defined(TPF)        if (S_ISDIR(buf.st_mode)) {            char newcachedir[HUGE_STRING_LEN];#if !defined(WIN32)            /* Win32 used stat, no file to close */            close(fd);#endif            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#if defined(WIN32)        /*         * Since we have determined above that the file is not a directory,         * it should be safe to open it now         */        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) = %d", filename, errno);            continue;        }#endif        i = read(fd, line, 17 * (3) - 1);        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 + 17 * (2));        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 * * We read the cache hex header, then the message response line and * response headers, and finally we return with the filepointer * pointing at the start of the message body itself, ready to be * shipped to the client later on, if appropriate. */static int rdcache(request_rec *r, BUFF *cachefp, cache_req *c){    char urlbuff[HUGE_STRING_LEN], *strp;    int len;    /* read the data from the cache file */    /*     * Format:     *      * The cache needs to keep track of the following information: - Date,     * LastMod, Version, ReqTime, RespTime, ContentLength - The original     * request headers (for Vary) - The original response headers (for     * returning with a cached response) - The body of the message     *      * date SP lastmod SP expire SP count SP request-time SP response-time SP     * content-lengthCRLF (dates are stored as hex seconds since 1970)     * Original URLCRLF Original Request Headers CRLF Original Response     * Headers CRLF Body     *      */    /* retrieve cachefile information values */    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);    if (len == -1) {        /* Delete broken cache file */        unlink(c->filename);        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 + 17 * (0));    c->lmod = ap_proxy_hex2sec(urlbuff + 17 * (1));    c->expire = ap_proxy_hex2sec(urlbuff + 17 * (2));    c->version = ap_proxy_hex2sec(urlbuff + 17 * (3));    c->req_time = ap_proxy_hex2sec(urlbuff + 17 * (4));    c->resp_time = ap_proxy_hex2sec(urlbuff + 17 * (5));    c->len = ap_proxy_hex2sec(urlbuff + 17 * (6));    /* check that we have the same URL */    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);    if (len == -1) {        /* Delete broken cache file */        unlink(c->filename);        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;    /* then the original request headers */    c->req_hdrs = ap_proxy_read_headers(r, urlbuff, sizeof urlbuff, cachefp);    if (c->req_hdrs == NULL) {        /* Delete broken cache file */        unlink(c->filename);        return -1;    }    /* then the original response headers */    len = ap_bgets(urlbuff, sizeof urlbuff, cachefp);    if (len == -1) {        /* Delete broken cache file */        unlink(c->filename);        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) {        /* Delete broken cache file */        unlink(c->filename);        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 check the possible conditional status of * the client request, and return the response from the cache * * Conditionals include If-Modified-Since, If-Match, If-Unmodified-Since * and If-None-Match. * * We don't yet understand If-Range, but we will... */int ap_proxy_cache_conditional(request_rec *r, cache_req *c, BUFF *cachefp){    const char *etag, *wetag = NULL;

⌨️ 快捷键说明

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