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