1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#ifndef _NGX_HTTP_CACHE_H_INCLUDED_
9e18a033bSKonstantin Ananyev#define _NGX_HTTP_CACHE_H_INCLUDED_
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyev#include <ngx_config.h>
13e18a033bSKonstantin Ananyev#include <ngx_core.h>
14e18a033bSKonstantin Ananyev#include <ngx_http.h>
15e18a033bSKonstantin Ananyev
16e18a033bSKonstantin Ananyev
17e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_MISS          1
18e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_BYPASS        2
19e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_EXPIRED       3
20e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_STALE         4
21e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_UPDATING      5
22e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_REVALIDATED   6
23e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_HIT           7
24e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_SCARCE        8
25e18a033bSKonstantin Ananyev
26e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_KEY_LEN       16
27e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_ETAG_LEN      128
28e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_VARY_LEN      128
29e18a033bSKonstantin Ananyev
30e18a033bSKonstantin Ananyev#define NGX_HTTP_CACHE_VERSION       5
31e18a033bSKonstantin Ananyev
32e18a033bSKonstantin Ananyev
33e18a033bSKonstantin Ananyevtypedef struct {
34e18a033bSKonstantin Ananyev    ngx_uint_t                       status;
35e18a033bSKonstantin Ananyev    time_t                           valid;
36e18a033bSKonstantin Ananyev} ngx_http_cache_valid_t;
37e18a033bSKonstantin Ananyev
38e18a033bSKonstantin Ananyev
39e18a033bSKonstantin Ananyevtypedef struct {
40e18a033bSKonstantin Ananyev    ngx_rbtree_node_t                node;
41e18a033bSKonstantin Ananyev    ngx_queue_t                      queue;
42e18a033bSKonstantin Ananyev
43e18a033bSKonstantin Ananyev    u_char                           key[NGX_HTTP_CACHE_KEY_LEN
44e18a033bSKonstantin Ananyev                                         - sizeof(ngx_rbtree_key_t)];
45e18a033bSKonstantin Ananyev
46e18a033bSKonstantin Ananyev    unsigned                         count:20;
47e18a033bSKonstantin Ananyev    unsigned                         uses:10;
48e18a033bSKonstantin Ananyev    unsigned                         valid_msec:10;
49e18a033bSKonstantin Ananyev    unsigned                         error:10;
50e18a033bSKonstantin Ananyev    unsigned                         exists:1;
51e18a033bSKonstantin Ananyev    unsigned                         updating:1;
52e18a033bSKonstantin Ananyev    unsigned                         deleting:1;
53e18a033bSKonstantin Ananyev    unsigned                         purged:1;
54e18a033bSKonstantin Ananyev                                     /* 10 unused bits */
55e18a033bSKonstantin Ananyev
56e18a033bSKonstantin Ananyev    ngx_file_uniq_t                  uniq;
57e18a033bSKonstantin Ananyev    time_t                           expire;
58e18a033bSKonstantin Ananyev    time_t                           valid_sec;
59e18a033bSKonstantin Ananyev    size_t                           body_start;
60e18a033bSKonstantin Ananyev    off_t                            fs_size;
61e18a033bSKonstantin Ananyev    ngx_msec_t                       lock_time;
62e18a033bSKonstantin Ananyev} ngx_http_file_cache_node_t;
63e18a033bSKonstantin Ananyev
64e18a033bSKonstantin Ananyev
65e18a033bSKonstantin Ananyevstruct ngx_http_cache_s {
66e18a033bSKonstantin Ananyev    ngx_file_t                       file;
67e18a033bSKonstantin Ananyev    ngx_array_t                      keys;
68e18a033bSKonstantin Ananyev    uint32_t                         crc32;
69e18a033bSKonstantin Ananyev    u_char                           key[NGX_HTTP_CACHE_KEY_LEN];
70e18a033bSKonstantin Ananyev    u_char                           main[NGX_HTTP_CACHE_KEY_LEN];
71e18a033bSKonstantin Ananyev
72e18a033bSKonstantin Ananyev    ngx_file_uniq_t                  uniq;
73e18a033bSKonstantin Ananyev    time_t                           valid_sec;
74e18a033bSKonstantin Ananyev    time_t                           updating_sec;
75e18a033bSKonstantin Ananyev    time_t                           error_sec;
76e18a033bSKonstantin Ananyev    time_t                           last_modified;
77e18a033bSKonstantin Ananyev    time_t                           date;
78e18a033bSKonstantin Ananyev
79e18a033bSKonstantin Ananyev    ngx_str_t                        etag;
80e18a033bSKonstantin Ananyev    ngx_str_t                        vary;
81e18a033bSKonstantin Ananyev    u_char                           variant[NGX_HTTP_CACHE_KEY_LEN];
82e18a033bSKonstantin Ananyev
83e18a033bSKonstantin Ananyev    size_t                           header_start;
84e18a033bSKonstantin Ananyev    size_t                           body_start;
85e18a033bSKonstantin Ananyev    off_t                            length;
86e18a033bSKonstantin Ananyev    off_t                            fs_size;
87e18a033bSKonstantin Ananyev
88e18a033bSKonstantin Ananyev    ngx_uint_t                       min_uses;
89e18a033bSKonstantin Ananyev    ngx_uint_t                       error;
90e18a033bSKonstantin Ananyev    ngx_uint_t                       valid_msec;
91e18a033bSKonstantin Ananyev    ngx_uint_t                       vary_tag;
92e18a033bSKonstantin Ananyev
93e18a033bSKonstantin Ananyev    ngx_buf_t                       *buf;
94e18a033bSKonstantin Ananyev
95e18a033bSKonstantin Ananyev    ngx_http_file_cache_t           *file_cache;
96e18a033bSKonstantin Ananyev    ngx_http_file_cache_node_t      *node;
97e18a033bSKonstantin Ananyev
98e18a033bSKonstantin Ananyev#if (NGX_THREADS || NGX_COMPAT)
99e18a033bSKonstantin Ananyev    ngx_thread_task_t               *thread_task;
100e18a033bSKonstantin Ananyev#endif
101e18a033bSKonstantin Ananyev
102e18a033bSKonstantin Ananyev    ngx_msec_t                       lock_timeout;
103e18a033bSKonstantin Ananyev    ngx_msec_t                       lock_age;
104e18a033bSKonstantin Ananyev    ngx_msec_t                       lock_time;
105e18a033bSKonstantin Ananyev    ngx_msec_t                       wait_time;
106e18a033bSKonstantin Ananyev
107e18a033bSKonstantin Ananyev    ngx_event_t                      wait_event;
108e18a033bSKonstantin Ananyev
109e18a033bSKonstantin Ananyev    unsigned                         lock:1;
110e18a033bSKonstantin Ananyev    unsigned                         waiting:1;
111e18a033bSKonstantin Ananyev
112e18a033bSKonstantin Ananyev    unsigned                         updated:1;
113e18a033bSKonstantin Ananyev    unsigned                         updating:1;
114e18a033bSKonstantin Ananyev    unsigned                         exists:1;
115e18a033bSKonstantin Ananyev    unsigned                         temp_file:1;
116e18a033bSKonstantin Ananyev    unsigned                         purged:1;
117e18a033bSKonstantin Ananyev    unsigned                         reading:1;
118e18a033bSKonstantin Ananyev    unsigned                         secondary:1;
119e18a033bSKonstantin Ananyev    unsigned                         background:1;
120e18a033bSKonstantin Ananyev
121e18a033bSKonstantin Ananyev    unsigned                         stale_updating:1;
122e18a033bSKonstantin Ananyev    unsigned                         stale_error:1;
123e18a033bSKonstantin Ananyev};
124e18a033bSKonstantin Ananyev
125e18a033bSKonstantin Ananyev
126e18a033bSKonstantin Ananyevtypedef struct {
127e18a033bSKonstantin Ananyev    ngx_uint_t                       version;
128e18a033bSKonstantin Ananyev    time_t                           valid_sec;
129e18a033bSKonstantin Ananyev    time_t                           updating_sec;
130e18a033bSKonstantin Ananyev    time_t                           error_sec;
131e18a033bSKonstantin Ananyev    time_t                           last_modified;
132e18a033bSKonstantin Ananyev    time_t                           date;
133e18a033bSKonstantin Ananyev    uint32_t                         crc32;
134e18a033bSKonstantin Ananyev    u_short                          valid_msec;
135e18a033bSKonstantin Ananyev    u_short                          header_start;
136e18a033bSKonstantin Ananyev    u_short                          body_start;
137e18a033bSKonstantin Ananyev    u_char                           etag_len;
138e18a033bSKonstantin Ananyev    u_char                           etag[NGX_HTTP_CACHE_ETAG_LEN];
139e18a033bSKonstantin Ananyev    u_char                           vary_len;
140e18a033bSKonstantin Ananyev    u_char                           vary[NGX_HTTP_CACHE_VARY_LEN];
141e18a033bSKonstantin Ananyev    u_char                           variant[NGX_HTTP_CACHE_KEY_LEN];
142e18a033bSKonstantin Ananyev} ngx_http_file_cache_header_t;
143e18a033bSKonstantin Ananyev
144e18a033bSKonstantin Ananyev
145e18a033bSKonstantin Ananyevtypedef struct {
146e18a033bSKonstantin Ananyev    ngx_rbtree_t                     rbtree;
147e18a033bSKonstantin Ananyev    ngx_rbtree_node_t                sentinel;
148e18a033bSKonstantin Ananyev    ngx_queue_t                      queue;
149e18a033bSKonstantin Ananyev    ngx_atomic_t                     cold;
150e18a033bSKonstantin Ananyev    ngx_atomic_t                     loading;
151e18a033bSKonstantin Ananyev    off_t                            size;
152e18a033bSKonstantin Ananyev    ngx_uint_t                       count;
153e18a033bSKonstantin Ananyev    ngx_uint_t                       watermark;
154e18a033bSKonstantin Ananyev} ngx_http_file_cache_sh_t;
155e18a033bSKonstantin Ananyev
156e18a033bSKonstantin Ananyev
157e18a033bSKonstantin Ananyevstruct ngx_http_file_cache_s {
158e18a033bSKonstantin Ananyev    ngx_http_file_cache_sh_t        *sh;
159e18a033bSKonstantin Ananyev    ngx_slab_pool_t                 *shpool;
160e18a033bSKonstantin Ananyev
161e18a033bSKonstantin Ananyev    ngx_path_t                      *path;
162e18a033bSKonstantin Ananyev
163e18a033bSKonstantin Ananyev    off_t                            max_size;
164e18a033bSKonstantin Ananyev    size_t                           bsize;
165e18a033bSKonstantin Ananyev
166e18a033bSKonstantin Ananyev    time_t                           inactive;
167e18a033bSKonstantin Ananyev
168e18a033bSKonstantin Ananyev    time_t                           fail_time;
169e18a033bSKonstantin Ananyev
170e18a033bSKonstantin Ananyev    ngx_uint_t                       files;
171e18a033bSKonstantin Ananyev    ngx_uint_t                       loader_files;
172e18a033bSKonstantin Ananyev    ngx_msec_t                       last;
173e18a033bSKonstantin Ananyev    ngx_msec_t                       loader_sleep;
174e18a033bSKonstantin Ananyev    ngx_msec_t                       loader_threshold;
175e18a033bSKonstantin Ananyev
176e18a033bSKonstantin Ananyev    ngx_uint_t                       manager_files;
177e18a033bSKonstantin Ananyev    ngx_msec_t                       manager_sleep;
178e18a033bSKonstantin Ananyev    ngx_msec_t                       manager_threshold;
179e18a033bSKonstantin Ananyev
180e18a033bSKonstantin Ananyev    ngx_shm_zone_t                  *shm_zone;
181e18a033bSKonstantin Ananyev
182e18a033bSKonstantin Ananyev    ngx_uint_t                       use_temp_path;
183e18a033bSKonstantin Ananyev                                     /* unsigned use_temp_path:1 */
184e18a033bSKonstantin Ananyev};
185e18a033bSKonstantin Ananyev
186e18a033bSKonstantin Ananyev
187e18a033bSKonstantin Ananyevngx_int_t ngx_http_file_cache_new(ngx_http_request_t *r);
188e18a033bSKonstantin Ananyevngx_int_t ngx_http_file_cache_create(ngx_http_request_t *r);
189e18a033bSKonstantin Ananyevvoid ngx_http_file_cache_create_key(ngx_http_request_t *r);
190e18a033bSKonstantin Ananyevngx_int_t ngx_http_file_cache_open(ngx_http_request_t *r);
191e18a033bSKonstantin Ananyevngx_int_t ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf);
192e18a033bSKonstantin Ananyevvoid ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf);
193e18a033bSKonstantin Ananyevvoid ngx_http_file_cache_update_header(ngx_http_request_t *r);
194e18a033bSKonstantin Ananyevngx_int_t ngx_http_cache_send(ngx_http_request_t *);
195e18a033bSKonstantin Ananyevvoid ngx_http_file_cache_free(ngx_http_cache_t *c, ngx_temp_file_t *tf);
196e18a033bSKonstantin Ananyevtime_t ngx_http_file_cache_valid(ngx_array_t *cache_valid, ngx_uint_t status);
197e18a033bSKonstantin Ananyev
198e18a033bSKonstantin Ananyevchar *ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
199e18a033bSKonstantin Ananyev    void *conf);
200e18a033bSKonstantin Ananyevchar *ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
201e18a033bSKonstantin Ananyev    void *conf);
202e18a033bSKonstantin Ananyev
203e18a033bSKonstantin Ananyev
204e18a033bSKonstantin Ananyevextern ngx_str_t  ngx_http_cache_status[];
205e18a033bSKonstantin Ananyev
206e18a033bSKonstantin Ananyev
207e18a033bSKonstantin Ananyev#endif /* _NGX_HTTP_CACHE_H_INCLUDED_ */
208