comparison src/http/modules/ngx_http_ssi_filter.c @ 14:f8a0d0f31a24

nginx-0.0.1-2002-09-17-21:49:32 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 17 Sep 2002 17:49:32 +0000
parents
children cbb38b60495c
comparison
equal deleted inserted replaced
13:2aba961a1d34 14:f8a0d0f31a24
1
2 #include <ngx_config.h>
3 #include <ngx_core.h>
4 #include <ngx_hunk.h>
5 #include <ngx_event_write.h>
6 #include <ngx_http.h>
7 #include <ngx_http_config.h>
8
9
10 static ngx_command_t ngx_http_ssi_filter_commands[];
11
12 static void *ngx_http_ssi_filter_create_conf(ngx_pool_t *pool);
13
14 ngx_http_module_t ngx_http_ssi_filter_module = {
15 NGX_HTTP_MODULE,
16 NULL, /* create server config */
17 ngx_http_ssi_filter_create_conf, /* create location config */
18 ngx_http_ssi_filter_commands, /* module directives */
19 NULL, /* init module */
20 NULL /* init output body filter */
21 };
22
23
24 static ngx_command_t ngx_http_ssi_filter_commands[] = {
25
26 {"ssi", ngx_conf_set_size_slot,
27 offsetof(ngx_http_write_filter_conf_t, buffer_output),
28 NGX_HTTP_LOC_CONF, NGX_CONF_TAKE1,
29 "set write filter size to buffer output"},
30
31 {NULL}
32
33 };
34
35
36 int ngx_http_ssi_filter(ngx_http_request_t *r, ngx_chain_t *in)
37 {
38 int last;
39 off_t size, flush;
40 ngx_chain_t *ch, **prev, *chain;
41 ngx_http_ssi_filter_ctx_t *ctx;
42 ngx_http_ssi_filter_conf_t *conf;
43
44 ctx = (ngx_http_ssi_filter_ctx_t *)
45 ngx_get_module_ctx(r->main ? r->main : r,
46 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 }
54
55 state = ctx->state;
56
57 ch = in;
58 p = ch->hunk->pos.mem;
59
60 for ( ;; ) {
61
62 if (state == ssi_start_state) {
63 for (/* void */ ; p < ch->hunk->last.mem; p++) {
64 if (*p == '<') {
65 state = ssi_exclam_state;
66 saved_pos = p;
67 saved_chain = ch;
68 break;
69 }
70 }
71 }
72
73 for (/* void */ ;
74 p < ch->hunk->last.mem && state > ssi_start_state;
75 p++)
76 {
77
78 if (*p == '<') {
79 state = ssi_exclam_state;
80 saved_pos = p;
81 saved_chain = ch;
82 continue;
83 }
84
85 switch (state) {
86
87 case ssi_exclam_state:
88 if (*p == '!') {
89 state = ssi_dash1_state;
90
91 else {
92 state = ssi_ssi_state;
93 saved_pos = NULL;
94 saved_chain = NULL;
95 }
96
97 break;
98
99 case ssi_dash1_state:
100 if (*p == '-') {
101 state = ssi_dash2_state;
102
103 else {
104 state = ssi_ssi_state;
105 saved_pos = NULL;
106 saved_chain = NULL;
107 }
108
109 break;
110
111 case ssi_dash2_state:
112 if (*p == '-') {
113 state = ssi_sharp_state;
114
115 else {
116 state = ssi_ssi_state;
117 saved_pos = NULL;
118 saved_chain = NULL;
119 }
120
121 break;
122
123 case ssi_sharp_state:
124 switch (*p) {
125 case '#':
126 state = ssi_command_state;
127 break;
128
129 case ' ':
130 case '\t':
131 case CR:
132 case LF:
133 break;
134
135 default:
136 state = ssi_ssi_state;
137 saved_pos = NULL;
138 saved_chain = NULL;
139 break;
140 }
141
142 break;
143 }
144 }
145
146 ch = ch->next;
147 if (ch == NULL) {
148 ctx->state = state;
149 break;
150 }
151
152 p = ch->hunk->pos.mem;
153 }
154
155 for (p = saved_pos, ch = saved_chain;
156 ch;
157 ch = ch->next, p = ch->hunk->pos.mem)
158 {
159 ngx_memcpy(saved_line, p, ch->hunk->last.mem - p);
160 saved_size += ch->hunk->last.mem - p;
161 if (ch->next == NULL)
162 break;
163 }
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 for (/* void */; in; in = in->next) {
179
180 for (p = in->hunk->pos.mem;
181 in->hunk->pos.mem < in->hunk->last.mem;
182 p++)
183 {
184 switch (state) {
185
186 case ssi_start_state:
187 if (*p == '<') {
188 state = ssi_exclam_state;
189 save_line = p;
190 }
191 break;
192
193 case ssi_exclam_state:
194 }
195 }
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216 size = flush = 0;
217 last = 0;
218 prev = &ctx->out;
219
220 /* find size, flush point and last link of saved chain */
221 for (ch = ctx->out; ch; ch = ch->next) {
222 prev = &ch->next;
223 size += ch->hunk->last.file - ch->hunk->pos.file;
224
225 ngx_log_debug(r->connection->log, "old chunk: %x " QX_FMT " " QD_FMT _
226 ch->hunk->type _ ch->hunk->pos.file _
227 ch->hunk->last.file - ch->hunk->pos.file);
228
229 if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)
230 flush = size;
231
232 if (ch->hunk->type & NGX_HUNK_LAST)
233 last = 1;
234 }
235
236 /* add new chain to existent one */
237 for (/* void */; in; in = in->next) {
238 ngx_test_null(ch, ngx_palloc(r->pool, sizeof(ngx_chain_t)), NGX_ERROR);
239
240 ch->hunk = in->hunk;
241 ch->next = NULL;
242 *prev = ch;
243 prev = &ch->next;
244 size += ch->hunk->last.file - ch->hunk->pos.file;
245
246 ngx_log_debug(r->connection->log, "new chunk: %x " QX_FMT " " QD_FMT _
247 ch->hunk->type _ ch->hunk->pos.file _
248 ch->hunk->last.file - ch->hunk->pos.file);
249
250 if (ch->hunk->type & NGX_HUNK_FLUSH|NGX_HUNK_RECYCLED)
251 flush = size;
252
253 if (ch->hunk->type & NGX_HUNK_LAST)
254 last = 1;
255 }
256
257 conf = (ngx_http_write_filter_conf_t *)
258 ngx_get_module_loc_conf(r->main ? r->main : r,
259 ngx_http_write_filter_module);
260
261 if (!last && flush == 0 && size < conf->buffer_output)
262 return NGX_OK;
263
264 chain = ngx_event_write(r->connection, ctx->out, flush);
265 if (chain == (ngx_chain_t *) -1)
266 return NGX_ERROR;
267
268 ctx->out = chain;
269
270 ngx_log_debug(r->connection->log, "write filter %x" _ chain);
271
272 return (chain ? NGX_AGAIN : NGX_OK);
273 }
274
275
276 static void *ngx_http_ssi_filter_create_conf(ngx_pool_t *pool)
277 {
278 ngx_http_ssi_filter_conf_t *conf;
279
280 ngx_test_null(conf,
281 ngx_palloc(pool, sizeof(ngx_http_ssi_filter_conf_t)),
282 NULL);
283
284 conf->buffer_output = NGX_CONF_UNSET;
285
286 return conf;
287 }