Mercurial > hg > nginx-vendor-current
comparison src/http/ngx_http_upstream.c @ 640:eb208e0cf44d NGINX_1_1_4
nginx 1.1.4
*) Feature: the ngx_http_upstream_keepalive module.
*) Feature: the "proxy_http_version" directive.
*) Feature: the "fastcgi_keep_conn" directive.
*) Feature: the "worker_aio_requests" directive.
*) Bugfix: if nginx was built --with-file-aio it could not be run on
Linux kernel which did not support AIO.
*) Bugfix: in Linux AIO error processing.
Thanks to Hagai Avrahami.
*) Bugfix: reduced memory consumption for long-lived requests.
*) Bugfix: the module ngx_http_mp4_module did not support 64-bit MP4
"co64" atom.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Tue, 20 Sep 2011 00:00:00 +0400 |
parents | 5b73504dd4ba |
children | d3cf6c6b0043 |
comparison
equal
deleted
inserted
replaced
639:b516b4e38bc9 | 640:eb208e0cf44d |
---|---|
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_content_length(ngx_http_request_t *r, | |
76 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, | 77 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); | 78 ngx_table_elt_t *h, ngx_uint_t offset); |
77 static ngx_int_t | 79 static ngx_int_t |
78 ngx_http_upstream_process_cache_control(ngx_http_request_t *r, | 80 ngx_http_upstream_process_cache_control(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); |
87 ngx_table_elt_t *h, ngx_uint_t offset); | 89 ngx_table_elt_t *h, ngx_uint_t offset); |
88 static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r, | 90 static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r, |
89 ngx_table_elt_t *h, ngx_uint_t offset); | 91 ngx_table_elt_t *h, ngx_uint_t offset); |
90 static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r, | 92 static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r, |
91 ngx_table_elt_t *h, ngx_uint_t offset); | 93 ngx_table_elt_t *h, ngx_uint_t offset); |
94 static ngx_int_t ngx_http_upstream_process_connection(ngx_http_request_t *r, | |
95 ngx_table_elt_t *h, ngx_uint_t offset); | |
96 static ngx_int_t | |
97 ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r, | |
98 ngx_table_elt_t *h, ngx_uint_t offset); | |
92 static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, | 99 static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r, |
93 ngx_table_elt_t *h, ngx_uint_t offset); | 100 ngx_table_elt_t *h, ngx_uint_t offset); |
94 static ngx_int_t | 101 static ngx_int_t |
95 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, | 102 ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r, |
96 ngx_table_elt_t *h, ngx_uint_t offset); | 103 ngx_table_elt_t *h, ngx_uint_t offset); |
97 static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r, | 104 static ngx_int_t ngx_http_upstream_copy_content_type(ngx_http_request_t *r, |
98 ngx_table_elt_t *h, ngx_uint_t offset); | |
99 static ngx_int_t ngx_http_upstream_copy_content_length(ngx_http_request_t *r, | |
100 ngx_table_elt_t *h, ngx_uint_t offset); | 105 ngx_table_elt_t *h, ngx_uint_t offset); |
101 static ngx_int_t ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, | 106 static ngx_int_t ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, |
102 ngx_table_elt_t *h, ngx_uint_t offset); | 107 ngx_table_elt_t *h, ngx_uint_t offset); |
103 static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r, | 108 static ngx_int_t ngx_http_upstream_rewrite_location(ngx_http_request_t *r, |
104 ngx_table_elt_t *h, ngx_uint_t offset); | 109 ngx_table_elt_t *h, ngx_uint_t offset); |
147 ngx_http_upstream_process_header_line, | 152 ngx_http_upstream_process_header_line, |
148 offsetof(ngx_http_upstream_headers_in_t, content_type), | 153 offsetof(ngx_http_upstream_headers_in_t, content_type), |
149 ngx_http_upstream_copy_content_type, 0, 1 }, | 154 ngx_http_upstream_copy_content_type, 0, 1 }, |
150 | 155 |
151 { ngx_string("Content-Length"), | 156 { ngx_string("Content-Length"), |
152 ngx_http_upstream_process_header_line, | 157 ngx_http_upstream_process_content_length, |
153 offsetof(ngx_http_upstream_headers_in_t, content_length), | 158 offsetof(ngx_http_upstream_headers_in_t, content_length), |
154 ngx_http_upstream_copy_content_length, 0, 0 }, | 159 ngx_http_upstream_ignore_header_line, 0, 0 }, |
155 | 160 |
156 { ngx_string("Date"), | 161 { ngx_string("Date"), |
157 ngx_http_upstream_process_header_line, | 162 ngx_http_upstream_process_header_line, |
158 offsetof(ngx_http_upstream_headers_in_t, date), | 163 offsetof(ngx_http_upstream_headers_in_t, date), |
159 ngx_http_upstream_copy_header_line, | 164 ngx_http_upstream_copy_header_line, |
213 offsetof(ngx_http_upstream_headers_in_t, accept_ranges), | 218 offsetof(ngx_http_upstream_headers_in_t, accept_ranges), |
214 ngx_http_upstream_copy_allow_ranges, | 219 ngx_http_upstream_copy_allow_ranges, |
215 offsetof(ngx_http_headers_out_t, accept_ranges), 1 }, | 220 offsetof(ngx_http_headers_out_t, accept_ranges), 1 }, |
216 | 221 |
217 { ngx_string("Connection"), | 222 { ngx_string("Connection"), |
218 ngx_http_upstream_ignore_header_line, 0, | 223 ngx_http_upstream_process_connection, 0, |
219 ngx_http_upstream_ignore_header_line, 0, 0 }, | 224 ngx_http_upstream_ignore_header_line, 0, 0 }, |
220 | 225 |
221 { ngx_string("Keep-Alive"), | 226 { ngx_string("Keep-Alive"), |
222 ngx_http_upstream_ignore_header_line, 0, | 227 ngx_http_upstream_ignore_header_line, 0, |
223 ngx_http_upstream_ignore_header_line, 0, 0 }, | 228 ngx_http_upstream_ignore_header_line, 0, 0 }, |
244 ngx_http_upstream_copy_header_line, 0, 0 }, | 249 ngx_http_upstream_copy_header_line, 0, 0 }, |
245 | 250 |
246 { ngx_string("X-Accel-Charset"), | 251 { ngx_string("X-Accel-Charset"), |
247 ngx_http_upstream_process_charset, 0, | 252 ngx_http_upstream_process_charset, 0, |
248 ngx_http_upstream_copy_header_line, 0, 0 }, | 253 ngx_http_upstream_copy_header_line, 0, 0 }, |
254 | |
255 { ngx_string("Transfer-Encoding"), | |
256 ngx_http_upstream_process_transfer_encoding, 0, | |
257 ngx_http_upstream_ignore_header_line, 0, 0 }, | |
249 | 258 |
250 #if (NGX_HTTP_GZIP) | 259 #if (NGX_HTTP_GZIP) |
251 { ngx_string("Content-Encoding"), | 260 { ngx_string("Content-Encoding"), |
252 ngx_http_upstream_process_header_line, | 261 ngx_http_upstream_process_header_line, |
253 offsetof(ngx_http_upstream_headers_in_t, content_encoding), | 262 offsetof(ngx_http_upstream_headers_in_t, content_encoding), |
394 | 403 |
395 #if (NGX_HTTP_CACHE) | 404 #if (NGX_HTTP_CACHE) |
396 r->cache = NULL; | 405 r->cache = NULL; |
397 #endif | 406 #endif |
398 | 407 |
408 u->headers_in.content_length_n = -1; | |
409 | |
399 return NGX_OK; | 410 return NGX_OK; |
400 } | 411 } |
401 | 412 |
402 | 413 |
403 void | 414 void |
798 | 809 |
799 u->buffer = *c->buf; | 810 u->buffer = *c->buf; |
800 u->buffer.pos += c->header_start; | 811 u->buffer.pos += c->header_start; |
801 | 812 |
802 ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); | 813 ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); |
814 u->headers_in.content_length_n = -1; | |
803 | 815 |
804 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, | 816 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, |
805 sizeof(ngx_table_elt_t)) | 817 sizeof(ngx_table_elt_t)) |
806 != NGX_OK) | 818 != NGX_OK) |
807 { | 819 { |
1134 u->read_event_handler = ngx_http_upstream_process_header; | 1146 u->read_event_handler = ngx_http_upstream_process_header; |
1135 | 1147 |
1136 c->sendfile &= r->connection->sendfile; | 1148 c->sendfile &= r->connection->sendfile; |
1137 u->output.sendfile = c->sendfile; | 1149 u->output.sendfile = c->sendfile; |
1138 | 1150 |
1139 c->pool = r->pool; | 1151 if (c->pool == NULL) { |
1152 | |
1153 /* we need separate pool here to be able to cache SSL connections */ | |
1154 | |
1155 c->pool = ngx_create_pool(128, r->connection->log); | |
1156 if (c->pool == NULL) { | |
1157 ngx_http_upstream_finalize_request(r, u, | |
1158 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1159 return; | |
1160 } | |
1161 } | |
1162 | |
1140 c->log = r->connection->log; | 1163 c->log = r->connection->log; |
1164 c->pool->log = c->log; | |
1141 c->read->log = c->log; | 1165 c->read->log = c->log; |
1142 c->write->log = c->log; | 1166 c->write->log = c->log; |
1143 | 1167 |
1144 /* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */ | 1168 /* init or reinit the ngx_output_chain() and ngx_chain_writer() contexts */ |
1145 | 1169 |
1280 | 1304 |
1281 if (u->reinit_request(r) != NGX_OK) { | 1305 if (u->reinit_request(r) != NGX_OK) { |
1282 return NGX_ERROR; | 1306 return NGX_ERROR; |
1283 } | 1307 } |
1284 | 1308 |
1309 u->keepalive = 0; | |
1310 | |
1285 ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); | 1311 ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); |
1312 u->headers_in.content_length_n = -1; | |
1286 | 1313 |
1287 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, | 1314 if (ngx_list_init(&u->headers_in.headers, r->pool, 8, |
1288 sizeof(ngx_table_elt_t)) | 1315 sizeof(ngx_table_elt_t)) |
1289 != NGX_OK) | 1316 != NGX_OK) |
1290 { | 1317 { |
1922 } | 1949 } |
1923 | 1950 |
1924 r->headers_out.status = u->headers_in.status_n; | 1951 r->headers_out.status = u->headers_in.status_n; |
1925 r->headers_out.status_line = u->headers_in.status_line; | 1952 r->headers_out.status_line = u->headers_in.status_line; |
1926 | 1953 |
1927 u->headers_in.content_length_n = r->headers_out.content_length_n; | 1954 r->headers_out.content_length_n = u->headers_in.content_length_n; |
1928 | 1955 |
1929 if (r->headers_out.content_length_n != -1) { | 1956 u->length = u->headers_in.content_length_n; |
1930 u->length = (size_t) r->headers_out.content_length_n; | |
1931 | |
1932 } else { | |
1933 u->length = NGX_MAX_SIZE_T_VALUE; | |
1934 } | |
1935 | 1957 |
1936 return NGX_OK; | 1958 return NGX_OK; |
1937 } | 1959 } |
1938 | 1960 |
1939 | 1961 |
1991 } | 2013 } |
1992 | 2014 |
1993 if (!rev->ready) { | 2015 if (!rev->ready) { |
1994 break; | 2016 break; |
1995 } | 2017 } |
2018 } | |
2019 | |
2020 if (u->length == 0) { | |
2021 ngx_http_upstream_finalize_request(r, u, 0); | |
2022 return; | |
1996 } | 2023 } |
1997 | 2024 |
1998 if (ngx_handle_read_event(rev, 0) != NGX_OK) { | 2025 if (ngx_handle_read_event(rev, 0) != NGX_OK) { |
1999 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); | 2026 ngx_http_upstream_finalize_request(r, u, NGX_ERROR); |
2000 return; | 2027 return; |
2113 if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { | 2140 if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) { |
2114 ngx_http_upstream_finalize_request(r, u, 0); | 2141 ngx_http_upstream_finalize_request(r, u, 0); |
2115 return; | 2142 return; |
2116 } | 2143 } |
2117 | 2144 |
2118 if (u->peer.connection->read->ready) { | 2145 if (u->peer.connection->read->ready || u->length == 0) { |
2119 ngx_http_upstream_process_non_buffered_upstream(r, u); | 2146 ngx_http_upstream_process_non_buffered_upstream(r, u); |
2120 } | 2147 } |
2121 } | 2148 } |
2122 | 2149 |
2123 return; | 2150 return; |
2291 | 2318 |
2292 p->read_timeout = u->conf->read_timeout; | 2319 p->read_timeout = u->conf->read_timeout; |
2293 p->send_timeout = clcf->send_timeout; | 2320 p->send_timeout = clcf->send_timeout; |
2294 p->send_lowat = clcf->send_lowat; | 2321 p->send_lowat = clcf->send_lowat; |
2295 | 2322 |
2323 p->length = -1; | |
2324 | |
2325 if (u->input_filter_init | |
2326 && u->input_filter_init(p->input_ctx) != NGX_OK) | |
2327 { | |
2328 ngx_http_upstream_finalize_request(r, u, 0); | |
2329 return; | |
2330 } | |
2331 | |
2296 u->read_event_handler = ngx_http_upstream_process_upstream; | 2332 u->read_event_handler = ngx_http_upstream_process_upstream; |
2297 r->write_event_handler = ngx_http_upstream_process_downstream; | 2333 r->write_event_handler = ngx_http_upstream_process_downstream; |
2298 | 2334 |
2299 ngx_http_upstream_process_upstream(r, u); | 2335 ngx_http_upstream_process_upstream(r, u); |
2300 } | 2336 } |
2380 if (rc == NGX_ERROR) { | 2416 if (rc == NGX_ERROR) { |
2381 ngx_http_upstream_finalize_request(r, u, 0); | 2417 ngx_http_upstream_finalize_request(r, u, 0); |
2382 return; | 2418 return; |
2383 } | 2419 } |
2384 | 2420 |
2385 ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs, | 2421 ngx_chain_update_chains(r->pool, &u->free_bufs, &u->busy_bufs, |
2386 &u->out_bufs, u->output.tag); | 2422 &u->out_bufs, u->output.tag); |
2387 } | 2423 } |
2388 | 2424 |
2389 if (u->busy_bufs == NULL) { | 2425 if (u->busy_bufs == NULL) { |
2390 | 2426 |
2401 } | 2437 } |
2402 } | 2438 } |
2403 | 2439 |
2404 size = b->end - b->last; | 2440 size = b->end - b->last; |
2405 | 2441 |
2406 if (size > u->length) { | |
2407 size = u->length; | |
2408 } | |
2409 | |
2410 if (size && upstream->read->ready) { | 2442 if (size && upstream->read->ready) { |
2411 | 2443 |
2412 n = upstream->recv(upstream, b->last, size); | 2444 n = upstream->recv(upstream, b->last, size); |
2413 | 2445 |
2414 if (n == NGX_AGAIN) { | 2446 if (n == NGX_AGAIN) { |
2501 cl->buf->pos = b->last; | 2533 cl->buf->pos = b->last; |
2502 b->last += bytes; | 2534 b->last += bytes; |
2503 cl->buf->last = b->last; | 2535 cl->buf->last = b->last; |
2504 cl->buf->tag = u->output.tag; | 2536 cl->buf->tag = u->output.tag; |
2505 | 2537 |
2506 if (u->length == NGX_MAX_SIZE_T_VALUE) { | 2538 if (u->length == -1) { |
2507 return NGX_OK; | 2539 return NGX_OK; |
2508 } | 2540 } |
2509 | 2541 |
2510 u->length -= bytes; | 2542 u->length -= bytes; |
2511 | 2543 |
2810 } | 2842 } |
2811 | 2843 |
2812 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { | 2844 if (u->peer.cached && ft_type == NGX_HTTP_UPSTREAM_FT_ERROR) { |
2813 status = 0; | 2845 status = 0; |
2814 | 2846 |
2847 /* TODO: inform balancer instead */ | |
2848 | |
2849 u->peer.tries++; | |
2850 | |
2815 } else { | 2851 } else { |
2816 switch(ft_type) { | 2852 switch(ft_type) { |
2817 | 2853 |
2818 case NGX_HTTP_UPSTREAM_FT_TIMEOUT: | 2854 case NGX_HTTP_UPSTREAM_FT_TIMEOUT: |
2819 status = NGX_HTTP_GATEWAY_TIME_OUT; | 2855 status = NGX_HTTP_GATEWAY_TIME_OUT; |
2884 | 2920 |
2885 (void) ngx_ssl_shutdown(u->peer.connection); | 2921 (void) ngx_ssl_shutdown(u->peer.connection); |
2886 } | 2922 } |
2887 #endif | 2923 #endif |
2888 | 2924 |
2925 if (u->peer.connection->pool) { | |
2926 ngx_destroy_pool(u->peer.connection->pool); | |
2927 } | |
2928 | |
2889 ngx_close_connection(u->peer.connection); | 2929 ngx_close_connection(u->peer.connection); |
2890 } | 2930 } |
2891 | 2931 |
2892 #if 0 | 2932 #if 0 |
2893 if (u->conf->busy_lock && !u->busy_locked) { | 2933 if (u->conf->busy_lock && !u->busy_locked) { |
2978 | 3018 |
2979 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 3019 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
2980 "close http upstream connection: %d", | 3020 "close http upstream connection: %d", |
2981 u->peer.connection->fd); | 3021 u->peer.connection->fd); |
2982 | 3022 |
3023 if (u->peer.connection->pool) { | |
3024 ngx_destroy_pool(u->peer.connection->pool); | |
3025 } | |
3026 | |
2983 ngx_close_connection(u->peer.connection); | 3027 ngx_close_connection(u->peer.connection); |
2984 } | 3028 } |
2985 | 3029 |
2986 u->peer.connection = NULL; | 3030 u->peer.connection = NULL; |
2987 | 3031 |
3053 | 3097 |
3054 static ngx_int_t | 3098 static ngx_int_t |
3055 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | 3099 ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, |
3056 ngx_uint_t offset) | 3100 ngx_uint_t offset) |
3057 { | 3101 { |
3102 return NGX_OK; | |
3103 } | |
3104 | |
3105 | |
3106 static ngx_int_t | |
3107 ngx_http_upstream_process_content_length(ngx_http_request_t *r, | |
3108 ngx_table_elt_t *h, ngx_uint_t offset) | |
3109 { | |
3110 ngx_http_upstream_t *u; | |
3111 | |
3112 u = r->upstream; | |
3113 | |
3114 u->headers_in.content_length = h; | |
3115 u->headers_in.content_length_n = ngx_atoof(h->value.data, h->value.len); | |
3116 | |
3058 return NGX_OK; | 3117 return NGX_OK; |
3059 } | 3118 } |
3060 | 3119 |
3061 | 3120 |
3062 static ngx_int_t | 3121 static ngx_int_t |
3319 return NGX_OK; | 3378 return NGX_OK; |
3320 } | 3379 } |
3321 | 3380 |
3322 | 3381 |
3323 static ngx_int_t | 3382 static ngx_int_t |
3383 ngx_http_upstream_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h, | |
3384 ngx_uint_t offset) | |
3385 { | |
3386 r->upstream->headers_in.connection = h; | |
3387 | |
3388 if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, | |
3389 (u_char *) "close", 5 - 1) | |
3390 != NULL) | |
3391 { | |
3392 r->upstream->headers_in.connection_close = 1; | |
3393 } | |
3394 | |
3395 return NGX_OK; | |
3396 } | |
3397 | |
3398 | |
3399 static ngx_int_t | |
3400 ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r, | |
3401 ngx_table_elt_t *h, ngx_uint_t offset) | |
3402 { | |
3403 r->upstream->headers_in.transfer_encoding = h; | |
3404 | |
3405 if (ngx_strlcasestrn(h->value.data, h->value.data + h->value.len, | |
3406 (u_char *) "chunked", 7 - 1) | |
3407 != NULL) | |
3408 { | |
3409 r->upstream->headers_in.chunked = 1; | |
3410 } | |
3411 | |
3412 return NGX_OK; | |
3413 } | |
3414 | |
3415 | |
3416 static ngx_int_t | |
3324 ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, | 3417 ngx_http_upstream_copy_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, |
3325 ngx_uint_t offset) | 3418 ngx_uint_t offset) |
3326 { | 3419 { |
3327 ngx_table_elt_t *ho, **ph; | 3420 ngx_table_elt_t *ho, **ph; |
3328 | 3421 |
3420 r->headers_out.charset.len = last - p; | 3513 r->headers_out.charset.len = last - p; |
3421 r->headers_out.charset.data = p; | 3514 r->headers_out.charset.data = p; |
3422 | 3515 |
3423 return NGX_OK; | 3516 return NGX_OK; |
3424 } | 3517 } |
3425 | |
3426 return NGX_OK; | |
3427 } | |
3428 | |
3429 | |
3430 static ngx_int_t | |
3431 ngx_http_upstream_copy_content_length(ngx_http_request_t *r, ngx_table_elt_t *h, | |
3432 ngx_uint_t offset) | |
3433 { | |
3434 ngx_table_elt_t *ho; | |
3435 | |
3436 ho = ngx_list_push(&r->headers_out.headers); | |
3437 if (ho == NULL) { | |
3438 return NGX_ERROR; | |
3439 } | |
3440 | |
3441 *ho = *h; | |
3442 | |
3443 r->headers_out.content_length = ho; | |
3444 r->headers_out.content_length_n = ngx_atoof(h->value.data, h->value.len); | |
3445 | 3518 |
3446 return NGX_OK; | 3519 return NGX_OK; |
3447 } | 3520 } |
3448 | 3521 |
3449 | 3522 |