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

📄 mod_disk_cache.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 3 页
字号:
    len = sizeof(format);    apr_file_read_full(dobj->hfd, &format, len, &len);    if (format == VARY_FORMAT_VERSION) {        apr_array_header_t* varray;        apr_time_t expire;        len = sizeof(expire);        apr_file_read_full(dobj->hfd, &expire, len, &len);        varray = apr_array_make(r->pool, 5, sizeof(char*));        rc = read_array(r, varray, dobj->hfd);        if (rc != APR_SUCCESS) {            ap_log_error(APLOG_MARK, APLOG_ERR, rc, r->server,                         "disk_cache: Cannot parse vary header file: %s",                         dobj->hdrsfile);            return DECLINED;        }        apr_file_close(dobj->hfd);        nkey = regen_key(r->pool, r->headers_in, varray, key);        dobj->hashfile = NULL;        dobj->prefix = dobj->hdrsfile;        dobj->hdrsfile = header_file(r->pool, conf, dobj, nkey);        flags = APR_READ|APR_BINARY|APR_BUFFERED;        rc = apr_file_open(&dobj->hfd, dobj->hdrsfile, flags, 0, r->pool);        if (rc != APR_SUCCESS) {            return DECLINED;        }    }    else if (format != DISK_FORMAT_VERSION) {        ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,                     "cache_disk: File '%s' has a version mismatch. File had version: %d.",                     dobj->hdrsfile, format);        return DECLINED;    }    else {        apr_off_t offset = 0;        /* This wasn't a Vary Format file, so we must seek to the         * start of the file again, so that later reads work.         */        apr_file_seek(dobj->hfd, APR_SET, &offset);        nkey = key;    }    obj->key = nkey;    dobj->key = nkey;    dobj->name = key;    dobj->datafile = data_file(r->pool, conf, dobj, nkey);    dobj->tempfile = apr_pstrcat(r->pool, conf->cache_root, AP_TEMPFILE, NULL);    /* Open the data file */    flags = APR_READ|APR_BINARY;#ifdef APR_SENDFILE_ENABLED    flags |= APR_SENDFILE_ENABLED;#endif    rc = apr_file_open(&dobj->fd, dobj->datafile, flags, 0, r->pool);    if (rc != APR_SUCCESS) {        /* XXX: Log message */        return DECLINED;    }    rc = apr_file_info_get(&finfo, APR_FINFO_SIZE, dobj->fd);    if (rc == APR_SUCCESS) {        dobj->file_size = finfo.size;    }    /* Read the bytes to setup the cache_info fields */    rc = file_cache_recall_mydata(dobj->hfd, info, dobj, r);    if (rc != APR_SUCCESS) {        /* XXX log message */        return DECLINED;    }    /* Initialize the cache_handle callback functions */    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "disk_cache: Recalled cached URL info header %s",  dobj->name);    return OK;}static int remove_entity(cache_handle_t *h){    /* Null out the cache object pointer so next time we start from scratch  */    h->cache_obj = NULL;    return OK;}static int remove_url(cache_handle_t *h, apr_pool_t *p){    apr_status_t rc;    disk_cache_object_t *dobj;    /* Get disk cache object from cache handle */    dobj = (disk_cache_object_t *) h->cache_obj->vobj;    if (!dobj) {        return DECLINED;    }    /* Delete headers file */    if (dobj->hdrsfile) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,                     "disk_cache: Deleting %s from cache.", dobj->hdrsfile);        rc = apr_file_remove(dobj->hdrsfile, p);        if ((rc != APR_SUCCESS) && !APR_STATUS_IS_ENOENT(rc)) {            /* Will only result in an output if httpd is started with -e debug.             * For reason see log_error_core for the case s == NULL.             */            ap_log_error(APLOG_MARK, APLOG_DEBUG, rc, NULL,                   "disk_cache: Failed to delete headers file %s from cache.",                         dobj->hdrsfile);            return DECLINED;        }    }     /* Delete data file */    if (dobj->datafile) {        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,                     "disk_cache: Deleting %s from cache.", dobj->datafile);        rc = apr_file_remove(dobj->datafile, p);        if ((rc != APR_SUCCESS) && !APR_STATUS_IS_ENOENT(rc)) {            /* Will only result in an output if httpd is started with -e debug.             * For reason see log_error_core for the case s == NULL.             */            ap_log_error(APLOG_MARK, APLOG_DEBUG, rc, NULL,                      "disk_cache: Failed to delete data file %s from cache.",                         dobj->datafile);            return DECLINED;        }    }    /* now delete directories as far as possible up to our cache root */    if (dobj->root) {        const char *str_to_copy;        str_to_copy = dobj->hdrsfile ? dobj->hdrsfile : dobj->datafile;        if (str_to_copy) {            char *dir, *slash, *q;            dir = apr_pstrdup(p, str_to_copy);            /* remove filename */            slash = strrchr(dir, '/');            *slash = '\0';            /*             * now walk our way back to the cache root, delete everything             * in the way as far as possible             *             * Note: due to the way we constructed the file names in             * header_file and data_file, we are guaranteed that the             * cache_root is suffixed by at least one '/' which will be             * turned into a terminating null by this loop.  Therefore,             * we won't either delete or go above our cache root.             */            for (q = dir + dobj->root_len; *q ; ) {                 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL,                              "disk_cache: Deleting directory %s from cache",                              dir);                 rc = apr_dir_remove(dir, p);                 if (rc != APR_SUCCESS && !APR_STATUS_IS_ENOENT(rc)) {                    break;                 }                 slash = strrchr(q, '/');                 *slash = '\0';            }        }    }    return OK;}static apr_status_t read_array(request_rec *r, apr_array_header_t* arr,                               apr_file_t *file){    char w[MAX_STRING_LEN];    int p;    apr_status_t rv;    while (1) {        rv = apr_file_gets(w, MAX_STRING_LEN - 1, file);        if (rv != APR_SUCCESS) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Premature end of vary array.");            return rv;        }        p = strlen(w);        if (p > 0 && w[p - 1] == '\n') {            if (p > 1 && w[p - 2] == CR) {                w[p - 2] = '\0';            }            else {                w[p - 1] = '\0';            }        }        /* If we've finished reading the array, break out of the loop. */        if (w[0] == '\0') {            break;        }       *((const char **) apr_array_push(arr)) = apr_pstrdup(r->pool, w);    }    return APR_SUCCESS;}static apr_status_t store_array(apr_file_t *fd, apr_array_header_t* arr){    int i;    apr_status_t rv;    struct iovec iov[2];    apr_size_t amt;    const char **elts;    elts = (const char **) arr->elts;    for (i = 0; i < arr->nelts; i++) {        iov[0].iov_base = (char*) elts[i];        iov[0].iov_len = strlen(elts[i]);        iov[1].iov_base = CRLF;        iov[1].iov_len = sizeof(CRLF) - 1;        rv = apr_file_writev(fd, (const struct iovec *) &iov, 2,                             &amt);        if (rv != APR_SUCCESS) {            return rv;        }    }    iov[0].iov_base = CRLF;    iov[0].iov_len = sizeof(CRLF) - 1;    return apr_file_writev(fd, (const struct iovec *) &iov, 1,                         &amt);}static apr_status_t read_table(cache_handle_t *handle, request_rec *r,                               apr_table_t *table, apr_file_t *file){    char w[MAX_STRING_LEN];    char *l;    int p;    apr_status_t rv;    while (1) {        /* ### What about APR_EOF? */        rv = apr_file_gets(w, MAX_STRING_LEN - 1, file);        if (rv != APR_SUCCESS) {            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "Premature end of cache headers.");            return rv;        }        /* Delete terminal (CR?)LF */        p = strlen(w);        /* Indeed, the host's '\n':           '\012' for UNIX; '\015' for MacOS; '\025' for OS/390           -- whatever the script generates.        */        if (p > 0 && w[p - 1] == '\n') {            if (p > 1 && w[p - 2] == CR) {                w[p - 2] = '\0';            }            else {                w[p - 1] = '\0';            }        }        /* If we've finished reading the headers, break out of the loop. */        if (w[0] == '\0') {            break;        }#if APR_CHARSET_EBCDIC        /* Chances are that we received an ASCII header text instead of         * the expected EBCDIC header lines. Try to auto-detect:         */        if (!(l = strchr(w, ':'))) {            int maybeASCII = 0, maybeEBCDIC = 0;            unsigned char *cp, native;            apr_size_t inbytes_left, outbytes_left;            for (cp = w; *cp != '\0'; ++cp) {                native = apr_xlate_conv_byte(ap_hdrs_from_ascii, *cp);                if (apr_isprint(*cp) && !apr_isprint(native))                    ++maybeEBCDIC;                if (!apr_isprint(*cp) && apr_isprint(native))                    ++maybeASCII;            }            if (maybeASCII > maybeEBCDIC) {                ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,                             "CGI Interface Error: Script headers apparently ASCII: (CGI = %s)",                             r->filename);                inbytes_left = outbytes_left = cp - w;                apr_xlate_conv_buffer(ap_hdrs_from_ascii,                                      w, &inbytes_left, w, &outbytes_left);            }        }#endif /*APR_CHARSET_EBCDIC*/        /* if we see a bogus header don't ignore it. Shout and scream */        if (!(l = strchr(w, ':'))) {            return APR_EGENERAL;        }        *l++ = '\0';        while (*l && apr_isspace(*l)) {            ++l;        }        apr_table_add(table, w, l);    }    return APR_SUCCESS;}/* * Reads headers from a buffer and returns an array of headers. * Returns NULL on file error * This routine tries to deal with too long lines and continuation lines. * @@@: XXX: FIXME: currently the headers are passed thru un-merged. * Is that okay, or should they be collapsed where possible? */static apr_status_t recall_headers(cache_handle_t *h, request_rec *r){    disk_cache_object_t *dobj = (disk_cache_object_t *) h->cache_obj->vobj;    /* This case should not happen... */    if (!dobj->hfd) {        /* XXX log message */        return APR_NOTFOUND;    }    h->req_hdrs = apr_table_make(r->pool, 20);    h->resp_hdrs = apr_table_make(r->pool, 20);    /* Call routine to read the header lines/status line */    read_table(h, r, h->resp_hdrs, dobj->hfd);    read_table(h, r, h->req_hdrs, dobj->hfd);    apr_file_close(dobj->hfd);    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "disk_cache: Recalled headers for URL %s",  dobj->name);    return APR_SUCCESS;}static apr_status_t recall_body(cache_handle_t *h, apr_pool_t *p, apr_bucket_brigade *bb){    apr_bucket *e;    disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj;    e = apr_bucket_file_create(dobj->fd, 0, (apr_size_t) dobj->file_size, p,                               bb->bucket_alloc);    APR_BRIGADE_INSERT_HEAD(bb, e);    e = apr_bucket_eos_create(bb->bucket_alloc);    APR_BRIGADE_INSERT_TAIL(bb, e);    return APR_SUCCESS;}static apr_status_t store_table(apr_file_t *fd, apr_table_t *table){    int i;    apr_status_t rv;    struct iovec iov[4];    apr_size_t amt;    apr_table_entry_t *elts;    elts = (apr_table_entry_t *) apr_table_elts(table)->elts;    for (i = 0; i < apr_table_elts(table)->nelts; ++i) {        if (elts[i].key != NULL) {            iov[0].iov_base = elts[i].key;            iov[0].iov_len = strlen(elts[i].key);            iov[1].iov_base = ": ";            iov[1].iov_len = sizeof(": ") - 1;            iov[2].iov_base = elts[i].val;            iov[2].iov_len = strlen(elts[i].val);            iov[3].iov_base = CRLF;            iov[3].iov_len = sizeof(CRLF) - 1;            rv = apr_file_writev(fd, (const struct iovec *) &iov, 4,                                 &amt);            if (rv != APR_SUCCESS) {                return rv;            }        }    }    iov[0].iov_base = CRLF;    iov[0].iov_len = sizeof(CRLF) - 1;

⌨️ 快捷键说明

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