Mercurial > hg > nginx-vendor-current
comparison src/http/ngx_http_upstream.c @ 356:b743d290eb3b NGINX_0_6_22
nginx 0.6.22
*) Change: now all ngx_http_perl_module methods return values copied to
perl's allocated memory.
*) Bugfix: if nginx was built with ngx_http_perl_module, the perl
before 5.8.6 was used, and perl supported threads, then during
reconfiguration the master process aborted; bug appeared in
0.5.9.
Thanks to Boris Zhmurov.
*) Bugfix: the ngx_http_perl_module methods may get invalid values of
the regex captures.
*) Bugfix: a segmentation fault occurred in worker process, if the
$r->has_request_body() method was called for a request whose small
request body was already received.
*) Bugfix: large_client_header_buffers did not freed before going to
keep-alive state.
Thanks to Olexander Shtepa.
*) Bugfix: the last address was missed in the $upstream_addr variable;
bug appeared in 0.6.18.
*) Bugfix: the "fastcgi_catch_stderr" directive did return error code;
now it returns 502 code, that can be rerouted to a next server using
the "fastcgi_next_upstream invalid_header" directive.
*) Bugfix: a segmentation fault occurred in master process if the
"fastcgi_catch_stderr" directive was used; bug appeared in
0.6.10.
Thanks to Manlio Perillo.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 19 Dec 2007 00:00:00 +0300 |
parents | 583decdb82a4 |
children | 9121a0a91f47 |
comparison
equal
deleted
inserted
replaced
355:3ac45897a61c | 356:b743d290eb3b |
---|---|
379 | 379 |
380 uscf = u->conf->upstream; | 380 uscf = u->conf->upstream; |
381 | 381 |
382 } else { | 382 } else { |
383 | 383 |
384 host = &r->upstream->resolved->host; | 384 host = &u->resolved->host; |
385 | 385 |
386 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | 386 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
387 | 387 |
388 uscfp = umcf->upstreams.elts; | 388 uscfp = umcf->upstreams.elts; |
389 | 389 |
663 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); | 663 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); |
664 | 664 |
665 tp = ngx_timeofday(); | 665 tp = ngx_timeofday(); |
666 u->state->response_sec = tp->sec; | 666 u->state->response_sec = tp->sec; |
667 u->state->response_msec = tp->msec; | 667 u->state->response_msec = tp->msec; |
668 u->state->peer = u->peer.name; | |
669 | 668 |
670 rc = ngx_event_connect_peer(&u->peer); | 669 rc = ngx_event_connect_peer(&u->peer); |
671 | 670 |
672 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 671 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
673 "http upstream connect: %i", rc); | 672 "http upstream connect: %i", rc); |
675 if (rc == NGX_ERROR) { | 674 if (rc == NGX_ERROR) { |
676 ngx_http_upstream_finalize_request(r, u, | 675 ngx_http_upstream_finalize_request(r, u, |
677 NGX_HTTP_INTERNAL_SERVER_ERROR); | 676 NGX_HTTP_INTERNAL_SERVER_ERROR); |
678 return; | 677 return; |
679 } | 678 } |
679 | |
680 u->state->peer = u->peer.name; | |
680 | 681 |
681 if (rc == NGX_BUSY) { | 682 if (rc == NGX_BUSY) { |
682 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); | 683 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); |
683 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); | 684 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); |
684 return; | 685 return; |
838 | 839 |
839 if (u->reinit_request(r) != NGX_OK) { | 840 if (u->reinit_request(r) != NGX_OK) { |
840 return NGX_ERROR; | 841 return NGX_ERROR; |
841 } | 842 } |
842 | 843 |
843 ngx_memzero(&r->upstream->headers_in, | 844 ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); |
844 sizeof(ngx_http_upstream_headers_in_t)); | 845 |
845 | 846 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, |
846 if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, | |
847 sizeof(ngx_table_elt_t)) | 847 sizeof(ngx_table_elt_t)) |
848 != NGX_OK) | 848 != NGX_OK) |
849 { | 849 { |
850 return NGX_ERROR; | 850 return NGX_ERROR; |
851 } | 851 } |
1076 u->buffer.end = u->buffer.start + u->conf->buffer_size; | 1076 u->buffer.end = u->buffer.start + u->conf->buffer_size; |
1077 u->buffer.temporary = 1; | 1077 u->buffer.temporary = 1; |
1078 | 1078 |
1079 u->buffer.tag = u->output.tag; | 1079 u->buffer.tag = u->output.tag; |
1080 | 1080 |
1081 if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, | 1081 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, |
1082 sizeof(ngx_table_elt_t)) | 1082 sizeof(ngx_table_elt_t)) |
1083 != NGX_OK) | 1083 != NGX_OK) |
1084 { | 1084 { |
1085 ngx_http_upstream_finalize_request(r, u, | 1085 ngx_http_upstream_finalize_request(r, u, |
1086 NGX_HTTP_INTERNAL_SERVER_ERROR); | 1086 NGX_HTTP_INTERNAL_SERVER_ERROR); |
1156 if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) { | 1156 if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) { |
1157 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); | 1157 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER); |
1158 return; | 1158 return; |
1159 } | 1159 } |
1160 | 1160 |
1161 if (rc == NGX_ERROR || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { | 1161 if (rc == NGX_ERROR) { |
1162 ngx_http_upstream_finalize_request(r, u, | 1162 ngx_http_upstream_finalize_request(r, u, |
1163 NGX_HTTP_INTERNAL_SERVER_ERROR); | 1163 NGX_HTTP_INTERNAL_SERVER_ERROR); |
1164 return; | 1164 return; |
1165 } | 1165 } |
1166 | 1166 |
1245 } | 1245 } |
1246 } | 1246 } |
1247 | 1247 |
1248 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | 1248 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
1249 | 1249 |
1250 if (r->upstream->headers_in.x_accel_redirect) { | 1250 if (u->headers_in.x_accel_redirect) { |
1251 | 1251 |
1252 ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); | 1252 ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); |
1253 | 1253 |
1254 part = &r->upstream->headers_in.headers.part; | 1254 part = &u->headers_in.headers.part; |
1255 h = part->elts; | 1255 h = part->elts; |
1256 | 1256 |
1257 for (i = 0; /* void */; i++) { | 1257 for (i = 0; /* void */; i++) { |
1258 | 1258 |
1259 if (i >= part->nelts) { | 1259 if (i >= part->nelts) { |
1276 return; | 1276 return; |
1277 } | 1277 } |
1278 } | 1278 } |
1279 } | 1279 } |
1280 | 1280 |
1281 uri = &r->upstream->headers_in.x_accel_redirect->value; | 1281 uri = &u->headers_in.x_accel_redirect->value; |
1282 args.len = 0; | 1282 args.len = 0; |
1283 args.data = NULL; | 1283 args.data = NULL; |
1284 flags = 0; | 1284 flags = 0; |
1285 | 1285 |
1286 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { | 1286 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { |
1298 | 1298 |
1299 ngx_http_internal_redirect(r, uri, &args); | 1299 ngx_http_internal_redirect(r, uri, &args); |
1300 return; | 1300 return; |
1301 } | 1301 } |
1302 | 1302 |
1303 part = &r->upstream->headers_in.headers.part; | 1303 part = &u->headers_in.headers.part; |
1304 h = part->elts; | 1304 h = part->elts; |
1305 | 1305 |
1306 for (i = 0; /* void */; i++) { | 1306 for (i = 0; /* void */; i++) { |
1307 | 1307 |
1308 if (i >= part->nelts) { | 1308 if (i >= part->nelts) { |
2162 goto failed; | 2162 goto failed; |
2163 } | 2163 } |
2164 | 2164 |
2165 #endif | 2165 #endif |
2166 | 2166 |
2167 if (r->upstream->headers_in.last_modified) { | 2167 if (u->headers_in.last_modified) { |
2168 | 2168 |
2169 last_modified = &r->upstream->headers_in.last_modified->value; | 2169 last_modified = &u->headers_in.last_modified->value; |
2170 | 2170 |
2171 lm = ngx_http_parse_time(last_modified->data, last_modified->len); | 2171 lm = ngx_http_parse_time(last_modified->data, last_modified->len); |
2172 | 2172 |
2173 if (lm != NGX_ERROR) { | 2173 if (lm != NGX_ERROR) { |
2174 if (ngx_set_file_time(temp->data, u->pipe->temp_file->file.fd, lm) | 2174 if (ngx_set_file_time(temp->data, u->pipe->temp_file->file.fd, lm) |
2222 } | 2222 } |
2223 | 2223 |
2224 #if (NGX_WIN32) | 2224 #if (NGX_WIN32) |
2225 | 2225 |
2226 if (err == NGX_EEXIST) { | 2226 if (err == NGX_EEXIST) { |
2227 if (ngx_win32_rename_file(temp, &path, r->pool) != NGX_ERROR) { | 2227 if (ngx_win32_rename_file(temp, &path, r->connection->log) == NGX_OK) { |
2228 | 2228 |
2229 if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { | 2229 if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { |
2230 return; | 2230 return; |
2231 } | 2231 } |
2232 } | 2232 } |
2370 static void | 2370 static void |
2371 ngx_http_upstream_cleanup(void *data) | 2371 ngx_http_upstream_cleanup(void *data) |
2372 { | 2372 { |
2373 ngx_http_request_t *r = data; | 2373 ngx_http_request_t *r = data; |
2374 | 2374 |
2375 ngx_http_upstream_t *u; | |
2376 | |
2375 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2377 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2376 "cleanup http upstream request: \"%V\"", &r->uri); | 2378 "cleanup http upstream request: \"%V\"", &r->uri); |
2377 | 2379 |
2378 if (r->upstream->resolved && r->upstream->resolved->ctx) { | 2380 u = r->upstream; |
2379 ngx_resolve_name_done(r->upstream->resolved->ctx); | 2381 |
2380 } | 2382 if (u->resolved && u->resolved->ctx) { |
2381 | 2383 ngx_resolve_name_done(u->resolved->ctx); |
2382 ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE); | 2384 } |
2385 | |
2386 ngx_http_upstream_finalize_request(r, u, NGX_DONE); | |
2383 } | 2387 } |
2384 | 2388 |
2385 | 2389 |
2386 static void | 2390 static void |
2387 ngx_http_upstream_finalize_request(ngx_http_request_t *r, | 2391 ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
3406 | 3410 |
3407 return uscf; | 3411 return uscf; |
3408 } | 3412 } |
3409 | 3413 |
3410 | 3414 |
3415 ngx_int_t | |
3416 ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf, | |
3417 ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, | |
3418 ngx_str_t *default_hide_headers, ngx_hash_init_t *hash) | |
3419 { | |
3420 ngx_str_t *h; | |
3421 ngx_uint_t i, j; | |
3422 ngx_array_t hide_headers; | |
3423 ngx_hash_key_t *hk; | |
3424 | |
3425 if (conf->hide_headers == NGX_CONF_UNSET_PTR | |
3426 && conf->pass_headers == NGX_CONF_UNSET_PTR) | |
3427 { | |
3428 conf->hide_headers_hash = prev->hide_headers_hash; | |
3429 | |
3430 if (conf->hide_headers_hash.buckets) { | |
3431 return NGX_OK; | |
3432 } | |
3433 | |
3434 conf->hide_headers = prev->hide_headers; | |
3435 conf->pass_headers = prev->pass_headers; | |
3436 | |
3437 } else { | |
3438 if (conf->hide_headers == NGX_CONF_UNSET_PTR) { | |
3439 conf->hide_headers = prev->hide_headers; | |
3440 } | |
3441 | |
3442 if (conf->pass_headers == NGX_CONF_UNSET_PTR) { | |
3443 conf->pass_headers = prev->pass_headers; | |
3444 } | |
3445 } | |
3446 | |
3447 if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | |
3448 != NGX_OK) | |
3449 { | |
3450 return NGX_ERROR; | |
3451 } | |
3452 | |
3453 for (h = default_hide_headers; h->len; h++) { | |
3454 hk = ngx_array_push(&hide_headers); | |
3455 if (hk == NULL) { | |
3456 return NGX_ERROR; | |
3457 } | |
3458 | |
3459 hk->key = *h; | |
3460 hk->key_hash = ngx_hash_key_lc(h->data, h->len); | |
3461 hk->value = (void *) 1; | |
3462 } | |
3463 | |
3464 if (conf->hide_headers != NGX_CONF_UNSET_PTR) { | |
3465 | |
3466 h = conf->hide_headers->elts; | |
3467 | |
3468 for (i = 0; i < conf->hide_headers->nelts; i++) { | |
3469 | |
3470 hk = hide_headers.elts; | |
3471 | |
3472 for (j = 0; j < hide_headers.nelts; j++) { | |
3473 if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) { | |
3474 goto exist; | |
3475 } | |
3476 } | |
3477 | |
3478 hk = ngx_array_push(&hide_headers); | |
3479 if (hk == NULL) { | |
3480 return NGX_ERROR; | |
3481 } | |
3482 | |
3483 hk->key = h[i]; | |
3484 hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len); | |
3485 hk->value = (void *) 1; | |
3486 | |
3487 exist: | |
3488 | |
3489 continue; | |
3490 } | |
3491 } | |
3492 | |
3493 if (conf->pass_headers != NGX_CONF_UNSET_PTR) { | |
3494 | |
3495 h = conf->pass_headers->elts; | |
3496 hk = hide_headers.elts; | |
3497 | |
3498 for (i = 0; i < conf->pass_headers->nelts; i++) { | |
3499 for (j = 0; j < hide_headers.nelts; j++) { | |
3500 | |
3501 if (hk[j].key.data == NULL) { | |
3502 continue; | |
3503 } | |
3504 | |
3505 if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) { | |
3506 hk[j].key.data = NULL; | |
3507 break; | |
3508 } | |
3509 } | |
3510 } | |
3511 } | |
3512 | |
3513 hash->hash = &conf->hide_headers_hash; | |
3514 hash->key = ngx_hash_key_lc; | |
3515 hash->pool = cf->pool; | |
3516 hash->temp_pool = NULL; | |
3517 | |
3518 return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts); | |
3519 } | |
3520 | |
3521 | |
3411 static void * | 3522 static void * |
3412 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) | 3523 ngx_http_upstream_create_main_conf(ngx_conf_t *cf) |
3413 { | 3524 { |
3414 ngx_http_upstream_main_conf_t *umcf; | 3525 ngx_http_upstream_main_conf_t *umcf; |
3415 | 3526 |