comparison src/http/ngx_http_upstream.c @ 296:2ceaee987f37 NGINX_0_5_18

nginx 0.5.18 *) Feature: the ngx_http_sub_filter_module. *) Feature: the "$upstream_http_..." variables. *) Feature: now the $upstream_status and $upstream_response_time variables keep data about all upstreams before X-Accel-Redirect. *) Bugfix: a segmentation fault occurred in master process after first reconfiguration and receiving any signal if nginx was built with ngx_http_perl_module and perl did not support multiplicity; bug appeared in 0.5.9. *) Bugfix: if perl did not support multiplicity, then after reconfiguration perl code did not work; bug appeared in 0.3.38.
author Igor Sysoev <http://sysoev.ru>
date Thu, 19 Apr 2007 00:00:00 +0400
parents 27d9d1f26b38
children 30862655219e
comparison
equal deleted inserted replaced
295:65b7ac8795e3 296:2ceaee987f37
326 u->output.output_filter = ngx_chain_writer; 326 u->output.output_filter = ngx_chain_writer;
327 u->output.filter_ctx = &u->writer; 327 u->output.filter_ctx = &u->writer;
328 328
329 u->writer.pool = r->pool; 329 u->writer.pool = r->pool;
330 330
331 if (ngx_array_init(&u->states, r->pool, 1, 331 if (r->upstream_states == NULL) {
332 sizeof(ngx_http_upstream_state_t)) 332
333 != NGX_OK) 333 r->upstream_states = ngx_array_create(r->pool, 1,
334 { 334 sizeof(ngx_http_upstream_state_t));
335 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 335 if (r->upstream_states == NULL) {
336 return; 336 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
337 return;
338 }
339
340 } else {
341
342 u->state = ngx_array_push(r->upstream_states);
343 if (u->state == NULL) {
344 ngx_http_upstream_finalize_request(r, u,
345 NGX_HTTP_INTERNAL_SERVER_ERROR);
346 return;
347 }
348
349 ngx_memzero(u->state, sizeof(ngx_http_upstream_state_t));
337 } 350 }
338 351
339 cln = ngx_http_cleanup_add(r, 0); 352 cln = ngx_http_cleanup_add(r, 0);
340 if (cln == NULL) { 353 if (cln == NULL) {
341 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); 354 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
507 tp = ngx_timeofday(); 520 tp = ngx_timeofday();
508 u->state->response_sec = tp->sec - u->state->response_sec; 521 u->state->response_sec = tp->sec - u->state->response_sec;
509 u->state->response_msec = tp->msec - u->state->response_msec; 522 u->state->response_msec = tp->msec - u->state->response_msec;
510 } 523 }
511 524
512 u->state = ngx_array_push(&u->states); 525 u->state = ngx_array_push(r->upstream_states);
513 if (u->state == NULL) { 526 if (u->state == NULL) {
514 ngx_http_upstream_finalize_request(r, u, 527 ngx_http_upstream_finalize_request(r, u,
515 NGX_HTTP_INTERNAL_SERVER_ERROR); 528 NGX_HTTP_INTERNAL_SERVER_ERROR);
516 return; 529 return;
517 } 530 }
765 778
766 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, 779 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
767 "http upstream send request"); 780 "http upstream send request");
768 781
769 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { 782 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
770 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); 783 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
771 return; 784 return;
772 } 785 }
773 786
774 c->log->action = "sending request to upstream"; 787 c->log->action = "sending request to upstream";
775 788
912 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT); 925 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_TIMEOUT);
913 return; 926 return;
914 } 927 }
915 928
916 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) { 929 if (!u->request_sent && ngx_http_upstream_test_connect(c) != NGX_OK) {
917 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR); 930 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
918 return; 931 return;
919 } 932 }
920 933
921 if (u->buffer.start == NULL) { 934 if (u->buffer.start == NULL) {
922 u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size); 935 u->buffer.start = ngx_palloc(r->pool, u->conf->buffer_size);
1257 socklen_t len; 1270 socklen_t len;
1258 1271
1259 #if (NGX_HAVE_KQUEUE) 1272 #if (NGX_HAVE_KQUEUE)
1260 1273
1261 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) { 1274 if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1262 if (c->write->pending_eof) { 1275 if (c->write->pending_eof) {
1263 (void) ngx_connection_error(c, c->write->kq_errno, 1276 (void) ngx_connection_error(c, c->write->kq_errno,
1264 "kevent() reported that connect() failed"); 1277 "kevent() reported that connect() failed");
1265 return NGX_ERROR; 1278 return NGX_ERROR;
1266 } 1279 }
1267 1280
1268 } else 1281 } else
1269 #endif 1282 #endif
1270 { 1283 {
1271 err = 0; 1284 err = 0;
1272 len = sizeof(int); 1285 len = sizeof(int);
1273 1286
1274 /* 1287 /*
1275 * BSDs and Linux return 0 and set a pending error in err 1288 * BSDs and Linux return 0 and set a pending error in err
1276 * Solaris returns -1 and sets errno 1289 * Solaris returns -1 and sets errno
1277 */ 1290 */
1278 1291
1279 if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len) 1292 if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1280 == -1) 1293 == -1)
1281 { 1294 {
1282 err = ngx_errno; 1295 err = ngx_errno;
1283 } 1296 }
1284 1297
1285 if (err) { 1298 if (err) {
1286 (void) ngx_connection_error(c, err, "connect() failed"); 1299 (void) ngx_connection_error(c, err, "connect() failed");
1287 return NGX_ERROR; 1300 return NGX_ERROR;
1288 } 1301 }
1289 } 1302 }
1290 1303
1291 return NGX_OK; 1304 return NGX_OK;
1292 } 1305 }
1293 1306
2500 ngx_http_variable_value_t *v, uintptr_t data) 2513 ngx_http_variable_value_t *v, uintptr_t data)
2501 { 2514 {
2502 u_char *p; 2515 u_char *p;
2503 size_t len; 2516 size_t len;
2504 ngx_uint_t i; 2517 ngx_uint_t i;
2505 ngx_http_upstream_t *u;
2506 ngx_http_upstream_state_t *state; 2518 ngx_http_upstream_state_t *state;
2507 2519
2508 v->valid = 1; 2520 v->valid = 1;
2509 v->no_cachable = 0; 2521 v->no_cachable = 0;
2510 v->not_found = 0; 2522 v->not_found = 0;
2511 2523
2512 u = r->upstream; 2524 if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
2513
2514 if (u == NULL || u->states.nelts == 0) {
2515 v->not_found = 1; 2525 v->not_found = 1;
2516 return NGX_OK; 2526 return NGX_OK;
2517 } 2527 }
2518 2528
2519 len = u->states.nelts * (3 + 2); 2529 len = r->upstream_states->nelts * (3 + 2);
2520 2530
2521 p = ngx_palloc(r->pool, len); 2531 p = ngx_palloc(r->pool, len);
2522 if (p == NULL) { 2532 if (p == NULL) {
2523 return NGX_ERROR; 2533 return NGX_ERROR;
2524 } 2534 }
2525 2535
2526 v->data = p; 2536 v->data = p;
2527 2537
2528 i = 0; 2538 i = 0;
2529 state = u->states.elts; 2539 state = r->upstream_states->elts;
2530 2540
2531 for ( ;; ) { 2541 for ( ;; ) {
2532 if (state[i].status == 0) { 2542 if (state[i].status) {
2543 p = ngx_sprintf(p, "%ui", state[i].status);
2544
2545 } else {
2533 *p++ = '-'; 2546 *p++ = '-';
2547 }
2548
2549 if (++i == r->upstream_states->nelts) {
2550 break;
2551 }
2552
2553 if (state[i].peer) {
2554 *p++ = ',';
2555 *p++ = ' ';
2534 2556
2535 } else { 2557 } else {
2536 p = ngx_sprintf(p, "%ui", state[i].status); 2558 *p++ = ' ';
2537 } 2559 *p++ = ':';
2538 2560 *p++ = ' ';
2539 if (++i == u->states.nelts) { 2561
2540 break; 2562 if (++i == r->upstream_states->nelts) {
2541 } 2563 break;
2542 2564 }
2543 *p++ = ','; 2565
2544 *p++ = ' '; 2566 continue;
2567 }
2545 } 2568 }
2546 2569
2547 v->len = p - v->data; 2570 v->len = p - v->data;
2548 2571
2549 return NGX_OK; 2572 return NGX_OK;
2556 { 2579 {
2557 u_char *p; 2580 u_char *p;
2558 size_t len; 2581 size_t len;
2559 ngx_uint_t i; 2582 ngx_uint_t i;
2560 ngx_msec_int_t ms; 2583 ngx_msec_int_t ms;
2561 ngx_http_upstream_t *u;
2562 ngx_http_upstream_state_t *state; 2584 ngx_http_upstream_state_t *state;
2563 2585
2564 v->valid = 1; 2586 v->valid = 1;
2565 v->no_cachable = 0; 2587 v->no_cachable = 0;
2566 v->not_found = 0; 2588 v->not_found = 0;
2567 2589
2568 u = r->upstream; 2590 if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
2569
2570 if (u == NULL || u->states.nelts == 0) {
2571 v->not_found = 1; 2591 v->not_found = 1;
2572 return NGX_OK; 2592 return NGX_OK;
2573 } 2593 }
2574 2594
2575 len = u->states.nelts * (NGX_TIME_T_LEN + 4 + 2); 2595 len = r->upstream_states->nelts * (NGX_TIME_T_LEN + 4 + 2);
2576 2596
2577 p = ngx_palloc(r->pool, len); 2597 p = ngx_palloc(r->pool, len);
2578 if (p == NULL) { 2598 if (p == NULL) {
2579 return NGX_ERROR; 2599 return NGX_ERROR;
2580 } 2600 }
2581 2601
2582 v->data = p; 2602 v->data = p;
2583 2603
2584 i = 0; 2604 i = 0;
2585 state = u->states.elts; 2605 state = r->upstream_states->elts;
2586 2606
2587 for ( ;; ) { 2607 for ( ;; ) {
2588 if (state[i].status == 0) { 2608 if (state[i].status) {
2589 *p++ = '-';
2590
2591 } else {
2592 ms = state[i].response_sec * 1000 + state[i].response_msec; 2609 ms = state[i].response_sec * 1000 + state[i].response_msec;
2593 ms = (ms >= 0) ? ms : 0; 2610 ms = (ms >= 0) ? ms : 0;
2594 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); 2611 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
2595 } 2612
2596 2613 } else {
2597 if (++i == u->states.nelts) { 2614 *p++ = '-';
2615 }
2616
2617 if (++i == r->upstream_states->nelts) {
2598 break; 2618 break;
2599 } 2619 }
2600 2620
2601 *p++ = ','; 2621 if (state[i].peer) {
2602 *p++ = ' '; 2622 *p++ = ',';
2623 *p++ = ' ';
2624
2625 } else {
2626 *p++ = ' ';
2627 *p++ = ':';
2628 *p++ = ' ';
2629
2630 if (++i == r->upstream_states->nelts) {
2631 break;
2632 }
2633
2634 continue;
2635 }
2603 } 2636 }
2604 2637
2605 v->len = p - v->data; 2638 v->len = p - v->data;
2606 2639
2607 return NGX_OK; 2640 return NGX_OK;
2641 }
2642
2643
2644 ngx_int_t
2645 ngx_http_upstream_header_variable(ngx_http_request_t *r,
2646 ngx_http_variable_value_t *v, uintptr_t data)
2647 {
2648 if (r->upstream == NULL) {
2649 v->not_found = 1;
2650 return NGX_OK;
2651 }
2652
2653 return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
2654 &r->upstream->headers_in.headers.part,
2655 sizeof("upstream_http_") - 1);
2608 } 2656 }
2609 2657
2610 2658
2611 static char * 2659 static char *
2612 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) 2660 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)