Mercurial > hg > nginx-vendor-1-0
comparison src/http/ngx_http_upstream.c @ 348:e10168d6e371 NGINX_0_6_18
nginx 0.6.18
*) Change: now the ngx_http_userid_module adds start time microseconds
to the cookie field contains a pid value.
*) Change: now the full request line instead of URI only is written to
error_log.
*) Feature: variables support in the "proxy_pass" directive.
*) Feature: the "resolver" and "resolver_timeout" directives.
*) Feature: now the directive "add_header last-modified ''" deletes a
"Last-Modified" response header line.
*) Bugfix: the "limit_rate" directive did not allow to use full
throughput, even if limit value was very high.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 27 Nov 2007 00:00:00 +0300 |
parents | 05693816539c |
children | 583decdb82a4 |
comparison
equal
deleted
inserted
replaced
347:d53199b68e17 | 348:e10168d6e371 |
---|---|
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 static void ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx); | |
12 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); | 13 static void ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r); |
13 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); | 14 static void ngx_http_upstream_wr_check_broken_connection(ngx_http_request_t *r); |
14 static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, | 15 static void ngx_http_upstream_check_broken_connection(ngx_http_request_t *r, |
15 ngx_event_t *ev); | 16 ngx_event_t *ev); |
16 static void ngx_http_upstream_connect(ngx_http_request_t *r, | 17 static void ngx_http_upstream_connect(ngx_http_request_t *r, |
281 | 282 |
282 | 283 |
283 void | 284 void |
284 ngx_http_upstream_init(ngx_http_request_t *r) | 285 ngx_http_upstream_init(ngx_http_request_t *r) |
285 { | 286 { |
286 ngx_connection_t *c; | 287 ngx_str_t *host; |
287 ngx_http_cleanup_t *cln; | 288 ngx_uint_t i; |
288 ngx_http_upstream_t *u; | 289 ngx_connection_t *c; |
289 ngx_http_core_loc_conf_t *clcf; | 290 ngx_resolver_ctx_t *ctx, temp; |
291 ngx_http_cleanup_t *cln; | |
292 ngx_http_upstream_t *u; | |
293 ngx_http_core_loc_conf_t *clcf; | |
294 ngx_http_upstream_srv_conf_t *uscf, **uscfp; | |
295 ngx_http_upstream_main_conf_t *umcf; | |
290 | 296 |
291 c = r->connection; | 297 c = r->connection; |
292 | 298 |
293 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 299 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
294 "http init upstream, client timer: %d", c->read->timer_set); | 300 "http init upstream, client timer: %d", c->read->timer_set); |
318 | 324 |
319 if (r->request_body) { | 325 if (r->request_body) { |
320 u->request_bufs = r->request_body->bufs; | 326 u->request_bufs = r->request_body->bufs; |
321 } | 327 } |
322 | 328 |
323 if (u->conf->upstream->peer.init(r, u->conf->upstream) != NGX_OK) { | |
324 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
325 return; | |
326 } | |
327 | |
328 if (u->create_request(r) != NGX_OK) { | 329 if (u->create_request(r) != NGX_OK) { |
329 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | 330 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); |
330 return; | 331 return; |
331 } | 332 } |
332 | 333 |
333 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 334 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
334 | 335 |
335 u->output.sendfile = r->connection->sendfile; | 336 u->output.sendfile = c->sendfile; |
336 u->output.pool = r->pool; | 337 u->output.pool = r->pool; |
337 u->output.bufs.num = 1; | 338 u->output.bufs.num = 1; |
338 u->output.bufs.size = clcf->client_body_buffer_size; | 339 u->output.bufs.size = clcf->client_body_buffer_size; |
339 u->output.output_filter = ngx_chain_writer; | 340 u->output.output_filter = ngx_chain_writer; |
340 u->output.filter_ctx = &u->writer; | 341 u->output.filter_ctx = &u->writer; |
372 cln->data = r; | 373 cln->data = r; |
373 u->cleanup = &cln->handler; | 374 u->cleanup = &cln->handler; |
374 | 375 |
375 u->store = (u->conf->store || u->conf->store_lengths); | 376 u->store = (u->conf->store || u->conf->store_lengths); |
376 | 377 |
378 if (u->resolved == NULL) { | |
379 | |
380 uscf = u->conf->upstream; | |
381 | |
382 } else { | |
383 | |
384 host = &r->upstream->resolved->host; | |
385 | |
386 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | |
387 | |
388 uscfp = umcf->upstreams.elts; | |
389 | |
390 for (i = 0; i < umcf->upstreams.nelts; i++) { | |
391 | |
392 uscf = uscfp[i]; | |
393 | |
394 if (uscf->host.len == host->len | |
395 && ngx_memcmp(uscf->host.data, host->data, host->len) == 0) | |
396 { | |
397 goto found; | |
398 } | |
399 } | |
400 | |
401 if (clcf->resolver == NULL) { | |
402 ngx_log_error(NGX_LOG_ERR, c->log, 0, | |
403 "no resolver defined to resolve %V", host); | |
404 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); | |
405 return; | |
406 } | |
407 | |
408 temp.name = *host; | |
409 | |
410 ctx = ngx_resolve_start(clcf->resolver, &temp); | |
411 if (ctx == NULL) { | |
412 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
413 return; | |
414 } | |
415 | |
416 ctx->name = *host; | |
417 ctx->type = NGX_RESOLVE_A; | |
418 ctx->handler = ngx_http_upstream_resolve_handler; | |
419 ctx->data = r; | |
420 ctx->timeout = clcf->resolver_timeout; | |
421 | |
422 u->resolved->ctx = ctx; | |
423 | |
424 if (ngx_resolve_name(ctx) != NGX_OK) { | |
425 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
426 return; | |
427 } | |
428 | |
429 return; | |
430 } | |
431 | |
432 found: | |
433 | |
434 if (uscf->peer.init(r, uscf) != NGX_OK) { | |
435 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
436 return; | |
437 } | |
438 | |
377 ngx_http_upstream_connect(r, u); | 439 ngx_http_upstream_connect(r, u); |
440 } | |
441 | |
442 | |
443 static void | |
444 ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx) | |
445 { | |
446 ngx_http_request_t *r; | |
447 ngx_http_upstream_resolved_t *ur; | |
448 | |
449 r = ctx->data; | |
450 | |
451 r->upstream->resolved->ctx = NULL; | |
452 | |
453 if (ctx->state) { | |
454 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
455 "%V could not be resolved (%i: %s)", | |
456 &ctx->name, ctx->state, | |
457 ngx_resolver_strerror(ctx->state)); | |
458 | |
459 ngx_resolve_name_done(ctx); | |
460 ngx_http_finalize_request(r, NGX_HTTP_BAD_GATEWAY); | |
461 return; | |
462 } | |
463 | |
464 ur = r->upstream->resolved; | |
465 ur->naddrs = ctx->naddrs; | |
466 ur->addrs = ctx->addrs; | |
467 | |
468 #if (NGX_DEBUG) | |
469 { | |
470 in_addr_t addr; | |
471 ngx_uint_t i; | |
472 | |
473 for (i = 0; i < ctx->naddrs; i++) { | |
474 addr = ntohl(ur->addrs[i]); | |
475 | |
476 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
477 "name was resolved to %ud.%ud.%ud.%ud", | |
478 (addr >> 24) & 0xff, (addr >> 16) & 0xff, | |
479 (addr >> 8) & 0xff, addr & 0xff); | |
480 } | |
481 } | |
482 #endif | |
483 | |
484 if (ngx_http_upstream_create_round_robin_peer(r, ur) != NGX_OK) { | |
485 ngx_resolve_name_done(ctx); | |
486 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
487 return; | |
488 } | |
489 | |
490 ngx_resolve_name_done(ctx); | |
491 | |
492 ngx_http_upstream_connect(r, r->upstream); | |
378 } | 493 } |
379 | 494 |
380 | 495 |
381 static void | 496 static void |
382 ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r) | 497 ngx_http_upstream_rd_check_broken_connection(ngx_http_request_t *r) |
547 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); | 662 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t)); |
548 | 663 |
549 tp = ngx_timeofday(); | 664 tp = ngx_timeofday(); |
550 u->state->response_sec = tp->sec; | 665 u->state->response_sec = tp->sec; |
551 u->state->response_msec = tp->msec; | 666 u->state->response_msec = tp->msec; |
667 u->state->peer = u->peer.name; | |
552 | 668 |
553 rc = ngx_event_connect_peer(&u->peer); | 669 rc = ngx_event_connect_peer(&u->peer); |
554 | 670 |
555 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 671 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
556 "http upstream connect: %i", rc); | 672 "http upstream connect: %i", rc); |
558 if (rc == NGX_ERROR) { | 674 if (rc == NGX_ERROR) { |
559 ngx_http_upstream_finalize_request(r, u, | 675 ngx_http_upstream_finalize_request(r, u, |
560 NGX_HTTP_INTERNAL_SERVER_ERROR); | 676 NGX_HTTP_INTERNAL_SERVER_ERROR); |
561 return; | 677 return; |
562 } | 678 } |
563 | |
564 u->state->peer = u->peer.name; | |
565 | 679 |
566 if (rc == NGX_BUSY) { | 680 if (rc == NGX_BUSY) { |
567 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); | 681 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); |
568 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); | 682 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); |
569 return; | 683 return; |
636 return; | 750 return; |
637 } | 751 } |
638 | 752 |
639 #if (NGX_HTTP_SSL) | 753 #if (NGX_HTTP_SSL) |
640 | 754 |
641 if (u->conf->ssl && c->ssl == NULL) { | 755 if (u->ssl && c->ssl == NULL) { |
642 ngx_http_upstream_ssl_init_connection(r, u, c); | 756 ngx_http_upstream_ssl_init_connection(r, u, c); |
643 return; | 757 return; |
644 } | 758 } |
645 | 759 |
646 #endif | 760 #endif |
891 return; | 1005 return; |
892 } | 1006 } |
893 | 1007 |
894 #if (NGX_HTTP_SSL) | 1008 #if (NGX_HTTP_SSL) |
895 | 1009 |
896 if (u->conf->ssl && c->ssl == NULL) { | 1010 if (u->ssl && c->ssl == NULL) { |
897 ngx_http_upstream_ssl_init_connection(r, u, c); | 1011 ngx_http_upstream_ssl_init_connection(r, u, c); |
898 return; | 1012 return; |
899 } | 1013 } |
900 | 1014 |
901 #endif | 1015 #endif |
2258 ngx_http_request_t *r = data; | 2372 ngx_http_request_t *r = data; |
2259 | 2373 |
2260 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2374 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2261 "cleanup http upstream request: \"%V\"", &r->uri); | 2375 "cleanup http upstream request: \"%V\"", &r->uri); |
2262 | 2376 |
2377 if (r->upstream->resolved && r->upstream->resolved->ctx) { | |
2378 ngx_resolve_name_done(r->upstream->resolved->ctx); | |
2379 } | |
2380 | |
2263 ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE); | 2381 ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE); |
2264 } | 2382 } |
2265 | 2383 |
2266 | 2384 |
2267 static void | 2385 static void |
2273 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2391 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2274 "finalize http upstream request: %i", rc); | 2392 "finalize http upstream request: %i", rc); |
2275 | 2393 |
2276 *u->cleanup = NULL; | 2394 *u->cleanup = NULL; |
2277 | 2395 |
2278 if (u->state->response_sec) { | 2396 if (u->state && u->state->response_sec) { |
2279 tp = ngx_timeofday(); | 2397 tp = ngx_timeofday(); |
2280 u->state->response_sec = tp->sec - u->state->response_sec; | 2398 u->state->response_sec = tp->sec - u->state->response_sec; |
2281 u->state->response_msec = tp->msec - u->state->response_msec; | 2399 u->state->response_msec = tp->msec - u->state->response_msec; |
2282 } | 2400 } |
2283 | 2401 |
2284 u->finalize_request(r, rc); | 2402 u->finalize_request(r, rc); |
2285 | 2403 |
2286 u->peer.free(&u->peer, u->peer.data, 0); | 2404 if (u->peer.free) { |
2405 u->peer.free(&u->peer, u->peer.data, 0); | |
2406 } | |
2287 | 2407 |
2288 if (u->peer.connection) { | 2408 if (u->peer.connection) { |
2289 | 2409 |
2290 #if (NGX_HTTP_SSL) | 2410 #if (NGX_HTTP_SSL) |
2291 | 2411 |
2607 } | 2727 } |
2608 | 2728 |
2609 return rc; | 2729 return rc; |
2610 } | 2730 } |
2611 | 2731 |
2732 if (ho->value.data[0] != '/') { | |
2733 r->headers_out.location = ho; | |
2734 } | |
2735 | |
2612 /* | 2736 /* |
2613 * we do not set r->headers_out.location here to avoid the handling | 2737 * we do not set r->headers_out.location here to avoid the handling |
2614 * the local redirects without a host name by ngx_http_header_filter() | 2738 * the local redirects without a host name by ngx_http_header_filter() |
2615 */ | 2739 */ |
2616 | 2740 |
2646 | 2770 |
2647 if (rc == NGX_DECLINED) { | 2771 if (rc == NGX_DECLINED) { |
2648 return NGX_OK; | 2772 return NGX_OK; |
2649 } | 2773 } |
2650 | 2774 |
2651 #if (NGX_DEBUG) | |
2652 if (rc == NGX_OK) { | 2775 if (rc == NGX_OK) { |
2776 r->headers_out.refresh = ho; | |
2777 | |
2653 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 2778 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2654 "rewritten refresh: \"%V\"", &ho->value); | 2779 "rewritten refresh: \"%V\"", &ho->value); |
2655 } | 2780 } |
2656 #endif | |
2657 | 2781 |
2658 return rc; | 2782 return rc; |
2659 } | 2783 } |
2784 | |
2785 r->headers_out.refresh = ho; | |
2660 | 2786 |
2661 return NGX_OK; | 2787 return NGX_OK; |
2662 } | 2788 } |
2663 | 2789 |
2664 | 2790 |