Mercurial > hg > nginx-vendor-current
comparison src/http/modules/ngx_http_rewrite_handler.c @ 32:da8c190bdaba NGINX_0_1_16
nginx 0.1.16
*) Bugfix: if the response were transferred by chunks, then on the HEAD
request the final chunk was issued.
*) Bugfix: the "Connection: keep-alive" header were issued, even if the
keepalive_timeout directive forbade the keep-alive use.
*) Bugfix: the errors in the ngx_http_fastcgi_module caused the
segmentation faults.
*) Bugfix: the compressed response encrypted by SSL may not transferred
complete.
*) Bugfix: the TCP-specific TCP_NODELAY, TCP_NOPSUH, and TCP_CORK
options, are not used for the unix domain sockets.
*) Feature: the rewrite directive supports the arguments rewriting.
*) Bugfix: the response code 400 was returned for the POST request with
the "Content-Length: 0" header; bug appeared in 0.1.14.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 25 Jan 2005 00:00:00 +0300 |
parents | e1ada20fc595 |
children | aab2ea7c0458 |
comparison
equal
deleted
inserted
replaced
31:1b17dd824438 | 32:da8c190bdaba |
---|---|
7 #include <ngx_config.h> | 7 #include <ngx_config.h> |
8 #include <ngx_core.h> | 8 #include <ngx_core.h> |
9 #include <ngx_http.h> | 9 #include <ngx_http.h> |
10 | 10 |
11 | 11 |
12 #define NGX_HTTP_REWRITE_COPY_MATCH 0 | 12 #define NGX_HTTP_REWRITE_COPY_CAPTURE 0 |
13 #define NGX_HTTP_REWRITE_COPY_SHORT 1 | 13 #define NGX_HTTP_REWRITE_COPY_SHORT 1 |
14 #define NGX_HTTP_REWRITE_COPY_LONG 2 | 14 #define NGX_HTTP_REWRITE_COPY_LONG 2 |
15 #define NGX_HTTP_REWRITE_START_ARGS 3 | |
15 | 16 |
16 | 17 |
17 typedef struct { | 18 typedef struct { |
18 ngx_int_t op; | 19 ngx_int_t op; |
19 size_t len; | 20 size_t len; |
117 u_char *p; | 118 u_char *p; |
118 size_t len; | 119 size_t len; |
119 uintptr_t data; | 120 uintptr_t data; |
120 ngx_int_t rc; | 121 ngx_int_t rc; |
121 ngx_uint_t i, m, n; | 122 ngx_uint_t i, m, n; |
122 ngx_str_t uri; | 123 ngx_str_t uri, args; |
123 ngx_http_rewrite_op_t *op; | 124 ngx_http_rewrite_op_t *op; |
124 ngx_http_rewrite_rule_t *rule; | 125 ngx_http_rewrite_rule_t *rule; |
125 ngx_http_rewrite_srv_conf_t *scf; | 126 ngx_http_rewrite_srv_conf_t *scf; |
126 | 127 |
127 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 128 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
174 } | 175 } |
175 | 176 |
176 uri.len = rule[i].size; | 177 uri.len = rule[i].size; |
177 | 178 |
178 for (n = 1; n < (ngx_uint_t) rc; n++) { | 179 for (n = 1; n < (ngx_uint_t) rc; n++) { |
179 uri.len += captures[2 * n + 1] - captures[2 * n]; | 180 uri.len += captures[2 * n + 1] - captures[2 * n]; |
180 } | 181 } |
181 | 182 |
182 if (!(uri.data = ngx_palloc(r->pool, uri.len))) { | 183 if (!(uri.data = ngx_palloc(r->pool, uri.len))) { |
183 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 184 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
184 } | 185 } |
185 | 186 |
187 args.data = NULL; | |
186 p = uri.data; | 188 p = uri.data; |
187 | 189 |
188 op = rule[i].ops.elts; | 190 op = rule[i].ops.elts; |
189 for (n = 0; n < rule[i].ops.nelts; n++) { | 191 for (n = 0; n < rule[i].ops.nelts; n++) { |
190 if (op[n].op == NGX_HTTP_REWRITE_COPY_SHORT) { | 192 if (op[n].op == NGX_HTTP_REWRITE_COPY_SHORT) { |
196 } | 198 } |
197 | 199 |
198 } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) { | 200 } else if (op[n].op == NGX_HTTP_REWRITE_COPY_LONG) { |
199 p = ngx_cpymem(p, (void *) op[n].data, op[n].len); | 201 p = ngx_cpymem(p, (void *) op[n].data, op[n].len); |
200 | 202 |
201 } else { /* NGX_HTTP_REWRITE_COPY_MATCH */ | 203 } else if (op[n].op == NGX_HTTP_REWRITE_START_ARGS) { |
204 args.data = p; | |
205 | |
206 } else { /* NGX_HTTP_REWRITE_COPY_CAPTURE */ | |
202 m = 2 * op[n].data; | 207 m = 2 * op[n].data; |
203 p = ngx_cpymem(p, &r->uri.data[captures[m]], | 208 p = ngx_cpymem(p, &r->uri.data[captures[m]], |
204 captures[m + 1] - captures[m]); | 209 captures[m + 1] - captures[m]); |
205 } | 210 } |
206 } | 211 } |
207 | 212 |
208 uri.len = p - uri.data; | 213 if (args.data) { |
214 uri.len = args.data - uri.data; | |
215 args.len = p - args.data; | |
216 | |
217 r->args = args; | |
218 | |
219 } else { | |
220 uri.len = p - uri.data; | |
221 args.len = 0; | |
222 } | |
223 | |
224 r->uri = uri; | |
209 | 225 |
210 if (scf->log) { | 226 if (scf->log) { |
211 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, | 227 ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, |
212 "rewritten uri: \"%V\"", &uri); | 228 "rewritten uri: \"%V\", args: \"%V\"", &uri, &args); |
213 } | 229 } |
214 | |
215 r->uri = uri; | |
216 | 230 |
217 if (ngx_http_set_exten(r) != NGX_OK) { | 231 if (ngx_http_set_exten(r) != NGX_OK) { |
218 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 232 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
219 } | 233 } |
220 | 234 |
357 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | 371 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
358 "invalid parameter \"%V\"", &value[3]); | 372 "invalid parameter \"%V\"", &value[3]); |
359 return NGX_CONF_ERROR; | 373 return NGX_CONF_ERROR; |
360 } | 374 } |
361 | 375 |
362 for (i = 0; i < value[2].len; /* void */) { | 376 i = 0; |
377 | |
378 while (i < value[2].len) { | |
363 | 379 |
364 if (!(op = ngx_push_array(&rule->ops))) { | 380 if (!(op = ngx_push_array(&rule->ops))) { |
365 return NGX_CONF_ERROR; | 381 return NGX_CONF_ERROR; |
366 } | 382 } |
367 | 383 |
370 if (value[2].data[i] == '$' | 386 if (value[2].data[i] == '$' |
371 && i < value[2].len | 387 && i < value[2].len |
372 && value[2].data[i + 1] >= '1' | 388 && value[2].data[i + 1] >= '1' |
373 && value[2].data[i + 1] <= '9') | 389 && value[2].data[i + 1] <= '9') |
374 { | 390 { |
375 op->op = NGX_HTTP_REWRITE_COPY_MATCH; | 391 op->op = NGX_HTTP_REWRITE_COPY_CAPTURE; |
392 op->len = 0; | |
376 op->data = value[2].data[++i] - '0'; | 393 op->data = value[2].data[++i] - '0'; |
377 | 394 |
378 if (rule->ncaptures < op->data) { | 395 if (rule->ncaptures < op->data) { |
379 rule->ncaptures = op->data; | 396 rule->ncaptures = op->data; |
380 } | 397 } |
381 | 398 |
382 i++; | 399 i++; |
383 | 400 |
384 } else { | 401 continue; |
402 } | |
403 | |
404 if (value[2].data[i] == '?') { | |
405 op->op = NGX_HTTP_REWRITE_START_ARGS; | |
406 op->len = 0; | |
407 op->data = 0; | |
408 | |
385 i++; | 409 i++; |
386 | 410 |
387 while (i < value[2].len && value[2].data[i] != '$') { | 411 continue; |
388 i++; | 412 } |
389 } | 413 |
390 | 414 i++; |
391 len = &value[2].data[i] - data; | 415 |
392 rule->size += len; | 416 while (i < value[2].len |
393 | 417 && value[2].data[i] != '$' |
394 if (len) { | 418 && value[2].data[i] != '?') |
395 | 419 { |
396 op->len = len; | 420 i++; |
397 | 421 } |
398 if (len <= sizeof(uintptr_t)) { | 422 |
399 op->op = NGX_HTTP_REWRITE_COPY_SHORT; | 423 len = &value[2].data[i] - data; |
400 op->data = 0; | 424 rule->size += len; |
401 | 425 |
402 while (len--) { | 426 if (len) { |
403 op->data <<= 8; | 427 |
404 op->data |= data[len]; | 428 op->len = len; |
405 } | 429 |
406 | 430 if (len <= sizeof(uintptr_t)) { |
407 } else { | 431 op->op = NGX_HTTP_REWRITE_COPY_SHORT; |
408 op->op = NGX_HTTP_REWRITE_COPY_LONG; | 432 op->data = 0; |
409 | 433 |
410 if (!(p = ngx_palloc(cf->pool, len))) { | 434 while (len--) { |
411 return NGX_CONF_ERROR; | 435 op->data <<= 8; |
412 } | 436 op->data |= data[len]; |
413 | |
414 ngx_memcpy(p, data, len); | |
415 op->data = (uintptr_t) p; | |
416 } | 437 } |
438 | |
439 } else { | |
440 op->op = NGX_HTTP_REWRITE_COPY_LONG; | |
441 | |
442 if (!(p = ngx_palloc(cf->pool, len))) { | |
443 return NGX_CONF_ERROR; | |
444 } | |
445 | |
446 ngx_memcpy(p, data, len); | |
447 op->data = (uintptr_t) p; | |
417 } | 448 } |
418 } | 449 } |
419 } | 450 } |
420 | 451 |
421 n = ngx_regex_capture_count(rule->regex); | 452 n = ngx_regex_capture_count(rule->regex); |