Mercurial > hg > nginx-vendor-0-8
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) |