static ngx_int_t ngx_http_file_cache_name(ngx_http_request_t *r, ngx_path_t *path) { u_char *p; ngx_http_cache_t *c; c = r->cache; if (c->file.name.len) { return NGX_OK; } c->file.name.len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); if (c->file.name.data == NULL) { return NGX_ERROR; } ngx_memcpy(c->file.name.data, path->name.data, path->name.len); p = c->file.name.data + path->name.len + 1 + path->len; p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); *p = '\0'; ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "cache file: \"%s\"", c->file.name.data); return NGX_OK; }
static void ngx_http_file_cache_delete(ngx_http_file_cache_t *cache, ngx_queue_t *q, u_char *name) { u_char *p; size_t len; ngx_path_t *path; ngx_http_file_cache_node_t *fcn; fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); if (fcn->exists) { cache->sh->size -= fcn->fs_size; path = cache->path; p = name + path->name.len + 1 + path->len; p = ngx_hex_dump(p, (u_char *) &fcn->node.key, sizeof(ngx_rbtree_key_t)); len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t); p = ngx_hex_dump(p, fcn->key, len); *p = '\0'; fcn->count++; fcn->deleting = 1; ngx_shmtx_unlock(&cache->shpool->mutex); len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; ngx_create_hashed_filename(path, name, len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache expire: \"%s\"", name); if (ngx_delete_file(name) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, ngx_delete_file_n " \"%s\" failed", name); } ngx_shmtx_lock(&cache->shpool->mutex); fcn->count--; fcn->deleting = 0; } if (fcn->count == 0) { ngx_queue_remove(q); ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); } }
ngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r) { u_char *p; ngx_int_t rc, rv; ngx_uint_t cold, test; ngx_path_t *path; ngx_http_cache_t *c; ngx_pool_cleanup_t *cln; ngx_open_file_info_t of; ngx_http_file_cache_t *cache; ngx_http_core_loc_conf_t *clcf; c = r->cache; if (c->buf) { return ngx_http_file_cache_read(r, c); } cache = c->file_cache; cln = ngx_pool_cleanup_add(r->pool, 0); if (cln == NULL) { return NGX_ERROR; } rc = ngx_http_file_cache_exists(cache, c); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http file cache exists: %i e:%d", rc, c->exists); if (rc == NGX_ERROR) { return rc; } cln->handler = ngx_http_file_cache_cleanup; cln->data = c; if (rc == NGX_AGAIN) { return NGX_HTTP_CACHE_SCARCE; } cold = cache->sh->cold; if (rc == NGX_OK) { if (c->error) { return c->error; } c->temp_file = 1; test = c->exists ? 1 : 0; rv = NGX_DECLINED; } else { /* rc == NGX_DECLINED */ if (c->min_uses > 1) { if (!cold) { return NGX_HTTP_CACHE_SCARCE; } test = 1; rv = NGX_HTTP_CACHE_SCARCE; } else { c->temp_file = 1; test = cold ? 1 : 0; rv = NGX_DECLINED; } } path = cache->path; c->file.name.len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; c->file.name.data = ngx_pnalloc(r->pool, c->file.name.len + 1); if (c->file.name.data == NULL) { return NGX_ERROR; } ngx_memcpy(c->file.name.data, path->name.data, path->name.len); p = c->file.name.data + path->name.len + 1 + path->len; p = ngx_hex_dump(p, c->key, NGX_HTTP_CACHE_KEY_LEN); *p = '\0'; ngx_create_hashed_filename(path, c->file.name.data, c->file.name.len); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "cache file: \"%s\"", c->file.name.data); if (!test) { return NGX_DECLINED; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_memzero(&of, sizeof(ngx_open_file_info_t)); of.uniq = c->uniq; of.valid = clcf->open_file_cache_valid; of.min_uses = clcf->open_file_cache_min_uses; of.events = clcf->open_file_cache_events; of.directio = NGX_OPEN_FILE_DIRECTIO_OFF; of.read_ahead = clcf->read_ahead; if (ngx_open_cached_file(clcf->open_file_cache, &c->file.name, &of, r->pool) != NGX_OK) { switch (of.err) { case 0: return NGX_ERROR; case NGX_ENOENT: case NGX_ENOTDIR: return rv; default: ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, ngx_open_file_n " \"%s\" failed", c->file.name.data); return NGX_ERROR; } } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http file cache fd: %d", of.fd); c->file.fd = of.fd; c->file.log = r->connection->log; c->uniq = of.uniq; c->length = of.size; c->buf = ngx_create_temp_buf(r->pool, c->body_start); if (c->buf == NULL) { return NGX_ERROR; } return ngx_http_file_cache_read(r, c); }
ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access) { uint32_t n; ngx_err_t err; ngx_pool_cleanup_t *cln; ngx_pool_cleanup_file_t *clnf; file->name.len = path->name.len + 1 + path->len + 10; file->name.data = ngx_pnalloc(pool, file->name.len + 1); if (file->name.data == NULL) { return NGX_ERROR; } #if 0 for (i = 0; i < file->name.len; i++) { file->name.data[i] = 'X'; } #endif ngx_memcpy(file->name.data, path->name.data, path->name.len); n = (uint32_t) ngx_next_temp_number(0); cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); if (cln == NULL) { return NGX_ERROR; } for ( ;; ) { (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len, "%010uD%Z", n); ngx_create_hashed_filename(path, file->name.data, file->name.len); ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, "hashed path: %s", file->name.data); file->fd = ngx_open_tempfile(file->name.data, persistent, access); ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, "temp fd:%d", file->fd); if (file->fd != NGX_INVALID_FILE) { cln->handler = clean ? ngx_pool_delete_file : ngx_pool_cleanup_file; clnf = cln->data; clnf->fd = file->fd; clnf->name = file->name.data; clnf->log = pool->log; return NGX_OK; } err = ngx_errno; if (err == NGX_EEXIST) { n = (uint32_t) ngx_next_temp_number(1); continue; } if ((path->level[0] == 0) || (err != NGX_ENOPATH)) { ngx_log_error(NGX_LOG_CRIT, file->log, err, ngx_open_tempfile_n " \"%s\" failed", file->name.data); return NGX_ERROR; } if (ngx_create_path(file, path) == NGX_ERROR) { return NGX_ERROR; } } }
int ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, int persistent) { int num; ngx_err_t err; file->name.len = path->name.len + 1 + path->len + 10; ngx_test_null(file->name.data, ngx_palloc(pool, file->name.len + 1), NGX_ERROR); #if 0 for (i = 0; i < file->name.len; i++) { file->name.data[i] = 'X'; } #endif ngx_memcpy(file->name.data, path->name.data, path->name.len); num = ngx_next_temp_number(0); for ( ;; ) { ngx_snprintf((char *) (file->name.data + path->name.len + 1 + path->len), 11, "%010u", num); ngx_create_hashed_filename(file, path); #if 1 file->fd = ngx_open_tempfile(file->name.data, persistent); #else file->fd = ngx_open_tempfile(file->name.data, 1); #endif ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, "temp fd:%d", file->fd); if (file->fd != NGX_INVALID_FILE) { return NGX_OK; } err = ngx_errno; if (err == NGX_EEXIST) { num = ngx_next_temp_number(1); continue; } if ((path->level[0] == 0) || (err != NGX_ENOENT #if (WIN32) && err != NGX_ENOTDIR #endif )) { ngx_log_error(NGX_LOG_CRIT, file->log, err, ngx_open_tempfile_n " \"%s\" failed", file->name.data); return NGX_ERROR; } if (ngx_create_path(file, path) == NGX_ERROR) { return NGX_ERROR; } } }