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