Mercurial > hg > nginx-vendor-1-0
comparison src/http/ngx_http_upstream.c @ 472:09f0ef15d544 NGINX_0_7_48
nginx 0.7.48
*) Feature: the "proxy_cache_key" directive.
*) Bugfix: now nginx takes into account the "X-Accel-Expires",
"Expires", and "Cache-Control" header lines in a backend response.
*) Bugfix: now nginx caches responses for the GET requests only.
*) Bugfix: the "fastcgi_cache_key" directive was not inherited.
*) Bugfix: the $arg_... variables did not work with SSI subrequests.
Thanks to Maxim Dounin.
*) Bugfix: nginx could not be built with uclibc library.
Thanks to Timothy Redaelli.
*) Bugfix: nginx could not be built on OpenBSD; the bug had
appeared in 0.7.46.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 06 Apr 2009 00:00:00 +0400 |
parents | c8cfb6c462ef |
children | f2c6a7373274 |
comparison
equal
deleted
inserted
replaced
471:0cc33540f2e0 | 472:09f0ef15d544 |
---|---|
68 ngx_http_upstream_t *u, ngx_int_t rc); | 68 ngx_http_upstream_t *u, ngx_int_t rc); |
69 | 69 |
70 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, | 70 static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r, |
71 ngx_table_elt_t *h, ngx_uint_t offset); | 71 ngx_table_elt_t *h, ngx_uint_t offset); |
72 static ngx_int_t | 72 static ngx_int_t |
73 ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, | 73 ngx_http_upstream_process_cache_control(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_ignore_header_line(ngx_http_request_t *r, | 75 static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, |
76 ngx_table_elt_t *h, ngx_uint_t offset); | |
77 static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r, | |
78 ngx_table_elt_t *h, ngx_uint_t offset); | |
79 static ngx_int_t ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, | |
76 ngx_table_elt_t *h, ngx_uint_t offset); | 80 ngx_table_elt_t *h, ngx_uint_t offset); |
77 static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, | 81 static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, |
78 ngx_table_elt_t *h, ngx_uint_t offset); | 82 ngx_table_elt_t *h, ngx_uint_t offset); |
79 static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r, | 83 static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r, |
80 ngx_table_elt_t *h, ngx_uint_t offset); | 84 ngx_table_elt_t *h, ngx_uint_t offset); |
182 { ngx_string("Content-Disposition"), | 186 { ngx_string("Content-Disposition"), |
183 ngx_http_upstream_ignore_header_line, 0, | 187 ngx_http_upstream_ignore_header_line, 0, |
184 ngx_http_upstream_copy_header_line, 0, 1 }, | 188 ngx_http_upstream_copy_header_line, 0, 1 }, |
185 | 189 |
186 { ngx_string("Cache-Control"), | 190 { ngx_string("Cache-Control"), |
187 ngx_http_upstream_process_multi_header_lines, | 191 ngx_http_upstream_process_cache_control, 0, |
188 offsetof(ngx_http_upstream_headers_in_t, cache_control), | |
189 ngx_http_upstream_copy_multi_header_lines, | 192 ngx_http_upstream_copy_multi_header_lines, |
190 offsetof(ngx_http_headers_out_t, cache_control), 1 }, | 193 offsetof(ngx_http_headers_out_t, cache_control), 1 }, |
191 | 194 |
192 { ngx_string("Expires"), | 195 { ngx_string("Expires"), |
193 ngx_http_upstream_process_header_line, | 196 ngx_http_upstream_process_expires, 0, |
194 offsetof(ngx_http_upstream_headers_in_t, expires), | |
195 ngx_http_upstream_copy_header_line, | 197 ngx_http_upstream_copy_header_line, |
196 offsetof(ngx_http_headers_out_t, expires), 1 }, | 198 offsetof(ngx_http_headers_out_t, expires), 1 }, |
197 | 199 |
198 { ngx_string("Accept-Ranges"), | 200 { ngx_string("Accept-Ranges"), |
199 ngx_http_upstream_process_header_line, | 201 ngx_http_upstream_process_header_line, |
212 { ngx_string("X-Powered-By"), | 214 { ngx_string("X-Powered-By"), |
213 ngx_http_upstream_ignore_header_line, 0, | 215 ngx_http_upstream_ignore_header_line, 0, |
214 ngx_http_upstream_copy_header_line, 0, 0 }, | 216 ngx_http_upstream_copy_header_line, 0, 0 }, |
215 | 217 |
216 { ngx_string("X-Accel-Expires"), | 218 { ngx_string("X-Accel-Expires"), |
217 ngx_http_upstream_process_header_line, | 219 ngx_http_upstream_process_accel_expires, 0, |
218 offsetof(ngx_http_upstream_headers_in_t, x_accel_expires), | |
219 ngx_http_upstream_copy_header_line, 0, 0 }, | 220 ngx_http_upstream_copy_header_line, 0, 0 }, |
220 | 221 |
221 { ngx_string("X-Accel-Redirect"), | 222 { ngx_string("X-Accel-Redirect"), |
222 ngx_http_upstream_process_header_line, | 223 ngx_http_upstream_process_header_line, |
223 offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), | 224 offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect), |
529 ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) | 530 ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u) |
530 { | 531 { |
531 ngx_int_t rc; | 532 ngx_int_t rc; |
532 ngx_http_cache_t *c; | 533 ngx_http_cache_t *c; |
533 | 534 |
535 if (!(r->method & NGX_HTTP_GET)) { | |
536 return NGX_DECLINED; | |
537 } | |
538 | |
534 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); | 539 c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); |
535 if (c == NULL) { | 540 if (c == NULL) { |
536 return NGX_ERROR; | 541 return NGX_ERROR; |
537 } | 542 } |
538 | 543 |
574 | 579 |
575 return NGX_ERROR; | 580 return NGX_ERROR; |
576 | 581 |
577 } else if (rc == NGX_HTTP_CACHE_STALE) { | 582 } else if (rc == NGX_HTTP_CACHE_STALE) { |
578 | 583 |
584 c->valid_sec = 0; | |
579 u->stale_cache = 1; | 585 u->stale_cache = 1; |
580 u->buffer.start = NULL; | 586 u->buffer.start = NULL; |
581 | 587 |
582 } else if (rc == NGX_DECLINED) { | 588 } else if (rc == NGX_DECLINED) { |
583 | 589 |
1908 } | 1914 } |
1909 | 1915 |
1910 if (u->cacheable) { | 1916 if (u->cacheable) { |
1911 time_t now, valid; | 1917 time_t now, valid; |
1912 | 1918 |
1913 valid = ngx_http_file_cache_valid(u->conf->cache_valid, | 1919 now = ngx_time(); |
1914 u->headers_in.status_n); | 1920 |
1921 valid = r->cache->valid_sec; | |
1922 | |
1923 if (valid == 0) { | |
1924 valid = ngx_http_file_cache_valid(u->conf->cache_valid, | |
1925 u->headers_in.status_n); | |
1926 if (valid) { | |
1927 r->cache->valid_sec = now + valid; | |
1928 } | |
1929 } | |
1930 | |
1915 if (valid) { | 1931 if (valid) { |
1916 | |
1917 now = ngx_time(); | |
1918 | |
1919 r->cache->valid_sec = now + valid; | |
1920 | |
1921 r->cache->last_modified = r->headers_out.last_modified_time; | 1932 r->cache->last_modified = r->headers_out.last_modified_time; |
1922 r->cache->date = now; | 1933 r->cache->date = now; |
1923 r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start); | 1934 r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start); |
1924 | 1935 |
1925 if (r->headers_out.content_length_n != -1) { | 1936 if (r->headers_out.content_length_n != -1) { |
2791 return NGX_OK; | 2802 return NGX_OK; |
2792 } | 2803 } |
2793 | 2804 |
2794 | 2805 |
2795 static ngx_int_t | 2806 static ngx_int_t |
2796 ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r, | 2807 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, |
2808 ngx_uint_t offset) | |
2809 { | |
2810 return NGX_OK; | |
2811 } | |
2812 | |
2813 | |
2814 static ngx_int_t | |
2815 ngx_http_upstream_process_cache_control(ngx_http_request_t *r, | |
2797 ngx_table_elt_t *h, ngx_uint_t offset) | 2816 ngx_table_elt_t *h, ngx_uint_t offset) |
2798 { | 2817 { |
2818 u_char *p, *last; | |
2819 ngx_int_t n; | |
2799 ngx_array_t *pa; | 2820 ngx_array_t *pa; |
2800 ngx_table_elt_t **ph; | 2821 ngx_table_elt_t **ph; |
2801 | 2822 |
2802 pa = (ngx_array_t *) ((char *) &r->upstream->headers_in + offset); | 2823 pa = &r->upstream->headers_in.cache_control; |
2803 | 2824 |
2804 if (pa->elts == NULL) { | 2825 if (pa->elts == NULL) { |
2805 if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) | 2826 if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *)) != NGX_OK) |
2806 { | 2827 { |
2807 return NGX_ERROR; | 2828 return NGX_ERROR; |
2813 return NGX_ERROR; | 2834 return NGX_ERROR; |
2814 } | 2835 } |
2815 | 2836 |
2816 *ph = h; | 2837 *ph = h; |
2817 | 2838 |
2839 if (r->cache == NULL) { | |
2840 return NGX_OK; | |
2841 } | |
2842 | |
2843 if (r->cache->valid_sec != 0) { | |
2844 return NGX_OK; | |
2845 } | |
2846 | |
2847 last = h->value.data + h->value.len; | |
2848 | |
2849 if (ngx_strlcasestrn(h->value.data, last, (u_char *) "no-cache", 8 - 1) | |
2850 != NULL) | |
2851 { | |
2852 r->upstream->cacheable = 0; | |
2853 return NGX_OK; | |
2854 } | |
2855 | |
2856 p = ngx_strlcasestrn(h->value.data, last, (u_char *) "max-age=", 8 - 1); | |
2857 | |
2858 if (p == NULL) { | |
2859 return NGX_OK; | |
2860 } | |
2861 | |
2862 n = 0; | |
2863 | |
2864 for (p += 8; p < last; p++) { | |
2865 if (*p == ';' || *p == ' ') { | |
2866 break; | |
2867 } | |
2868 | |
2869 if (*p >= '0' && *p <= '9') { | |
2870 n = n * 10 + *p - '0'; | |
2871 continue; | |
2872 } | |
2873 | |
2874 r->upstream->cacheable = 0; | |
2875 return NGX_OK; | |
2876 } | |
2877 | |
2878 if (n == 0) { | |
2879 r->upstream->cacheable = 0; | |
2880 return NGX_OK; | |
2881 } | |
2882 | |
2883 r->cache->valid_sec = ngx_time() + n; | |
2818 return NGX_OK; | 2884 return NGX_OK; |
2819 } | 2885 } |
2820 | 2886 |
2821 | 2887 |
2822 static ngx_int_t | 2888 static ngx_int_t |
2823 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | 2889 ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h, |
2824 ngx_uint_t offset) | 2890 ngx_uint_t offset) |
2825 { | 2891 { |
2892 time_t expires; | |
2893 | |
2894 r->upstream->headers_in.expires = h; | |
2895 | |
2896 if (r->cache == NULL) { | |
2897 return NGX_OK; | |
2898 } | |
2899 | |
2900 if (r->cache->valid_sec != 0) { | |
2901 return NGX_OK; | |
2902 } | |
2903 | |
2904 expires = ngx_http_parse_time(h->value.data, h->value.len); | |
2905 | |
2906 if (expires == NGX_ERROR || expires < ngx_time()) { | |
2907 r->upstream->cacheable = 0; | |
2908 return NGX_OK; | |
2909 } | |
2910 | |
2911 r->cache->valid_sec = expires; | |
2912 | |
2913 return NGX_OK; | |
2914 } | |
2915 | |
2916 | |
2917 static ngx_int_t | |
2918 ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, | |
2919 ngx_table_elt_t *h, ngx_uint_t offset) | |
2920 { | |
2921 u_char *p; | |
2922 size_t len; | |
2923 ngx_int_t n; | |
2924 | |
2925 r->upstream->headers_in.x_accel_expires = h; | |
2926 | |
2927 if (r->cache == NULL) { | |
2928 return NGX_OK; | |
2929 } | |
2930 | |
2931 len = h->value.len; | |
2932 p = h->value.data; | |
2933 | |
2934 if (p[0] != '@') { | |
2935 n = ngx_atoi(p, len); | |
2936 | |
2937 switch (n) { | |
2938 case 0: | |
2939 r->upstream->cacheable = 0; | |
2940 case NGX_ERROR: | |
2941 return NGX_OK; | |
2942 | |
2943 default: | |
2944 r->cache->valid_sec = ngx_time() + n; | |
2945 return NGX_OK; | |
2946 } | |
2947 } | |
2948 | |
2949 p++; | |
2950 len--; | |
2951 | |
2952 n = ngx_atoi(p, len); | |
2953 | |
2954 if (n != NGX_ERROR) { | |
2955 r->cache->valid_sec = n; | |
2956 } | |
2957 | |
2826 return NGX_OK; | 2958 return NGX_OK; |
2827 } | 2959 } |
2828 | 2960 |
2829 | 2961 |
2830 static ngx_int_t | 2962 static ngx_int_t |