Mercurial > hg > nginx
comparison src/http/modules/ngx_http_rewrite_handler.c @ 481:fd661d14a7fa release-0.1.15
nginx-0.1.15-RELEASE import
*) Bugfix: the error while the connecting to the FastCGI server caused
segmentation fault.
*) Bugfix: the correct handling of the regular expression, that has
different number of the captures and substitutions.
*) Feature: the location, that is passed to the FastCGI server, can be
regular expression.
*) Bugfix: the FastCGI's parameter REQUEST_URI is now passed with the
arguments and in the original state.
*) Bugfix: the ngx_http_rewrite_module module was required to be built
to use the regular expressions in locations.
*) Bugfix: the directive "proxy_preserve_host on" adds port 80 to the
"Host" headers, if upstream listen on port 80; the bug had appeared
in 0.1.14.
*) Bugfix: the same paths in autoconfiguration parameters
--http-client-body-temp-path=PATH and --http-proxy-temp-path=PATH,
or --http-client-body-temp-path=PATH and
--http-fastcgi-temp-path=PATH caused segmentation fault.
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Wed, 19 Jan 2005 13:10:56 +0000 |
parents | a88a3e4e158f |
children | 621229427cba |
comparison
equal
deleted
inserted
replaced
480:4d5a5478ceda | 481:fd661d14a7fa |
---|---|
21 } ngx_http_rewrite_op_t; | 21 } ngx_http_rewrite_op_t; |
22 | 22 |
23 | 23 |
24 typedef struct { | 24 typedef struct { |
25 ngx_regex_t *regex; | 25 ngx_regex_t *regex; |
26 ngx_uint_t msize; | 26 ngx_uint_t ncaptures; |
27 | 27 |
28 ngx_array_t ops; | 28 ngx_array_t ops; |
29 ngx_uint_t size; | 29 ngx_uint_t size; |
30 | 30 |
31 ngx_str_t re_name; | 31 ngx_str_t re_name; |
111 }; | 111 }; |
112 | 112 |
113 | 113 |
114 static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) | 114 static ngx_int_t ngx_http_rewrite_handler(ngx_http_request_t *r) |
115 { | 115 { |
116 int *matches; | 116 int *captures; |
117 u_char *p; | 117 u_char *p; |
118 size_t len; | 118 size_t len; |
119 uintptr_t data; | 119 uintptr_t data; |
120 ngx_int_t rc; | 120 ngx_int_t rc; |
121 ngx_uint_t i, m, n; | 121 ngx_uint_t i, m, n; |
130 scf = ngx_http_get_module_srv_conf(r, ngx_http_rewrite_module); | 130 scf = ngx_http_get_module_srv_conf(r, ngx_http_rewrite_module); |
131 | 131 |
132 rule = scf->rules.elts; | 132 rule = scf->rules.elts; |
133 for (i = 0; i < scf->rules.nelts; i++) { | 133 for (i = 0; i < scf->rules.nelts; i++) { |
134 | 134 |
135 if (rule[i].msize) { | 135 if (rule[i].ncaptures) { |
136 if (!(matches = ngx_palloc(r->pool, rule[i].msize * sizeof(int)))) { | 136 captures = ngx_palloc(r->pool, rule[i].ncaptures * sizeof(int)); |
137 if (captures == NULL) { | |
137 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 138 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
138 } | 139 } |
139 | 140 |
140 } else { | 141 } else { |
141 matches = NULL; | 142 captures = NULL; |
142 } | 143 } |
143 | 144 |
144 rc = ngx_regex_exec(rule[i].regex, &r->uri, matches, rule[i].msize); | 145 rc = ngx_regex_exec(rule[i].regex, &r->uri, |
145 | 146 captures, rule[i].ncaptures); |
146 if (rc == NGX_DECLINED) { | 147 |
148 if (rc == NGX_REGEX_NO_MATCHED) { | |
147 if (scf->log) { | 149 if (scf->log) { |
148 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 150 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
149 "\"%V\" does not match \"%V\"", | 151 "\"%V\" does not match \"%V\"", |
150 &rule[i].re_name, &r->uri); | 152 &rule[i].re_name, &r->uri); |
151 } | 153 } |
172 } | 174 } |
173 | 175 |
174 uri.len = rule[i].size; | 176 uri.len = rule[i].size; |
175 | 177 |
176 for (n = 1; n < (ngx_uint_t) rc; n++) { | 178 for (n = 1; n < (ngx_uint_t) rc; n++) { |
177 uri.len += matches[2 * n + 1] - matches[2 * n]; | 179 uri.len += captures[2 * n + 1] - captures[2 * n]; |
178 } | 180 } |
179 | 181 |
180 if (!(uri.data = ngx_palloc(r->pool, uri.len))) { | 182 if (!(uri.data = ngx_palloc(r->pool, uri.len))) { |
181 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 183 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
182 } | 184 } |
196 } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) { | 198 } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) { |
197 p = ngx_cpymem(p, (void *) op[n].data, op[n].len); | 199 p = ngx_cpymem(p, (void *) op[n].data, op[n].len); |
198 | 200 |
199 } else { /* NGX_HTTP_REWRITE_COPY_MATCH */ | 201 } else { /* NGX_HTTP_REWRITE_COPY_MATCH */ |
200 m = 2 * op[n].data; | 202 m = 2 * op[n].data; |
201 p = ngx_cpymem(p, &r->uri.data[matches[m]], | 203 p = ngx_cpymem(p, &r->uri.data[captures[m]], |
202 matches[m + 1] - matches[m]); | 204 captures[m + 1] - captures[m]); |
203 } | 205 } |
204 } | 206 } |
207 | |
208 uri.len = p - uri.data; | |
205 | 209 |
206 if (scf->log) { | 210 if (scf->log) { |
207 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 211 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
208 "rewritten uri: \"%V\"", &uri); | 212 "rewritten uri: \"%V\"", &uri); |
209 } | 213 } |
307 ngx_http_rewrite_srv_conf_t *scf = conf; | 311 ngx_http_rewrite_srv_conf_t *scf = conf; |
308 | 312 |
309 u_char *data, *p; | 313 u_char *data, *p; |
310 size_t len; | 314 size_t len; |
311 ngx_str_t *value, err; | 315 ngx_str_t *value, err; |
312 ngx_uint_t i; | 316 ngx_uint_t i, n; |
313 ngx_http_rewrite_op_t *op; | 317 ngx_http_rewrite_op_t *op; |
314 ngx_http_rewrite_rule_t *rule; | 318 ngx_http_rewrite_rule_t *rule; |
315 u_char errstr[NGX_MAX_CONF_ERRSTR]; | 319 u_char errstr[NGX_MAX_CONF_ERRSTR]; |
316 | 320 |
317 if (!(rule = ngx_push_array(&scf->rules))) { | 321 if (!(rule = ngx_push_array(&scf->rules))) { |
319 } | 323 } |
320 | 324 |
321 ngx_init_array(rule->ops, cf->pool, 5, sizeof(ngx_http_rewrite_op_t), | 325 ngx_init_array(rule->ops, cf->pool, 5, sizeof(ngx_http_rewrite_op_t), |
322 NGX_CONF_ERROR); | 326 NGX_CONF_ERROR); |
323 | 327 |
324 rule->msize = 0; | 328 rule->ncaptures = 0; |
325 rule->size = 0; | 329 rule->size = 0; |
326 rule->status = 0; | 330 rule->status = 0; |
327 rule->last = 0; | 331 rule->last = 0; |
328 | 332 |
329 value = cf->args->elts; | 333 value = cf->args->elts; |
369 && value[2].data[i + 1] <= '9') | 373 && value[2].data[i + 1] <= '9') |
370 { | 374 { |
371 op->op = NGX_HTTP_REWRITE_COPY_MATCH; | 375 op->op = NGX_HTTP_REWRITE_COPY_MATCH; |
372 op->data = value[2].data[++i] - '0'; | 376 op->data = value[2].data[++i] - '0'; |
373 | 377 |
374 if (rule->msize < op->data) { | 378 if (rule->ncaptures < op->data) { |
375 rule->msize = op->data; | 379 rule->ncaptures = op->data; |
376 } | 380 } |
377 | 381 |
378 i++; | 382 i++; |
379 | 383 |
380 } else { | 384 } else { |
412 } | 416 } |
413 } | 417 } |
414 } | 418 } |
415 } | 419 } |
416 | 420 |
417 if (rule->msize) { | 421 n = ngx_regex_capture_count(rule->regex); |
418 rule->msize++; | 422 |
419 rule->msize *= 3; | 423 if (rule->ncaptures > n) { |
424 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
425 "pattern \"%V\" has less captures " | |
426 "than referrenced in substitution \"%V\"", | |
427 &value[1], &value[2]); | |
428 return NGX_CONF_ERROR; | |
429 } | |
430 | |
431 if (rule->ncaptures < n) { | |
432 rule->ncaptures = n; | |
433 } | |
434 | |
435 if (rule->ncaptures) { | |
436 rule->ncaptures = (rule->ncaptures + 1) * 3; | |
420 } | 437 } |
421 | 438 |
422 if (cf->args->nelts > 3) { | 439 if (cf->args->nelts > 3) { |
423 if (ngx_strcmp(value[3].data, "last") == 0) { | 440 if (ngx_strcmp(value[3].data, "last") == 0) { |
424 rule->last = 1; | 441 rule->last = 1; |