1 
2 /*
3  * Copyright (C) Yichun Zhang (agentzh)
4  */
5 
6 
7 #ifndef DDEBUG
8 #define DDEBUG 0
9 #endif
10 #include "ddebug.h"
11 
12 
13 #include "ngx_http_srcache_var.h"
14 
15 
16 static ngx_int_t ngx_http_srcache_expire_variable(ngx_http_request_t *r,
17     ngx_http_variable_value_t *v, uintptr_t data);
18 static ngx_int_t ngx_http_srcache_fetch_status_variable(ngx_http_request_t *r,
19     ngx_http_variable_value_t *v, uintptr_t data);
20 static ngx_int_t ngx_http_srcache_store_status_variable(ngx_http_request_t *r,
21     ngx_http_variable_value_t *v, uintptr_t data);
22 
23 
24 static ngx_str_t  ngx_http_srcache_fetch_status[] = {
25     ngx_string("BYPASS"),
26     ngx_string("MISS"),
27     ngx_string("HIT")
28 };
29 
30 
31 static ngx_str_t  ngx_http_srcache_store_status[] = {
32     ngx_string("BYPASS"),
33     ngx_string("STORE"),
34 };
35 
36 
37 static ngx_http_variable_t ngx_http_srcache_variables[] = {
38 
39     { ngx_string("srcache_expire"), NULL,
40       ngx_http_srcache_expire_variable, 0,
41       NGX_HTTP_VAR_NOCACHEABLE, 0 },
42 
43     { ngx_string("srcache_fetch_status"), NULL,
44       ngx_http_srcache_fetch_status_variable, 0,
45       NGX_HTTP_VAR_NOCACHEABLE, 0 },
46 
47     { ngx_string("srcache_store_status"), NULL,
48       ngx_http_srcache_store_status_variable, 0,
49       NGX_HTTP_VAR_NOCACHEABLE, 0 },
50 
51     { ngx_null_string, NULL, NULL, 0, 0, 0 }
52 };
53 
54 
55 static ngx_int_t
ngx_http_srcache_expire_variable(ngx_http_request_t * r,ngx_http_variable_value_t * v,uintptr_t data)56 ngx_http_srcache_expire_variable(ngx_http_request_t *r,
57     ngx_http_variable_value_t *v, uintptr_t data)
58 {
59     ngx_http_srcache_ctx_t       *ctx;
60     u_char                       *p;
61     time_t                        expire;
62     ngx_http_srcache_loc_conf_t  *conf;
63 
64     conf = ngx_http_get_module_loc_conf(r, ngx_http_srcache_filter_module);
65 
66     v->valid = 1;
67     v->no_cacheable = 1;
68     v->not_found = 0;
69 
70     ctx = ngx_http_get_module_ctx(r, ngx_http_srcache_filter_module);
71 
72     if (!ctx || !ctx->store_response) {
73         v->not_found = 1;
74         return NGX_OK;
75     }
76 
77     if (ctx->valid_sec == 0) {
78         expire = conf->default_expire;
79 
80     } else {
81         expire = ctx->valid_sec - ngx_time();
82     }
83 
84     if (conf->max_expire > 0 && expire > conf->max_expire) {
85         expire = conf->max_expire;
86     }
87 
88     p = ngx_palloc(r->pool, NGX_TIME_T_LEN);
89     if (p == NULL) {
90         return NGX_ERROR;
91     }
92 
93     v->data = p;
94     p =  ngx_sprintf(p, "%T", expire);
95     v->len = p - v->data;
96 
97     return NGX_OK;
98 }
99 
100 
101 static ngx_int_t
ngx_http_srcache_fetch_status_variable(ngx_http_request_t * r,ngx_http_variable_value_t * v,uintptr_t data)102 ngx_http_srcache_fetch_status_variable(ngx_http_request_t *r,
103     ngx_http_variable_value_t *v, uintptr_t data)
104 {
105     ngx_uint_t                    status;
106     ngx_http_srcache_ctx_t       *ctx;
107 
108     ctx = ngx_http_get_module_ctx(r, ngx_http_srcache_filter_module);
109 
110     if (ctx == NULL) {
111         status = NGX_HTTP_SRCACHE_FETCH_BYPASS;
112 
113     } else if (ctx->from_cache) {
114         status = NGX_HTTP_SRCACHE_FETCH_HIT;
115 
116     } else if (ctx->issued_fetch_subrequest) {
117         status = NGX_HTTP_SRCACHE_FETCH_MISS;
118 
119     } else {
120         status = NGX_HTTP_SRCACHE_FETCH_BYPASS;
121     }
122 
123     v->valid = 1;
124     v->no_cacheable = 1;
125     v->not_found = 0;
126 
127     v->len = ngx_http_srcache_fetch_status[status].len;
128     v->data = ngx_http_srcache_fetch_status[status].data;
129 
130     return NGX_OK;
131 }
132 
133 
134 static ngx_int_t
ngx_http_srcache_store_status_variable(ngx_http_request_t * r,ngx_http_variable_value_t * v,uintptr_t data)135 ngx_http_srcache_store_status_variable(ngx_http_request_t *r,
136     ngx_http_variable_value_t *v, uintptr_t data)
137 {
138     ngx_uint_t                    status;
139     ngx_http_srcache_ctx_t       *ctx;
140 
141     ctx = ngx_http_get_module_ctx(r, ngx_http_srcache_filter_module);
142 
143     if (ctx && ctx->store_response) {
144         status = NGX_HTTP_SRCACHE_STORE_STORE;
145 
146     } else {
147         status = NGX_HTTP_SRCACHE_STORE_BYPASS;
148 
149     }
150 
151     v->valid = 1;
152     v->no_cacheable = 1;
153     v->not_found = 0;
154 
155     v->len = ngx_http_srcache_store_status[status].len;
156     v->data = ngx_http_srcache_store_status[status].data;
157 
158     return NGX_OK;
159 }
160 
161 
162 ngx_int_t
ngx_http_srcache_add_variables(ngx_conf_t * cf)163 ngx_http_srcache_add_variables(ngx_conf_t *cf)
164 {
165     ngx_http_variable_t *var, *v;
166 
167     for (v = ngx_http_srcache_variables; v->name.len; v++) {
168         var = ngx_http_add_variable(cf, &v->name, v->flags);
169         if (var == NULL) {
170             return NGX_ERROR;
171         }
172 
173         var->get_handler = v->get_handler;
174         var->data = v->data;
175     }
176 
177     return NGX_OK;
178 }
179 
180 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
181