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

📄 mod_disk_cache.c

📁 最新apache的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        return DECLINED;    }    /* Create and init the cache object */    h->cache_obj = obj = apr_pcalloc(r->pool, sizeof(cache_object_t));    obj->vobj = dobj = apr_pcalloc(r->pool, sizeof(disk_cache_object_t));    info = &(obj->info);    obj->key = (char *) key;    dobj->name = (char *) key;    dobj->datafile = data_file(r->pool, conf, dobj, key);    dobj->hdrsfile = header_file(r->pool, conf, dobj, key);    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;    }    /* Open the headers file */    flags = APR_READ|APR_BINARY|APR_BUFFERED;    rc = apr_file_open(&dobj->hfd, dobj->hdrsfile, 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(const char *key){    /* XXX: Delete file from cache! */    return OK;}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);    h->resp_err_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);    h->status = dobj->disk_info.status;    h->content_type = apr_table_get(h->resp_hdrs, "Content-Type");    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;    rv = apr_file_writev(fd, (const struct iovec *) &iov, 1,                         &amt);    return rv;}static apr_status_t store_headers(cache_handle_t *h, request_rec *r, cache_info *info){    disk_cache_conf *conf = ap_get_module_config(r->server->module_config,                                                 &disk_cache_module);    apr_status_t rv;    apr_size_t amt;    disk_cache_object_t *dobj = (disk_cache_object_t*) h->cache_obj->vobj;    if (!dobj->hfd)  {        disk_cache_info_t disk_info;        struct iovec iov[2];        /* This is flaky... we need to manage the cache_info differently */        h->cache_obj->info = *info;        /* Remove old file with the same name. If remove fails, then         * perhaps we need to create the directory tree where we are         * about to write the new headers file.         */        rv = apr_file_remove(dobj->hdrsfile, r->pool);        if (rv != APR_SUCCESS) {            mkdir_structure(conf, dobj->hdrsfile, r->pool);        }        rv = apr_file_open(&dobj->hfd, dobj->hdrsfile,                           APR_WRITE | APR_CREATE | APR_EXCL,                           APR_OS_DEFAULT, r->pool);        if (rv != APR_SUCCESS) {            return rv;        }        dobj->name = h->cache_obj->key;        disk_info.format = DISK_FORMAT_VERSION;        disk_info.date = info->date;        disk_info.expire = info->expire;        disk_info.entity_version = dobj->disk_info.entity_version++;        disk_info.request_time = info->request_time;        disk_info.response_time = info->response_time;        disk_info.status = info->status;        disk_info.name_len = strlen(dobj->name);        iov[0].iov_base = (void*)&disk_info;        iov[0].iov_len = sizeof(disk_cache_info_t);        iov[1].iov_base = dobj->name;        iov[1].iov_len = disk_info.name_len;        rv = apr_file_writev(dobj->hfd, (const struct iovec *) &iov, 2, &amt);        if (rv != APR_SUCCESS) {            return rv;        }        if (r->headers_out) {            apr_table_t *headers_out;            headers_out = ap_cache_cacheable_hdrs_out(r->pool, r->headers_out,                                                      r->server);            if (!apr_table_get(headers_out, "Content-Type") &&                r->content_type) {                apr_table_setn(headers_out, "Content-Type",                               ap_make_content_type(r, r->content_type));            }            rv = store_table(dobj->hfd, headers_out);            if (rv != APR_SUCCESS) {                return rv;            }        }        /* Parse the vary header and dump those fields from the headers_in. */        /* Make call to the same thing cache_select_url calls to crack Vary. */        /* @@@ Some day, not today. */        if (r->headers_in) {            apr_table_t *headers_in;            headers_in = ap_cache_cacheable_hdrs_out(r->pool, r->headers_in,                                                     r->server);            rv = store_table(dobj->hfd, headers_in);            if (rv != APR_SUCCESS) {                return rv;            }        }        apr_file_close(dobj->hfd); /* flush and close */    }    else {        /* XXX log message */    }    ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,                 "disk_cache: Stored headers for URL %s",  dobj->name);    return APR_SUCCESS;

⌨️ 快捷键说明

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