Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_headers_filter.c @ 326:8733703a37f3
nginx-0.0.3-2004-04-26-00:13:21 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 25 Apr 2004 20:13:21 +0000 |
parents | |
children | 2e3cbc1bbe3c |
comparison
equal
deleted
inserted
replaced
325:7c3323909107 | 326:8733703a37f3 |
---|---|
1 | |
2 #include <ngx_config.h> | |
3 #include <ngx_core.h> | |
4 #include <ngx_http.h> | |
5 | |
6 | |
7 typedef struct { | |
8 time_t expires; | |
9 } ngx_http_headers_conf_t; | |
10 | |
11 | |
12 #define NGX_HTTP_EXPIRES_UNSET -2147483647 | |
13 #define NGX_HTTP_EXPIRES_OFF -2147483646 | |
14 #define NGX_HTTP_EXPIRES_EPOCH -2147483645 | |
15 | |
16 | |
17 static int ngx_http_headers_filter_init(ngx_cycle_t *cycle); | |
18 static void *ngx_http_headers_create_conf(ngx_conf_t *cf); | |
19 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, | |
20 void *parent, void *child); | |
21 char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
22 | |
23 | |
24 static ngx_command_t ngx_http_headers_filter_commands[] = { | |
25 | |
26 { ngx_string("expires"), | |
27 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
28 ngx_http_headers_expires, | |
29 NGX_HTTP_LOC_CONF_OFFSET, | |
30 0, | |
31 NULL}, | |
32 | |
33 ngx_null_command | |
34 }; | |
35 | |
36 | |
37 static ngx_http_module_t ngx_http_headers_filter_module_ctx = { | |
38 NULL, /* pre conf */ | |
39 | |
40 NULL, /* create main configuration */ | |
41 NULL, /* init main configuration */ | |
42 | |
43 NULL, /* create server configuration */ | |
44 NULL, /* merge server configuration */ | |
45 | |
46 ngx_http_headers_create_conf, /* create location configuration */ | |
47 ngx_http_headers_merge_conf /* merge location configuration */ | |
48 }; | |
49 | |
50 | |
51 ngx_module_t ngx_http_headers_filter_module = { | |
52 NGX_MODULE, | |
53 &ngx_http_headers_filter_module_ctx, /* module context */ | |
54 ngx_http_headers_filter_commands, /* module directives */ | |
55 NGX_HTTP_MODULE, /* module type */ | |
56 ngx_http_headers_filter_init, /* init module */ | |
57 NULL /* init child */ | |
58 }; | |
59 | |
60 | |
61 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
62 | |
63 | |
64 static int ngx_http_headers_filter(ngx_http_request_t *r) | |
65 { | |
66 size_t len; | |
67 ngx_table_elt_t *expires, *cc; | |
68 ngx_http_headers_conf_t *conf; | |
69 | |
70 if (r->headers_out.status != NGX_HTTP_OK) { | |
71 return ngx_http_next_header_filter(r); | |
72 } | |
73 | |
74 conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); | |
75 | |
76 if (conf->expires != NGX_HTTP_EXPIRES_OFF) { | |
77 | |
78 expires = ngx_http_add_header(&r->headers_out, ngx_http_headers_out); | |
79 if (expires == NULL) { | |
80 return NGX_ERROR; | |
81 } | |
82 | |
83 r->headers_out.expires = expires; | |
84 | |
85 cc = ngx_http_add_header(&r->headers_out, ngx_http_headers_out); | |
86 if (cc == NULL) { | |
87 return NGX_ERROR; | |
88 } | |
89 | |
90 r->headers_out.cache_control = cc; | |
91 | |
92 len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT"); | |
93 | |
94 expires->key.len = sizeof("Expires") - 1; | |
95 expires->key.data = (u_char *) "Expires"; | |
96 expires->value.len = len - 1; | |
97 | |
98 cc->key.len = sizeof("Cache-Control") - 1; | |
99 cc->key.data = (u_char *) "Cache-Control"; | |
100 | |
101 if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) { | |
102 expires->value.data = (u_char *) "Thu, 01 Jan 1970 00:00:01 GMT"; | |
103 | |
104 cc->value.len = sizeof("no-cache") - 1; | |
105 cc->value.data = (u_char *) "no-cache"; | |
106 | |
107 } else { | |
108 expires->value.data = ngx_palloc(r->pool, len); | |
109 if (expires->value.data == NULL) { | |
110 return NGX_ERROR; | |
111 } | |
112 | |
113 if (conf->expires == 0) { | |
114 ngx_memcpy(expires->value.data, ngx_cached_http_time.data, | |
115 ngx_cached_http_time.len + 1); | |
116 | |
117 cc->value.len = sizeof("max-age=0") - 1; | |
118 cc->value.data = (u_char *) "max-age=0"; | |
119 | |
120 } else { | |
121 ngx_http_time(expires->value.data, | |
122 ngx_cached_time + conf->expires); | |
123 | |
124 if (conf->expires < 0) { | |
125 cc->value.len = sizeof("no-cache") - 1; | |
126 cc->value.data = (u_char *) "no-cache"; | |
127 | |
128 } else { | |
129 cc->value.data = ngx_palloc(r->pool, NGX_TIME_T_LEN + 1); | |
130 if (cc->value.data == NULL) { | |
131 return NGX_ERROR; | |
132 } | |
133 | |
134 cc->value.len = ngx_snprintf((char *) cc->value.data, | |
135 sizeof("max-age=") | |
136 + NGX_TIME_T_LEN, | |
137 "max-age=" TIME_T_FMT, | |
138 conf->expires); | |
139 } | |
140 } | |
141 } | |
142 } | |
143 | |
144 return ngx_http_next_header_filter(r); | |
145 } | |
146 | |
147 | |
148 static int ngx_http_headers_filter_init(ngx_cycle_t *cycle) | |
149 { | |
150 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
151 ngx_http_top_header_filter = ngx_http_headers_filter; | |
152 | |
153 return NGX_OK; | |
154 } | |
155 | |
156 | |
157 static void *ngx_http_headers_create_conf(ngx_conf_t *cf) | |
158 { | |
159 ngx_http_headers_conf_t *conf; | |
160 | |
161 if (!(conf = ngx_palloc(cf->pool, sizeof(ngx_http_headers_conf_t)))) { | |
162 return NGX_CONF_ERROR; | |
163 } | |
164 | |
165 conf->expires = NGX_HTTP_EXPIRES_UNSET; | |
166 | |
167 return conf; | |
168 } | |
169 | |
170 | |
171 static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, | |
172 void *parent, void *child) | |
173 { | |
174 ngx_http_headers_conf_t *prev = parent; | |
175 ngx_http_headers_conf_t *conf = child; | |
176 | |
177 if (conf->expires == NGX_HTTP_EXPIRES_UNSET) { | |
178 conf->expires = (prev->expires == NGX_HTTP_EXPIRES_UNSET) ? | |
179 NGX_HTTP_EXPIRES_OFF : prev->expires; | |
180 } | |
181 | |
182 return NGX_CONF_OK; | |
183 } | |
184 | |
185 | |
186 char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
187 { | |
188 ngx_http_headers_conf_t *hcf = conf; | |
189 | |
190 ngx_uint_t minus; | |
191 ngx_str_t *value; | |
192 | |
193 if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) { | |
194 return "is duplicate"; | |
195 } | |
196 | |
197 value = cf->args->elts; | |
198 | |
199 if (ngx_strcmp(value[1].data, "epoch") == 0) { | |
200 hcf->expires = NGX_HTTP_EXPIRES_EPOCH; | |
201 return NGX_CONF_OK; | |
202 } | |
203 | |
204 if (ngx_strcmp(value[1].data, "off") == 0) { | |
205 hcf->expires = NGX_HTTP_EXPIRES_OFF; | |
206 return NGX_CONF_OK; | |
207 } | |
208 | |
209 if (value[1].data[0] == '+') { | |
210 value[1].data++; | |
211 value[1].len--; | |
212 minus = 0; | |
213 | |
214 } else if (value[1].data[0] == '-') { | |
215 value[1].data++; | |
216 value[1].len--; | |
217 minus = 1; | |
218 | |
219 } else { | |
220 minus = 0; | |
221 } | |
222 | |
223 hcf->expires = ngx_parse_time(&value[1], 1); | |
224 if (hcf->expires == NGX_ERROR) { | |
225 return "invalid value"; | |
226 } | |
227 | |
228 if (hcf->expires == NGX_PARSE_LARGE_TIME) { | |
229 return "value must be less than 68 years"; | |
230 } | |
231 | |
232 if (minus) { | |
233 hcf->expires = - hcf->expires; | |
234 } | |
235 | |
236 return NGX_CONF_OK; | |
237 } |