comparison src/http/modules/ngx_http_headers_filter.c @ 0:f0b350454894 NGINX_0_1_0

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