Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_ssi_filter.c @ 16:6ce4755737b4
nginx-0.0.1-2002-09-26-20:50:29 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 26 Sep 2002 16:50:29 +0000 |
parents | cbb38b60495c |
children | 885ffb8cc32a |
comparison
equal
deleted
inserted
replaced
15:cbb38b60495c | 16:6ce4755737b4 |
---|---|
37 { | 37 { |
38 ngx_chain_t *ch, **prev, *chain; | 38 ngx_chain_t *ch, **prev, *chain; |
39 ngx_http_ssi_filter_ctx_t *ctx; | 39 ngx_http_ssi_filter_ctx_t *ctx; |
40 ngx_http_ssi_filter_conf_t *conf; | 40 ngx_http_ssi_filter_conf_t *conf; |
41 | 41 |
42 if (in == NULL) | |
43 return next_filter; | |
44 | |
42 ctx = (ngx_http_ssi_filter_ctx_t *) | 45 ctx = (ngx_http_ssi_filter_ctx_t *) |
43 ngx_get_module_ctx(r->main ? r->main : r, | 46 ngx_get_module_ctx(r, ngx_http_ssi_filter_module); |
44 ngx_http_ssi_filter_module); | |
45 if (ctx == NULL) { | 47 if (ctx == NULL) { |
46 ngx_http_create_ctx(r, ctx, | 48 ngx_http_create_ctx(r, ctx, |
47 ngx_http_ssi_filter_module, | 49 ngx_http_ssi_filter_module, |
48 sizeof(ngx_http_ssi_filter_ctx_t)); | 50 sizeof(ngx_http_ssi_filter_ctx_t)); |
49 | 51 |
50 ctx->state = &ssi_start; | 52 ctx->state = &ssi_start; |
51 } | 53 ctx->handler = ngx_http_ssi_find_start; |
52 | 54 } |
53 state = ctx->state; | |
54 length = ctx->length; | |
55 | 55 |
56 ch = in; | 56 ch = in; |
57 p = ch->hunk->pos.mem; | 57 ctx->start = ctx->pos = ch->hunk->pos.mem; |
58 | 58 |
59 rc = ngx_http_ssi_parse(r, ctx, in); | 59 for ( ;; ) { |
60 if (rc == NGX_SSI_FOUND) { | 60 if (ctx->handler(r, ctx, ch) == NGX_ERROR) |
61 } | 61 return NGX_ERROR; |
62 | 62 |
63 } | 63 if (ctx->pos + ctx->length == ch->hunk->last.mem) { |
64 | 64 ch = ch->next; |
65 | 65 if (ch == NULL) |
66 static int ngx_http_ssi_parse(ngx_http_request_t *r, | 66 break; |
67 ngx_http_ssi_filter_ctx_t *ctx, ngx_chain_t *in) | 67 |
68 ctx->start = ctx->pos = ch->hunk->pos.mem; | |
69 } | |
70 } | |
71 } | |
72 | |
73 | |
74 | |
75 static int ngx_http_ssi_find_start(ngx_http_request_t *r, | |
76 ngx_http_ssi_filter_ctx_t *ctx, | |
77 ngx_chain_t *ch) | |
68 { | 78 { |
69 state = ctx->state; | 79 ngx_http_ssi_parse(r, ctx, ch->hunk); |
70 length = ctx->length; | 80 |
81 if (ctx->state == ssi_command_state | |
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 | |
95 ngx_add_hunk_to_chain(ctx->last, h, r->pool, NGX_ERROR); | |
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 | |
71 | 149 |
72 for ( ;; ) { | 150 for ( ;; ) { |
73 | 151 |
74 if (state == ssi_start_state) { | 152 for (/* void */ ; p < ch->hunk->last.mem; p++) { |
75 for (/* void */ ; p < ch->hunk->last.mem; p++) { | 153 |
76 if (*p == '<') { | 154 switch (state) { |
77 state = ssi_exclam_state; | 155 |
78 length = 1; | 156 case ssi_start_state: |
79 break; | 157 |
80 } | 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 | |
81 } | 210 } |
82 } | 211 } |
83 | 212 |
84 for (/* void */ ; | 213 if (length == 6 |
85 p < ch->hunk->last.mem | 214 || (length > 0 && ch->next == NULL) |
86 && (state > ssi_start_state && state < ssi_command_state) | 215 || hunk_with_ssi) { |
87 p++) | 216 |
88 { | 217 if (ctx->saved > 0 && flush) { |
89 switch (state) { | 218 add saved |
90 | 219 ctx->saved = 0; |
91 case ssi_exclam_state: | 220 } |
92 switch (*p) { | 221 |
93 | 222 for (c = ctx->in; c != hunk; c = c->next) { |
94 case '!': | 223 ngx_add_hunk_to_chain(ctx->last, c->hunk, |
95 state = ssi_dash1_state; | 224 r->pool, NGX_ERROR); |
96 length = 2; | 225 } |
97 break; | 226 |
98 | 227 add duped; |
99 case '<': | 228 push duped_hunk, hunk, NULL; |
100 state = ssi_exclam_state; | 229 |
101 length = 1; | 230 n = length - (hunk->last.mem - pos); |
102 break; | 231 for (c = hunk; c; c->next) { |
103 | 232 if (n > c->hunk->last.mem - c->hunk->pos.mem) { |
104 default: | 233 n -= c->hunk->last.mem - c->hunk->pos.mem; |
105 state = ssi_start_state; | 234 push NULL, c->hunk, NULL; |
106 length = 0; | 235 } |
107 break; | 236 } |
108 } | 237 |
109 | 238 ctx->in = c; |
110 break; | |
111 | |
112 case ssi_dash1_state: | |
113 switch (*p) { | |
114 | |
115 case '-': | |
116 state = ssi_dash2_state; | |
117 length = 3; | |
118 break; | |
119 | |
120 case '<': | |
121 state = ssi_exclam_state; | |
122 length = 1; | |
123 break; | |
124 | |
125 default: | |
126 state = ssi_start_state; | |
127 length = 0; | |
128 break; | |
129 } | |
130 | |
131 break; | |
132 | |
133 case ssi_dash2_state: | |
134 switch (*p) { | |
135 | |
136 case '-': | |
137 state = ssi_sharp_state; | |
138 length = 4; | |
139 break; | |
140 | |
141 case '<': | |
142 state = ssi_exclam_state; | |
143 length = 1; | |
144 break; | |
145 | |
146 default: | |
147 state = ssi_start_state; | |
148 length = 0; | |
149 break; | |
150 } | |
151 | |
152 break; | |
153 | |
154 case ssi_sharp_state: | |
155 switch (*p) { | |
156 | |
157 case '#': | |
158 ctx->state = ssi_command_state; | |
159 ctx->length = 5; | |
160 return NGX_SSI_FOUND; | |
161 | |
162 case '<': | |
163 state = ssi_exclam_state; | |
164 length = 1; | |
165 break; | |
166 | |
167 default: | |
168 state = ssi_start_state; | |
169 length = 0; | |
170 break; | |
171 } | |
172 | |
173 break; | |
174 } | 239 } |
175 } | 240 } |
176 | 241 |
177 if (state > ssi_start_state) { | 242 } else { |
178 ngx_add_hunk_to_chain(ch->hunk); | 243 |
179 } | 244 for (/* void */ ; p < ch->hunk->last.mem; p++) { |
180 | 245 if (*p == ' ' || *p == '\t' || *p == CR || *P == LF) |
181 ch = ch->next; | 246 continue; |
182 if (ch == NULL) { | 247 |
183 ctx->state = state; | 248 ctx->state = ssi_command_state; |
184 break; | 249 break; |
185 } | 250 } |
186 | 251 |
187 p = ch->hunk->pos.mem; | 252 if ( |
188 } | 253 |
189 | 254 } |
190 if (state > ssi_start_state) | 255 } |
191 if (ngx_http_ssi_dup_hunk(r, ch->hunk) == NGX_ERROR) | 256 |
192 return NGX_ERROR; | 257 |
193 | 258 |
194 } | 259 |
195 | 260 |
196 | 261 |
197 static ngx_http_ssi_dup_hunk(ngx_http_request_t *r, ngx_hunk_t *hunk); | 262 |
198 { | 263 |
199 new dup_hunk | 264 |
200 set dup_hunk | 265 |
201 ngx_add_hunk_to_chain dup_hunk | |
202 | |
203 ngx_test_null(ssi_hunk, ngx_push_array); | |
204 ssi_hunk->ssi_hunk = dup_hunk; | |
205 ssi_hunk->hunk = hunk; | |
206 ssi_hunk->pos = NULL; | |
207 } | |
208 | 266 |
209 | 267 |
210 | 268 |
211 | 269 |
212 | 270 |