comparison src/http/modules/ngx_http_ssi_filter.c @ 125:885ffb8cc32a

nginx-0.0.1-2003-08-06-09:30:51 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 06 Aug 2003 05:30:51 +0000
parents 6ce4755737b4
children fcc79370b9a8
comparison
equal deleted inserted replaced
124:842a78cebbb7 125:885ffb8cc32a
1 1
2 #include <ngx_config.h> 2 #include <ngx_config.h>
3 #include <ngx_core.h> 3 #include <ngx_core.h>
4 #include <ngx_hunk.h>
5 #include <ngx_event_write.h>
6 #include <ngx_http.h> 4 #include <ngx_http.h>
7 #include <ngx_http_config.h>
8 5
9 6
10 static ngx_command_t ngx_http_ssi_filter_commands[]; 7 typedef struct {
8 } ngx_http_ssi_filter_ctx_t;
11 9
12 static void *ngx_http_ssi_filter_create_conf(ngx_pool_t *pool);
13 10
14 ngx_http_module_t ngx_http_ssi_filter_module = { 11 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle);
15 NGX_HTTP_MODULE, 12
16 NULL, /* create server config */ 13
17 ngx_http_ssi_filter_create_conf, /* create location config */ 14 static ngx_http_module_t ngx_http_ssi_filter_module_ctx = {
18 ngx_http_ssi_filter_commands, /* module directives */ 15 NULL, /* create main configuration */
19 NULL, /* init module */ 16 NULL, /* init main configuration */
20 NULL /* init output body filter */ 17
18 NULL, /* create server configuration */
19 NULL, /* merge server configuration */
20
21 NULL, /* create location configuration */
22 NULL, /* merge location configuration */
23 };
24
25
26 ngx_module_t ngx_http_ssi_filter_module = {
27 NGX_MODULE,
28 &ngx_http_ssi_filter_module_ctx, /* module context */
29 NULL, /* module directives */
30 NGX_HTTP_MODULE, /* module type */
31 ngx_http_ssi_filter_init, /* init module */
32 NULL /* init child */
21 }; 33 };
22 34
23 35
24 static ngx_command_t ngx_http_ssi_filter_commands[] = { 36 static int (*next_header_filter) (ngx_http_request_t *r);
25 37 static int (*next_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
26 {"ssi", ngx_conf_set_flag_slot,
27 offsetof(ngx_http_ssi_filter_conf_t, on),
28 NGX_HTTP_LOC_CONF, NGX_CONF_FLAG,
29 "enable ssi filter"},
30
31 {NULL}
32
33 };
34 38
35 39
36 int ngx_http_ssi_filter(ngx_http_request_t *r, ngx_chain_t *in) 40 static int ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
37 { 41 {
38 ngx_chain_t *ch, **prev, *chain;
39 ngx_http_ssi_filter_ctx_t *ctx;
40 ngx_http_ssi_filter_conf_t *conf;
41 42
42 if (in == NULL)
43 return next_filter;
44
45 ctx = (ngx_http_ssi_filter_ctx_t *)
46 ngx_get_module_ctx(r, ngx_http_ssi_filter_module);
47 if (ctx == NULL) {
48 ngx_http_create_ctx(r, ctx,
49 ngx_http_ssi_filter_module,
50 sizeof(ngx_http_ssi_filter_ctx_t));
51
52 ctx->state = &ssi_start;
53 ctx->handler = ngx_http_ssi_find_start;
54 }
55
56 ch = in;
57 ctx->start = ctx->pos = ch->hunk->pos.mem;
58
59 for ( ;; ) {
60 if (ctx->handler(r, ctx, ch) == NGX_ERROR)
61 return NGX_ERROR;
62
63 if (ctx->pos + ctx->length == ch->hunk->last.mem) {
64 ch = ch->next;
65 if (ch == NULL)
66 break;
67
68 ctx->start = ctx->pos = ch->hunk->pos.mem;
69 }
70 }
71 } 43 }
72 44
73 45
46 static void ngx_http_ssi_parse()
47 {
48 for ( ) {
49 switch (state) {
50 case ssi_start_state:
74 51
75 static int ngx_http_ssi_find_start(ngx_http_request_t *r, 52 /* tight loop */
76 ngx_http_ssi_filter_ctx_t *ctx, 53 while (p < h->last) {
77 ngx_chain_t *ch) 54 if (*p++ == '<') {
78 { 55 state = ssi_comment_state;
79 ngx_http_ssi_parse(r, ctx, ch->hunk); 56 length = 1;
57 break;
58 }
59 }
80 60
81 if (ctx->state == ssi_command_state 61 /* fall through */
82 || (ctx->length > 0 && ch->next == NULL)
83 || ctx->hunk_with_ssi)
84 {
85 ngx_test_null(h, ngx_palloc(r->pool, sizeof(ngx_hunk_t)), NGX_ERROR);
86 #if !(HAVE_OFFSET_EQUAL_PTR)
87 h->pos.file = h->last.file = 0;
88 #endif
89 h->pre_start = h->start = h->pos.mem = ctx->start;
90 h->post_end = h->end = h->last.mem = ctx->pos;
91 h->type = NGX_HUNK_TEMP;
92 h->tag = 0;
93 h->file = NULL;
94 62
95 ngx_add_hunk_to_chain(ctx->last, h, r->pool, NGX_ERROR); 63 case ssi_comment_state:
96
97 ngx_test_null(ssi_hunk, ngx_push_array(ctx->ssi_hunks), NGX_ERROR);
98 ssi_hunk->ssi_hunk = h;
99 ssi_hunk->hunk = ch->hunk;
100 ssi_hunk->pos = NULL;
101 }
102
103 if (ctx->state == ssi_command_state)
104 ctx->handler = ngx_http_ssi_find_command;
105 }
106
107 return NGX_OK;
108 }
109
110
111 static int ngx_http_ssi_find_command(ngx_http_request_t *r,
112 ngx_http_ssi_filter_ctx_t *ctx,
113 ngx_chain_t *ch)
114 {
115 ngx_http_ssi_parse_command(r, ctx, ch->hunk);
116 }
117
118
119 static char ssi_start[] = "<!--#";
120
121 static char ssi_include[] = "include";
122
123 static ssi_parser_t ssi_pre_command_state[] = {
124 { 1, (char *) ' ', ssi_pre_command_state, NULL },
125
126 { 7, "include", ssi_command_state, ssi_include_state },
127
128 { 4, "random", ssi_command_state, NULL },
129 { 0, NULL, ssi_error_state }
130 };
131
132 static ssi_parser_t ssi_include_state[] = {
133 { 1, (char *) ' ', ssi_include_state, NULL },
134 { 7, "virtual", ssi_equal_state, offsetof(ssi_include_t, virtual) },
135 { 0, NULL, ssi_error_state }
136 };
137
138 static ssi_parser_t ssi_equal_state[] = {
139 { 1, (char *) ' ', ssi_equal_state, NULL },
140 { 1, (char *) '=', ssi_param_state, NULL },
141 };
142
143 static char ssi_echo[] = "echo";
144
145 static void ngx_http_ssi_parse(ngx_http_request_t *r,
146 ngx_http_ssi_filter_ctx_t *ctx,
147 ngx_hunk_t *hunk)
148
149
150 for ( ;; ) {
151
152 for (/* void */ ; p < ch->hunk->last.mem; p++) {
153
154 switch (state) {
155
156 case ssi_start_state:
157
158 /* tight loop */
159 while (p < ch->hunk->last.mem) {
160 if (*p++ == '<') {
161 state = ssi_comment_state;
162 length = 1;
163 break;
164 }
165 }
166
167 /* fall through */
168
169 case ssi_comment_state:
170
171 if (*p == ssi_start[length]) {
172 length++;
173
174 } else {
175 length = 0;
176 flush = 1;
177 state = ssi_start_state;
178 }
179
180 if (length < 6)
181 continue;
182
183 state = ssi_space_before_command_state;
184
185 /* fall through */
186
187 case ssi_space_before_command_state:
188
189 if (*p == ' ' || *p == '\t' || *p == CR || *p == LF)
190 continue;
191
192 state = ssi_command_state;
193
194 /* fall through */
195
196 case ssi_choose_command_state:
197
198 for (i = 0; ctx->name[i].len; i++) {
199 if (*p == ctx->name[i].name[0]) {
200 state = choos[i].state;
201 }
202 }
203
204 case ssi_command_state:
205 if (*p == ssi_include[n];
206 n++;
207
208 break;
209
210 }
211 }
212
213 if (length == 6
214 || (length > 0 && ch->next == NULL)
215 || hunk_with_ssi) {
216
217 if (ctx->saved > 0 && flush) {
218 add saved
219 ctx->saved = 0;
220 }
221
222 for (c = ctx->in; c != hunk; c = c->next) {
223 ngx_add_hunk_to_chain(ctx->last, c->hunk,
224 r->pool, NGX_ERROR);
225 }
226
227 add duped;
228 push duped_hunk, hunk, NULL;
229
230 n = length - (hunk->last.mem - pos);
231 for (c = hunk; c; c->next) {
232 if (n > c->hunk->last.mem - c->hunk->pos.mem) {
233 n -= c->hunk->last.mem - c->hunk->pos.mem;
234 push NULL, c->hunk, NULL;
235 }
236 }
237
238 ctx->in = c;
239 }
240 }
241
242 } else {
243
244 for (/* void */ ; p < ch->hunk->last.mem; p++) {
245 if (*p == ' ' || *p == '\t' || *p == CR || *P == LF)
246 continue;
247
248 ctx->state = ssi_command_state;
249 break; 64 break;
250 }
251
252 if (
253 65
254 } 66 }
255 } 67 }
256 68
257 69
70 static int ngx_http_ssi_filter_init(ngx_cycle_t *cycle)
71 {
72 next_header_filter = ngx_http_top_header_filter;
73 ngx_http_top_header_filter = ngx_http_ssi_header_filter;
258 74
75 next_body_filter = ngx_http_top_body_filter;
76 ngx_http_top_body_filter = ngx_http_ssi_body_filter;
259 77
260 78 return NGX_OK;
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295 static void *ngx_http_ssi_filter_create_conf(ngx_pool_t *pool)
296 {
297 ngx_http_ssi_filter_conf_t *conf;
298
299 ngx_test_null(conf,
300 ngx_palloc(pool, sizeof(ngx_http_ssi_filter_conf_t)),
301 NULL);
302
303 conf->buffer_output = NGX_CONF_UNSET;
304
305 return conf;
306 } 79 }