Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_upstream.c @ 635:e67b227c8dbb default tip
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 25 Apr 2011 04:07:55 +0400 |
parents | b9763778e212 |
children |
comparison
equal
deleted
inserted
replaced
578:f3a9e57d2e17 | 635:e67b227c8dbb |
---|---|
70 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, | 70 static void ngx_http_upstream_finalize_request(ngx_http_request_t *r, |
71 ngx_http_upstream_t *u, ngx_int_t rc); | 71 ngx_http_upstream_t *u, ngx_int_t rc); |
72 | 72 |
73 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, | 73 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, |
74 ngx_table_elt_t *h, ngx_uint_t offset); | 74 ngx_table_elt_t *h, ngx_uint_t offset); |
75 static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, | |
76 ngx_table_elt_t *h, ngx_uint_t offset); | |
75 static ngx_int_t | 77 static ngx_int_t |
76 ngx_http_upstream_process_cache_control(ngx_http_request_t *r, | 78 ngx_http_upstream_process_cache_control(ngx_http_request_t *r, |
77 ngx_table_elt_t *h, ngx_uint_t offset); | 79 ngx_table_elt_t *h, ngx_uint_t offset); |
78 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, | 80 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, |
79 ngx_table_elt_t *h, ngx_uint_t offset); | 81 ngx_table_elt_t *h, ngx_uint_t offset); |
187 { ngx_string("Refresh"), | 189 { ngx_string("Refresh"), |
188 ngx_http_upstream_ignore_header_line, 0, | 190 ngx_http_upstream_ignore_header_line, 0, |
189 ngx_http_upstream_rewrite_refresh, 0, 0 }, | 191 ngx_http_upstream_rewrite_refresh, 0, 0 }, |
190 | 192 |
191 { ngx_string("Set-Cookie"), | 193 { ngx_string("Set-Cookie"), |
192 ngx_http_upstream_ignore_header_line, 0, | 194 ngx_http_upstream_process_set_cookie, 0, |
193 ngx_http_upstream_copy_header_line, 0, 1 }, | 195 ngx_http_upstream_copy_header_line, 0, 1 }, |
194 | 196 |
195 { ngx_string("Content-Disposition"), | 197 { ngx_string("Content-Disposition"), |
196 ngx_http_upstream_ignore_header_line, 0, | 198 ngx_http_upstream_ignore_header_line, 0, |
197 ngx_http_upstream_copy_header_line, 0, 1 }, | 199 ngx_http_upstream_copy_header_line, 0, 1 }, |
353 { ngx_string("POST"), NGX_HTTP_POST }, | 355 { ngx_string("POST"), NGX_HTTP_POST }, |
354 { ngx_null_string, 0 } | 356 { ngx_null_string, 0 } |
355 }; | 357 }; |
356 | 358 |
357 | 359 |
360 ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = { | |
361 { ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT }, | |
362 { ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES }, | |
363 { ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES }, | |
364 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL }, | |
365 { ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE }, | |
366 { ngx_null_string, 0 } | |
367 }; | |
368 | |
369 | |
358 ngx_int_t | 370 ngx_int_t |
359 ngx_http_upstream_create(ngx_http_request_t *r) | 371 ngx_http_upstream_create(ngx_http_request_t *r) |
360 { | 372 { |
361 ngx_http_upstream_t *u; | 373 ngx_http_upstream_t *u; |
362 | 374 |
363 u = r->upstream; | 375 u = r->upstream; |
364 | 376 |
365 if (u && u->cleanup) { | 377 if (u && u->cleanup) { |
366 r->main->count++; | 378 r->main->count++; |
367 ngx_http_upstream_cleanup(r); | 379 ngx_http_upstream_cleanup(r); |
368 *u->cleanup = NULL; | |
369 u->cleanup = NULL; | |
370 } | 380 } |
371 | 381 |
372 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); | 382 u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); |
373 if (u == NULL) { | 383 if (u == NULL) { |
374 return NGX_ERROR; | 384 return NGX_ERROR; |
562 { | 572 { |
563 goto found; | 573 goto found; |
564 } | 574 } |
565 } | 575 } |
566 | 576 |
577 if (u->resolved->port == 0) { | |
578 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
579 "no port in upstream \"%V\"", host); | |
580 ngx_http_upstream_finalize_request(r, u, | |
581 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
582 return; | |
583 } | |
584 | |
567 temp.name = *host; | 585 temp.name = *host; |
568 | 586 |
569 ctx = ngx_resolve_start(clcf->resolver, &temp); | 587 ctx = ngx_resolve_start(clcf->resolver, &temp); |
570 if (ctx == NULL) { | 588 if (ctx == NULL) { |
571 ngx_http_upstream_finalize_request(r, u, | 589 ngx_http_upstream_finalize_request(r, u, |
621 | 639 |
622 c = r->cache; | 640 c = r->cache; |
623 | 641 |
624 if (c == NULL) { | 642 if (c == NULL) { |
625 | 643 |
644 switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) { | |
645 | |
646 case NGX_ERROR: | |
647 return NGX_ERROR; | |
648 | |
649 case NGX_DECLINED: | |
650 u->cache_status = NGX_HTTP_CACHE_BYPASS; | |
651 return NGX_DECLINED; | |
652 | |
653 default: /* NGX_OK */ | |
654 break; | |
655 } | |
656 | |
626 if (!(r->method & u->conf->cache_methods)) { | 657 if (!(r->method & u->conf->cache_methods)) { |
627 return NGX_DECLINED; | 658 return NGX_DECLINED; |
628 } | 659 } |
629 | 660 |
630 if (r->method & NGX_HTTP_HEAD) { | 661 if (r->method & NGX_HTTP_HEAD) { |
631 u->method = ngx_http_core_get_method; | 662 u->method = ngx_http_core_get_method; |
632 } | 663 } |
633 | 664 |
634 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); | 665 if (ngx_http_file_cache_new(r) != NGX_OK) { |
635 if (c == NULL) { | |
636 return NGX_ERROR; | 666 return NGX_ERROR; |
637 } | 667 } |
638 | |
639 if (ngx_array_init(&c->keys, r->pool, 4, sizeof(ngx_str_t)) != NGX_OK) { | |
640 return NGX_ERROR; | |
641 } | |
642 | |
643 r->cache = c; | |
644 c->file.log = r->connection->log; | |
645 | 668 |
646 if (u->create_key(r) != NGX_OK) { | 669 if (u->create_key(r) != NGX_OK) { |
647 return NGX_ERROR; | 670 return NGX_ERROR; |
648 } | 671 } |
649 | 672 |
650 /* TODO: add keys */ | 673 /* TODO: add keys */ |
651 | 674 |
652 ngx_http_file_cache_create_key(r); | 675 ngx_http_file_cache_create_key(r); |
653 | 676 |
654 u->cacheable = 1; | 677 u->cacheable = 1; |
678 | |
679 c = r->cache; | |
655 | 680 |
656 c->min_uses = u->conf->cache_min_uses; | 681 c->min_uses = u->conf->cache_min_uses; |
657 c->body_start = u->conf->buffer_size; | 682 c->body_start = u->conf->buffer_size; |
658 c->file_cache = u->conf->cache->data; | 683 c->file_cache = u->conf->cache->data; |
659 | 684 |
1701 *h = *u->headers_in.www_authenticate; | 1726 *h = *u->headers_in.www_authenticate; |
1702 | 1727 |
1703 r->headers_out.www_authenticate = h; | 1728 r->headers_out.www_authenticate = h; |
1704 } | 1729 } |
1705 | 1730 |
1731 #if (NGX_HTTP_CACHE) | |
1732 | |
1733 if (r->cache) { | |
1734 time_t valid; | |
1735 | |
1736 valid = ngx_http_file_cache_valid(u->conf->cache_valid, status); | |
1737 | |
1738 if (valid) { | |
1739 r->cache->valid_sec = ngx_time() + valid; | |
1740 r->cache->error = status; | |
1741 } | |
1742 | |
1743 ngx_http_file_cache_free(r->cache, u->pipe->temp_file); | |
1744 } | |
1745 #endif | |
1706 ngx_http_upstream_finalize_request(r, u, status); | 1746 ngx_http_upstream_finalize_request(r, u, status); |
1707 | 1747 |
1708 return NGX_OK; | 1748 return NGX_OK; |
1709 } | 1749 } |
1710 } | 1750 } |
1800 } | 1840 } |
1801 } | 1841 } |
1802 } | 1842 } |
1803 | 1843 |
1804 uri = &u->headers_in.x_accel_redirect->value; | 1844 uri = &u->headers_in.x_accel_redirect->value; |
1805 args.len = 0; | 1845 ngx_str_null(&args); |
1806 args.data = NULL; | |
1807 flags = NGX_HTTP_LOG_UNSAFE; | 1846 flags = NGX_HTTP_LOG_UNSAFE; |
1808 | 1847 |
1809 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { | 1848 if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) { |
1810 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); | 1849 ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); |
1811 return NGX_DONE; | 1850 return NGX_DONE; |
1812 } | |
1813 | |
1814 if (flags & NGX_HTTP_ZERO_IN_URI) { | |
1815 r->zero_in_uri = 1; | |
1816 } | 1851 } |
1817 | 1852 |
1818 if (r->method != NGX_HTTP_HEAD) { | 1853 if (r->method != NGX_HTTP_HEAD) { |
1819 r->method = NGX_HTTP_GET; | 1854 r->method = NGX_HTTP_GET; |
1820 } | 1855 } |
1919 | 1954 |
1920 size = b->end - b->last; | 1955 size = b->end - b->last; |
1921 | 1956 |
1922 if (size == 0) { | 1957 if (size == 0) { |
1923 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | 1958 ngx_log_error(NGX_LOG_ALERT, c->log, 0, |
1924 "upstream buffer is too small to read repsonse"); | 1959 "upstream buffer is too small to read response"); |
1925 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); | 1960 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
1926 return; | 1961 return; |
1927 } | 1962 } |
1928 | 1963 |
1929 n = c->recv(c, b->last, size); | 1964 n = c->recv(c, b->last, size); |
2084 if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) { | 2119 if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) { |
2085 ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd); | 2120 ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd); |
2086 r->cache->file.fd = NGX_INVALID_FILE; | 2121 r->cache->file.fd = NGX_INVALID_FILE; |
2087 } | 2122 } |
2088 | 2123 |
2124 switch (ngx_http_test_predicates(r, u->conf->no_cache)) { | |
2125 | |
2126 case NGX_ERROR: | |
2127 ngx_http_upstream_finalize_request(r, u, 0); | |
2128 return; | |
2129 | |
2130 case NGX_DECLINED: | |
2131 u->cacheable = 0; | |
2132 break; | |
2133 | |
2134 default: /* NGX_OK */ | |
2135 | |
2136 if (u->cache_status == NGX_HTTP_CACHE_BYPASS) { | |
2137 | |
2138 if (ngx_http_file_cache_new(r) != NGX_OK) { | |
2139 ngx_http_upstream_finalize_request(r, u, 0); | |
2140 return; | |
2141 } | |
2142 | |
2143 if (u->create_key(r) != NGX_OK) { | |
2144 ngx_http_upstream_finalize_request(r, u, 0); | |
2145 return; | |
2146 } | |
2147 | |
2148 /* TODO: add keys */ | |
2149 | |
2150 r->cache->min_uses = u->conf->cache_min_uses; | |
2151 r->cache->body_start = u->conf->buffer_size; | |
2152 r->cache->file_cache = u->conf->cache->data; | |
2153 | |
2154 if (ngx_http_file_cache_create(r) != NGX_OK) { | |
2155 ngx_http_upstream_finalize_request(r, u, 0); | |
2156 return; | |
2157 } | |
2158 | |
2159 u->cacheable = 1; | |
2160 } | |
2161 | |
2162 break; | |
2163 } | |
2164 | |
2089 if (u->cacheable) { | 2165 if (u->cacheable) { |
2090 time_t now, valid; | 2166 time_t now, valid; |
2091 | 2167 |
2092 now = ngx_time(); | 2168 now = ngx_time(); |
2093 | 2169 |
2116 | 2192 |
2117 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, | 2193 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, |
2118 "http cacheable: %d", u->cacheable); | 2194 "http cacheable: %d", u->cacheable); |
2119 | 2195 |
2120 if (u->cacheable == 0 && r->cache) { | 2196 if (u->cacheable == 0 && r->cache) { |
2121 ngx_http_file_cache_free(r, u->pipe->temp_file); | 2197 ngx_http_file_cache_free(r->cache, u->pipe->temp_file); |
2122 } | 2198 } |
2123 | 2199 |
2124 #endif | 2200 #endif |
2125 | 2201 |
2126 p = u->pipe; | 2202 p = u->pipe; |
2591 /* TODO: check length & update cache */ | 2667 /* TODO: check length & update cache */ |
2592 | 2668 |
2593 ngx_http_file_cache_update(r, u->pipe->temp_file); | 2669 ngx_http_file_cache_update(r, u->pipe->temp_file); |
2594 | 2670 |
2595 } else if (p->upstream_error) { | 2671 } else if (p->upstream_error) { |
2596 ngx_http_file_cache_free(r, u->pipe->temp_file); | 2672 ngx_http_file_cache_free(r->cache, u->pipe->temp_file); |
2597 } | 2673 } |
2598 } | 2674 } |
2599 | 2675 |
2600 #endif | 2676 #endif |
2601 | 2677 |
2919 #if (NGX_HTTP_CACHE) | 2995 #if (NGX_HTTP_CACHE) |
2920 | 2996 |
2921 if (u->cacheable && r->cache) { | 2997 if (u->cacheable && r->cache) { |
2922 time_t valid; | 2998 time_t valid; |
2923 | 2999 |
2924 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
2925 "http upstream cache fd: %d", | |
2926 r->cache->file.fd); | |
2927 | |
2928 if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) { | 3000 if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) { |
2929 | 3001 |
2930 valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc); | 3002 valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc); |
2931 | 3003 |
2932 if (valid) { | 3004 if (valid) { |
2933 r->cache->valid_sec = ngx_time() + valid; | 3005 r->cache->valid_sec = ngx_time() + valid; |
2934 r->cache->error = rc; | 3006 r->cache->error = rc; |
2935 } | 3007 } |
2936 } | 3008 } |
2937 | 3009 |
2938 ngx_http_file_cache_free(r, u->pipe->temp_file); | 3010 ngx_http_file_cache_free(r->cache, u->pipe->temp_file); |
2939 } | 3011 } |
2940 | 3012 |
2941 #endif | 3013 #endif |
2942 | 3014 |
2943 if (u->header_sent | 3015 if (u->header_sent |
2978 | 3050 |
2979 static ngx_int_t | 3051 static ngx_int_t |
2980 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | 3052 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, |
2981 ngx_uint_t offset) | 3053 ngx_uint_t offset) |
2982 { | 3054 { |
3055 return NGX_OK; | |
3056 } | |
3057 | |
3058 | |
3059 static ngx_int_t | |
3060 ngx_http_upstream_process_set_cookie(ngx_http_request_t *r, ngx_table_elt_t *h, | |
3061 ngx_uint_t offset) | |
3062 { | |
3063 #if (NGX_HTTP_CACHE) | |
3064 ngx_http_upstream_t *u; | |
3065 | |
3066 u = r->upstream; | |
3067 | |
3068 if (!(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_SET_COOKIE)) { | |
3069 u->cacheable = 0; | |
3070 } | |
3071 #endif | |
3072 | |
2983 return NGX_OK; | 3073 return NGX_OK; |
2984 } | 3074 } |
2985 | 3075 |
2986 | 3076 |
2987 static ngx_int_t | 3077 static ngx_int_t |
3024 | 3114 |
3025 if (r->cache->valid_sec != 0) { | 3115 if (r->cache->valid_sec != 0) { |
3026 return NGX_OK; | 3116 return NGX_OK; |
3027 } | 3117 } |
3028 | 3118 |
3029 last = h->value.data + h->value.len; | 3119 p = h->value.data; |
3030 | 3120 last = p + h->value.len; |
3031 if (ngx_strlcasestrn(h->value.data, last, (u_char *) "no-cache", 8 - 1) | 3121 |
3032 != NULL) | 3122 if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL |
3123 || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL | |
3124 || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL) | |
3033 { | 3125 { |
3034 u->cacheable = 0; | 3126 u->cacheable = 0; |
3035 return NGX_OK; | 3127 return NGX_OK; |
3036 } | 3128 } |
3037 | 3129 |
3038 p = ngx_strlcasestrn(h->value.data, last, (u_char *) "max-age=", 8 - 1); | 3130 p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1); |
3039 | 3131 |
3040 if (p == NULL) { | 3132 if (p == NULL) { |
3041 return NGX_OK; | 3133 return NGX_OK; |
3042 } | 3134 } |
3043 | 3135 |
3710 | 3802 |
3711 for ( ;; ) { | 3803 for ( ;; ) { |
3712 if (state[i].status) { | 3804 if (state[i].status) { |
3713 ms = (ngx_msec_int_t) | 3805 ms = (ngx_msec_int_t) |
3714 (state[i].response_sec * 1000 + state[i].response_msec); | 3806 (state[i].response_sec * 1000 + state[i].response_msec); |
3715 ms = (ms >= 0) ? ms : 0; | 3807 ms = ngx_max(ms, 0); |
3716 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); | 3808 p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000); |
3717 | 3809 |
3718 } else { | 3810 } else { |
3719 *p++ = '-'; | 3811 *p++ = '-'; |
3720 } | 3812 } |