20
31
ngx_http_upstream_t *u);
21
32
static void ngx_http_upstream_send_request(ngx_http_request_t *r,
22
33
ngx_http_upstream_t *u);
23
static void ngx_http_upstream_send_request_handler(ngx_event_t *wev);
24
static void ngx_http_upstream_process_header(ngx_event_t *rev);
34
static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
35
ngx_http_upstream_t *u);
36
static void ngx_http_upstream_process_header(ngx_http_request_t *r,
37
ngx_http_upstream_t *u);
38
static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
39
ngx_http_upstream_t *u);
40
static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
41
ngx_http_upstream_t *u);
25
42
static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
26
static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev);
43
static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
44
ngx_http_upstream_t *u);
45
static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
46
ngx_http_upstream_t *u);
27
47
static void ngx_http_upstream_send_response(ngx_http_request_t *r,
28
48
ngx_http_upstream_t *u);
49
static void ngx_http_upstream_upgrade(ngx_http_request_t *r,
50
ngx_http_upstream_t *u);
51
static void ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r);
52
static void ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r);
53
static void ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
54
ngx_http_upstream_t *u);
55
static void ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
56
ngx_http_upstream_t *u);
57
static void ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
58
ngx_uint_t from_upstream, ngx_uint_t do_write);
30
60
ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r);
31
static void ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev);
62
ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
63
ngx_http_upstream_t *u);
65
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
32
67
static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
33
68
static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
35
70
static void ngx_http_upstream_process_downstream(ngx_http_request_t *r);
36
static void ngx_http_upstream_process_body(ngx_event_t *ev);
71
static void ngx_http_upstream_process_upstream(ngx_http_request_t *r,
72
ngx_http_upstream_t *u);
73
static void ngx_http_upstream_process_request(ngx_http_request_t *r);
37
74
static void ngx_http_upstream_store(ngx_http_request_t *r,
38
75
ngx_http_upstream_t *u);
39
static void ngx_http_upstream_dummy_handler(ngx_event_t *wev);
76
static void ngx_http_upstream_dummy_handler(ngx_http_request_t *r,
77
ngx_http_upstream_t *u);
40
78
static void ngx_http_upstream_next(ngx_http_request_t *r,
41
79
ngx_http_upstream_t *u, ngx_uint_t ft_type);
42
80
static void ngx_http_upstream_cleanup(void *data);
46
84
static ngx_int_t ngx_http_upstream_process_header_line(ngx_http_request_t *r,
47
85
ngx_table_elt_t *h, ngx_uint_t offset);
86
static ngx_int_t ngx_http_upstream_process_content_length(ngx_http_request_t *r,
87
ngx_table_elt_t *h, ngx_uint_t offset);
88
static ngx_int_t ngx_http_upstream_process_set_cookie(ngx_http_request_t *r,
89
ngx_table_elt_t *h, ngx_uint_t offset);
49
ngx_http_upstream_process_multi_header_lines(ngx_http_request_t *r,
91
ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
50
92
ngx_table_elt_t *h, ngx_uint_t offset);
51
93
static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r,
52
94
ngx_table_elt_t *h, ngx_uint_t offset);
95
static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r,
96
ngx_table_elt_t *h, ngx_uint_t offset);
97
static ngx_int_t ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
98
ngx_table_elt_t *h, ngx_uint_t offset);
53
99
static ngx_int_t ngx_http_upstream_process_limit_rate(ngx_http_request_t *r,
54
100
ngx_table_elt_t *h, ngx_uint_t offset);
55
101
static ngx_int_t ngx_http_upstream_process_buffering(ngx_http_request_t *r,
56
102
ngx_table_elt_t *h, ngx_uint_t offset);
57
103
static ngx_int_t ngx_http_upstream_process_charset(ngx_http_request_t *r,
58
104
ngx_table_elt_t *h, ngx_uint_t offset);
105
static ngx_int_t ngx_http_upstream_process_connection(ngx_http_request_t *r,
106
ngx_table_elt_t *h, ngx_uint_t offset);
108
ngx_http_upstream_process_transfer_encoding(ngx_http_request_t *r,
109
ngx_table_elt_t *h, ngx_uint_t offset);
59
110
static ngx_int_t ngx_http_upstream_copy_header_line(ngx_http_request_t *r,
60
111
ngx_table_elt_t *h, ngx_uint_t offset);
146
212
ngx_http_upstream_rewrite_refresh, 0, 0 },
148
214
{ ngx_string("Set-Cookie"),
149
ngx_http_upstream_ignore_header_line, 0,
150
ngx_http_upstream_copy_header_line, 0, 1 },
215
ngx_http_upstream_process_set_cookie, 0,
216
ngx_http_upstream_rewrite_set_cookie, 0, 1 },
152
218
{ ngx_string("Content-Disposition"),
153
219
ngx_http_upstream_ignore_header_line, 0,
154
220
ngx_http_upstream_copy_header_line, 0, 1 },
156
222
{ ngx_string("Cache-Control"),
157
ngx_http_upstream_process_multi_header_lines,
158
offsetof(ngx_http_upstream_headers_in_t, cache_control),
223
ngx_http_upstream_process_cache_control, 0,
159
224
ngx_http_upstream_copy_multi_header_lines,
160
225
offsetof(ngx_http_headers_out_t, cache_control), 1 },
162
227
{ ngx_string("Expires"),
163
ngx_http_upstream_process_header_line,
164
offsetof(ngx_http_upstream_headers_in_t, expires),
228
ngx_http_upstream_process_expires, 0,
165
229
ngx_http_upstream_copy_header_line,
166
230
offsetof(ngx_http_headers_out_t, expires), 1 },
168
232
{ ngx_string("Accept-Ranges"),
169
233
ngx_http_upstream_process_header_line,
170
234
offsetof(ngx_http_upstream_headers_in_t, accept_ranges),
171
ngx_http_upstream_copy_header_line,
235
ngx_http_upstream_copy_allow_ranges,
172
236
offsetof(ngx_http_headers_out_t, accept_ranges), 1 },
174
238
{ ngx_string("Connection"),
175
ngx_http_upstream_ignore_header_line, 0,
239
ngx_http_upstream_process_connection, 0,
176
240
ngx_http_upstream_ignore_header_line, 0, 0 },
178
242
{ ngx_string("Keep-Alive"),
184
248
ngx_http_upstream_copy_header_line, 0, 0 },
186
250
{ ngx_string("X-Accel-Expires"),
187
ngx_http_upstream_process_header_line,
188
offsetof(ngx_http_upstream_headers_in_t, x_accel_expires),
251
ngx_http_upstream_process_accel_expires, 0,
189
252
ngx_http_upstream_copy_header_line, 0, 0 },
191
254
{ ngx_string("X-Accel-Redirect"),
192
255
ngx_http_upstream_process_header_line,
193
256
offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect),
194
ngx_http_upstream_ignore_header_line, 0, 0 },
257
ngx_http_upstream_copy_header_line, 0, 0 },
196
259
{ ngx_string("X-Accel-Limit-Rate"),
197
260
ngx_http_upstream_process_limit_rate, 0,
198
ngx_http_upstream_ignore_header_line, 0, 0 },
261
ngx_http_upstream_copy_header_line, 0, 0 },
200
263
{ ngx_string("X-Accel-Buffering"),
201
264
ngx_http_upstream_process_buffering, 0,
202
ngx_http_upstream_ignore_header_line, 0, 0 },
265
ngx_http_upstream_copy_header_line, 0, 0 },
204
267
{ ngx_string("X-Accel-Charset"),
205
268
ngx_http_upstream_process_charset, 0,
269
ngx_http_upstream_copy_header_line, 0, 0 },
271
{ ngx_string("Transfer-Encoding"),
272
ngx_http_upstream_process_transfer_encoding, 0,
206
273
ngx_http_upstream_ignore_header_line, 0, 0 },
208
275
#if (NGX_HTTP_GZIP)
270
337
static ngx_http_variable_t ngx_http_upstream_vars[] = {
272
339
{ ngx_string("upstream_addr"), NULL,
273
ngx_http_upstream_addr_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
340
ngx_http_upstream_addr_variable, 0,
341
NGX_HTTP_VAR_NOCACHEABLE, 0 },
275
343
{ ngx_string("upstream_status"), NULL,
276
ngx_http_upstream_status_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
344
ngx_http_upstream_status_variable, 0,
345
NGX_HTTP_VAR_NOCACHEABLE, 0 },
278
347
{ ngx_string("upstream_response_time"), NULL,
279
ngx_http_upstream_response_time_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
348
ngx_http_upstream_response_time_variable, 0,
349
NGX_HTTP_VAR_NOCACHEABLE, 0 },
351
{ ngx_string("upstream_response_length"), NULL,
352
ngx_http_upstream_response_length_variable, 0,
353
NGX_HTTP_VAR_NOCACHEABLE, 0 },
357
{ ngx_string("upstream_cache_status"), NULL,
358
ngx_http_upstream_cache_status, 0,
359
NGX_HTTP_VAR_NOCACHEABLE, 0 },
281
363
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
367
static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
368
{ 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 },
369
{ 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
370
{ 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
371
{ 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
372
{ 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
377
ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
378
{ ngx_string("GET"), NGX_HTTP_GET},
379
{ ngx_string("HEAD"), NGX_HTTP_HEAD },
380
{ ngx_string("POST"), NGX_HTTP_POST },
381
{ ngx_null_string, 0 }
385
ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = {
386
{ ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT },
387
{ ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES },
388
{ ngx_string("X-Accel-Limit-Rate"), NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE },
389
{ ngx_string("X-Accel-Buffering"), NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING },
390
{ ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET },
391
{ ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
392
{ ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
393
{ ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
394
{ ngx_null_string, 0 }
399
ngx_http_upstream_create(ngx_http_request_t *r)
401
ngx_http_upstream_t *u;
405
if (u && u->cleanup) {
407
ngx_http_upstream_cleanup(r);
410
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
417
u->peer.log = r->connection->log;
418
u->peer.log_error = NGX_ERROR_ERR;
420
u->peer.lock = &r->connection->lock;
427
u->headers_in.content_length_n = -1;
286
434
ngx_http_upstream_init(ngx_http_request_t *r)
291
ngx_resolver_ctx_t *ctx, temp;
292
ngx_http_cleanup_t *cln;
293
ngx_http_upstream_t *u;
294
ngx_http_core_loc_conf_t *clcf;
295
ngx_http_upstream_srv_conf_t *uscf, **uscfp;
296
ngx_http_upstream_main_conf_t *umcf;
298
438
c = r->connection;
300
440
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
301
441
"http init upstream, client timer: %d", c->read->timer_set);
444
if (r->spdy_stream) {
445
ngx_http_upstream_init_request(r);
303
450
if (c->read->timer_set) {
304
451
ngx_del_timer(c->read);
309
if (!r->post_action && !u->conf->ignore_client_abort) {
310
r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;
311
r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
314
454
if (ngx_event_flags & NGX_USE_CLEAR_EVENT) {
316
456
if (!c->write->active) {
680
ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
689
if (!(r->method & u->conf->cache_methods)) {
693
if (r->method & NGX_HTTP_HEAD) {
694
u->method = ngx_http_core_get_method;
697
if (ngx_http_file_cache_new(r) != NGX_OK) {
701
if (u->create_key(r) != NGX_OK) {
707
ngx_http_file_cache_create_key(r);
709
if (r->cache->header_start + 256 >= u->conf->buffer_size) {
710
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
711
"%V_buffer_size %uz is not enough for cache key, "
712
"it should increased at least to %uz",
713
&u->conf->module, u->conf->buffer_size,
714
ngx_align(r->cache->header_start + 256, 1024));
722
switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
728
u->cache_status = NGX_HTTP_CACHE_BYPASS;
731
default: /* NGX_OK */
737
c->min_uses = u->conf->cache_min_uses;
738
c->body_start = u->conf->buffer_size;
739
c->file_cache = u->conf->cache->data;
741
c->lock = u->conf->cache_lock;
742
c->lock_timeout = u->conf->cache_lock_timeout;
744
u->cache_status = NGX_HTTP_CACHE_MISS;
747
rc = ngx_http_file_cache_open(r);
749
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
750
"http upstream cache: %i", rc);
754
case NGX_HTTP_CACHE_UPDATING:
756
if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) {
757
u->cache_status = rc;
761
rc = NGX_HTTP_CACHE_STALE;
767
u->cache_status = NGX_HTTP_CACHE_HIT;
774
rc = ngx_http_upstream_cache_send(r, u);
776
if (rc != NGX_HTTP_UPSTREAM_INVALID_HEADER) {
782
case NGX_HTTP_CACHE_STALE:
785
u->buffer.start = NULL;
786
u->cache_status = NGX_HTTP_CACHE_EXPIRED;
792
if ((size_t) (u->buffer.end - u->buffer.start) < u->conf->buffer_size) {
793
u->buffer.start = NULL;
796
u->buffer.pos = u->buffer.start + c->header_start;
797
u->buffer.last = u->buffer.pos;
802
case NGX_HTTP_CACHE_SCARCE:
818
/* cached NGX_HTTP_BAD_GATEWAY, NGX_HTTP_GATEWAY_TIME_OUT, etc. */
820
u->cache_status = NGX_HTTP_CACHE_HIT;
832
ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
840
if (c->header_start == c->body_start) {
841
r->http_version = NGX_HTTP_VERSION_9;
842
return ngx_http_cache_send(r);
845
/* TODO: cache stack */
848
u->buffer.pos += c->header_start;
850
ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
851
u->headers_in.content_length_n = -1;
853
if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
854
sizeof(ngx_table_elt_t))
860
rc = u->process_header(r);
864
if (ngx_http_upstream_process_headers(r, u) != NGX_OK) {
868
return ngx_http_cache_send(r);
871
if (rc == NGX_ERROR) {
875
/* rc == NGX_HTTP_UPSTREAM_INVALID_HEADER */
877
/* TODO: delete file */
448
886
ngx_http_upstream_resolve_handler(ngx_resolver_ctx_t *ctx)
450
889
ngx_http_request_t *r;
890
ngx_http_upstream_t *u;
451
891
ngx_http_upstream_resolved_t *ur;
455
r->upstream->resolved->ctx = NULL;
457
899
if (ctx->state) {
458
900
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1096
u->buffer.pos += u->cache->ctx.header_size;
1586
#if (NGX_HTTP_CACHE)
1589
u->buffer.pos += r->cache->header_start;
1097
1590
u->buffer.last = u->buffer.pos;
1102
n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
1104
if (n == NGX_AGAIN) {
1106
ngx_add_timer(rev, u->read_timeout);
1109
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
1110
ngx_http_upstream_finalize_request(r, u,
1111
NGX_HTTP_INTERNAL_SERVER_ERROR);
1119
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
1120
"upstream prematurely closed connection");
1123
if (n == NGX_ERROR || n == 0) {
1124
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1128
u->buffer.last += n;
1131
u->valid_header_in = 0;
1136
rc = u->process_header(r);
1138
if (rc == NGX_AGAIN) {
1140
ngx_add_timer(rev, u->read_timeout);
1143
if (u->buffer.pos == u->buffer.end) {
1144
ngx_log_error(NGX_LOG_ERR, rev->log, 0,
1145
"upstream sent too big header");
1147
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
1151
if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
1152
ngx_http_upstream_finalize_request(r, u,
1153
NGX_HTTP_INTERNAL_SERVER_ERROR);
1597
n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
1599
if (n == NGX_AGAIN) {
1601
ngx_add_timer(rev, u->read_timeout);
1604
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
1605
ngx_http_upstream_finalize_request(r, u,
1606
NGX_HTTP_INTERNAL_SERVER_ERROR);
1614
ngx_log_error(NGX_LOG_ERR, c->log, 0,
1615
"upstream prematurely closed connection");
1618
if (n == NGX_ERROR || n == 0) {
1619
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
1623
u->buffer.last += n;
1626
u->valid_header_in = 0;
1631
rc = u->process_header(r);
1633
if (rc == NGX_AGAIN) {
1635
if (u->buffer.last == u->buffer.end) {
1636
ngx_log_error(NGX_LOG_ERR, c->log, 0,
1637
"upstream sent too big header");
1639
ngx_http_upstream_next(r, u,
1640
NGX_HTTP_UPSTREAM_FT_INVALID_HEADER);
1160
1650
if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
1171
1661
/* rc == NGX_OK */
1173
if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST
1174
&& r->subrequest_in_memory)
1176
u->buffer.last = u->buffer.pos;
1179
if (u->headers_in.status_n == NGX_HTTP_INTERNAL_SERVER_ERROR) {
1181
if (u->peer.tries > 1
1182
&& (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500))
1184
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500);
1663
if (u->headers_in.status_n > NGX_HTTP_SPECIAL_RESPONSE) {
1665
if (r->subrequest_in_memory) {
1666
u->buffer.last = u->buffer.pos;
1669
if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
1673
if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
1678
if (ngx_http_upstream_process_headers(r, u) != NGX_OK) {
1682
if (!r->subrequest_in_memory) {
1683
ngx_http_upstream_send_response(r, u);
1687
/* subrequest content in memory */
1689
if (u->input_filter == NULL) {
1690
u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
1691
u->input_filter = ngx_http_upstream_non_buffered_filter;
1692
u->input_filter_ctx = r;
1695
if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
1696
ngx_http_upstream_finalize_request(r, u,
1697
NGX_HTTP_INTERNAL_SERVER_ERROR);
1701
n = u->buffer.last - u->buffer.pos;
1704
u->buffer.last -= n;
1706
u->state->response_length += n;
1708
if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
1709
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1713
if (u->length == 0) {
1714
ngx_http_upstream_finalize_request(r, u, 0);
1719
u->read_event_handler = ngx_http_upstream_process_body_in_memory;
1721
ngx_http_upstream_process_body_in_memory(r, u);
1726
ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
1729
ngx_http_upstream_next_t *un;
1731
status = u->headers_in.status_n;
1733
for (un = ngx_http_upstream_next_errors; un->status; un++) {
1735
if (status != un->status) {
1739
if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) {
1740
ngx_http_upstream_next(r, u, un->mask);
1188
1744
#if (NGX_HTTP_CACHE)
1190
if (u->peer.tries == 0
1192
&& (u->conf->use_stale & NGX_HTTP_UPSTREAM_FT_HTTP_500))
1746
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
1747
&& (u->conf->cache_use_stale & un->mask))
1194
ngx_http_upstream_finalize_request(r, u,
1195
ngx_http_send_cached_response(r));
1751
rc = u->reinit_request(r);
1754
u->cache_status = NGX_HTTP_CACHE_STALE;
1755
rc = ngx_http_upstream_cache_send(r, u);
1758
ngx_http_upstream_finalize_request(r, u, rc);
1202
if (u->headers_in.status_n == NGX_HTTP_NOT_FOUND) {
1204
if (u->peer.tries > 1
1205
&& u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_404)
1207
ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_404);
1211
if (u->conf->intercept_404) {
1212
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1218
if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST
1219
&& u->conf->intercept_errors)
1221
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1223
if (clcf->error_pages) {
1225
err_page = clcf->error_pages->elts;
1226
for (i = 0; i < clcf->error_pages->nelts; i++) {
1227
if (err_page[i].status == (ngx_int_t) u->headers_in.status_n) {
1229
if (u->headers_in.status_n == NGX_HTTP_UNAUTHORIZED) {
1231
r->headers_out.www_authenticate =
1232
ngx_list_push(&r->headers_out.headers);
1234
if (r->headers_out.www_authenticate == NULL) {
1235
ngx_http_upstream_finalize_request(r, u,
1236
NGX_HTTP_INTERNAL_SERVER_ERROR);
1240
*r->headers_out.www_authenticate =
1241
*u->headers_in.www_authenticate;
1765
return NGX_DECLINED;
1770
ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
1771
ngx_http_upstream_t *u)
1776
ngx_http_err_page_t *err_page;
1777
ngx_http_core_loc_conf_t *clcf;
1779
status = u->headers_in.status_n;
1781
if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
1782
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1786
if (!u->conf->intercept_errors) {
1787
return NGX_DECLINED;
1790
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1792
if (clcf->error_pages == NULL) {
1793
return NGX_DECLINED;
1796
err_page = clcf->error_pages->elts;
1797
for (i = 0; i < clcf->error_pages->nelts; i++) {
1799
if (err_page[i].status == status) {
1801
if (status == NGX_HTTP_UNAUTHORIZED
1802
&& u->headers_in.www_authenticate)
1804
h = ngx_list_push(&r->headers_out.headers);
1244
1807
ngx_http_upstream_finalize_request(r, u,
1245
u->headers_in.status_n);
1808
NGX_HTTP_INTERNAL_SERVER_ERROR);
1812
*h = *u->headers_in.www_authenticate;
1814
r->headers_out.www_authenticate = h;
1817
#if (NGX_HTTP_CACHE)
1822
valid = ngx_http_file_cache_valid(u->conf->cache_valid, status);
1825
r->cache->valid_sec = ngx_time() + valid;
1826
r->cache->error = status;
1829
ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
1832
ngx_http_upstream_finalize_request(r, u, status);
1838
return NGX_DECLINED;
1843
ngx_http_upstream_test_connect(ngx_connection_t *c)
1848
#if (NGX_HAVE_KQUEUE)
1850
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1851
if (c->write->pending_eof || c->read->pending_eof) {
1852
if (c->write->pending_eof) {
1853
err = c->write->kq_errno;
1856
err = c->read->kq_errno;
1859
c->log->action = "connecting to upstream";
1860
(void) ngx_connection_error(c, err,
1861
"kevent() reported that connect() failed");
1872
* BSDs and Linux return 0 and set a pending error in err
1873
* Solaris returns -1 and sets errno
1876
if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1883
c->log->action = "connecting to upstream";
1884
(void) ngx_connection_error(c, err, "connect() failed");
1894
ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
1896
ngx_str_t *uri, args;
1897
ngx_uint_t i, flags;
1898
ngx_list_part_t *part;
1900
ngx_http_upstream_header_t *hh;
1901
ngx_http_upstream_main_conf_t *umcf;
1252
1903
umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
1254
if (u->headers_in.x_accel_redirect) {
1905
if (u->headers_in.x_accel_redirect
1906
&& !(u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT))
1256
1908
ngx_http_upstream_finalize_request(r, u, NGX_DECLINED);
1258
1910
part = &u->headers_in.headers.part;
1356
2004
r->headers_out.status = u->headers_in.status_n;
1357
2005
r->headers_out.status_line = u->headers_in.status_line;
1359
u->headers_in.content_length_n = r->headers_out.content_length_n;
1361
if (r->headers_out.content_length_n != -1) {
1362
u->length = (size_t) r->headers_out.content_length_n;
1365
u->length = NGX_MAX_SIZE_T_VALUE;
1368
if (!r->subrequest_in_memory) {
1369
ngx_http_upstream_send_response(r, u);
1373
/* subrequest content in memory */
1375
if (u->input_filter == NULL) {
1376
u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
1377
u->input_filter = ngx_http_upstream_non_buffered_filter;
1378
u->input_filter_ctx = r;
1381
if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
1382
ngx_http_upstream_finalize_request(r, u,
1383
NGX_HTTP_INTERNAL_SERVER_ERROR);
1387
if (u->buffer.last - u->buffer.pos >= (ssize_t) u->length) {
1388
if (u->input_filter(u->input_filter_ctx, 0) == NGX_ERROR) {
1389
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
1393
ngx_http_upstream_finalize_request(r, u, 0);
1397
rev->handler = ngx_http_upstream_process_body_in_memory;
1399
ngx_http_upstream_process_body_in_memory(rev);
1404
ngx_http_upstream_test_connect(ngx_connection_t *c)
1409
#if (NGX_HAVE_KQUEUE)
1411
if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
1412
if (c->write->pending_eof) {
1413
c->log->action = "connecting to upstream";
1414
(void) ngx_connection_error(c, c->write->kq_errno,
1415
"kevent() reported that connect() failed");
1426
* BSDs and Linux return 0 and set a pending error in err
1427
* Solaris returns -1 and sets errno
1430
if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
1437
c->log->action = "connecting to upstream";
1438
(void) ngx_connection_error(c, err, "connect() failed");
2007
r->headers_out.content_length_n = u->headers_in.content_length_n;
2009
u->length = u->headers_in.content_length_n;
1448
ngx_http_upstream_process_body_in_memory(ngx_event_t *rev)
2016
ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
2017
ngx_http_upstream_t *u)
1453
ngx_connection_t *c;
1454
ngx_http_request_t *r;
1455
ngx_http_upstream_t *u;
2023
ngx_connection_t *c;
2025
c = u->peer.connection;
1461
2028
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1462
2029
"http upstream process body on memory");
1625
2211
/* TODO: preallocate event_pipe bufs, look "Content-Length" */
1629
if (u->cache && u->cache->ctx.file.fd != NGX_INVALID_FILE) {
1630
if (ngx_close_file(u->cache->ctx.file.fd) == NGX_FILE_ERROR) {
1631
ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno,
1632
ngx_close_file_n " \"%s\" failed",
1633
u->cache->ctx.file.name.data);
2213
#if (NGX_HTTP_CACHE)
2215
if (r->cache && r->cache->file.fd != NGX_INVALID_FILE) {
2216
ngx_pool_run_cleanup_file(r->pool, r->cache->file.fd);
2217
r->cache->file.fd = NGX_INVALID_FILE;
2220
switch (ngx_http_test_predicates(r, u->conf->no_cache)) {
2223
ngx_http_upstream_finalize_request(r, u, 0);
2230
default: /* NGX_OK */
2232
if (u->cache_status == NGX_HTTP_CACHE_BYPASS) {
2234
r->cache->min_uses = u->conf->cache_min_uses;
2235
r->cache->body_start = u->conf->buffer_size;
2236
r->cache->file_cache = u->conf->cache->data;
2238
if (ngx_http_file_cache_create(r) != NGX_OK) {
2239
ngx_http_upstream_finalize_request(r, u, 0);
1637
2247
if (u->cacheable) {
1638
header = (ngx_http_cache_header_t *) u->buffer->start;
1640
header->expires = u->cache->ctx.expires;
1641
header->last_modified = u->cache->ctx.last_modified;
1642
header->date = u->cache->ctx.date;
1643
header->length = r->headers_out.content_length_n;
1644
u->cache->ctx.length = r->headers_out.content_length_n;
1646
header->key_len = u->cache->ctx.key0.len;
1647
ngx_memcpy(&header->key, u->cache->ctx.key0.data, header->key_len);
1648
header->key[header->key_len] = LF;
2252
valid = r->cache->valid_sec;
2255
valid = ngx_http_file_cache_valid(u->conf->cache_valid,
2256
u->headers_in.status_n);
2258
r->cache->valid_sec = now + valid;
2263
r->cache->last_modified = r->headers_out.last_modified_time;
2264
r->cache->date = now;
2265
r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
2267
ngx_http_file_cache_set_header(r, u->buffer.start);
2271
r->headers_out.last_modified_time = -1;
2275
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
2276
"http cacheable: %d", u->cacheable);
2278
if (u->cacheable == 0 && r->cache) {
2279
ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
1745
2377
p->send_timeout = clcf->send_timeout;
1746
2378
p->send_lowat = clcf->send_lowat;
1748
u->peer.connection->read->handler = ngx_http_upstream_process_body;
2382
if (u->input_filter_init
2383
&& u->input_filter_init(p->input_ctx) != NGX_OK)
2385
ngx_http_upstream_finalize_request(r, u, 0);
2389
u->read_event_handler = ngx_http_upstream_process_upstream;
1749
2390
r->write_event_handler = ngx_http_upstream_process_downstream;
1751
ngx_http_upstream_process_body(u->peer.connection->read);
2392
ngx_http_upstream_process_upstream(r, u);
2397
ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
2400
ngx_connection_t *c;
2401
ngx_http_core_loc_conf_t *clcf;
2404
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2406
/* TODO: prevent upgrade if not requested or not possible */
2409
c->log->action = "proxying upgraded connection";
2411
u->read_event_handler = ngx_http_upstream_upgraded_read_upstream;
2412
u->write_event_handler = ngx_http_upstream_upgraded_write_upstream;
2413
r->read_event_handler = ngx_http_upstream_upgraded_read_downstream;
2414
r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;
2416
if (clcf->tcp_nodelay) {
2419
if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
2420
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
2422
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
2423
(const void *) &tcp_nodelay, sizeof(int)) == -1)
2425
ngx_connection_error(c, ngx_socket_errno,
2426
"setsockopt(TCP_NODELAY) failed");
2427
ngx_http_upstream_finalize_request(r, u, 0);
2431
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
2434
if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
2435
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0,
2438
if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY,
2439
(const void *) &tcp_nodelay, sizeof(int)) == -1)
2441
ngx_connection_error(u->peer.connection, ngx_socket_errno,
2442
"setsockopt(TCP_NODELAY) failed");
2443
ngx_http_upstream_finalize_request(r, u, 0);
2447
u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET;
2451
if (ngx_http_send_special(r, NGX_HTTP_FLUSH) == NGX_ERROR) {
2452
ngx_http_upstream_finalize_request(r, u, 0);
2456
if (u->peer.connection->read->ready
2457
|| u->buffer.pos != u->buffer.last)
2459
ngx_http_upstream_process_upgraded(r, 1, 1);
2463
|| r->header_in->pos != r->header_in->last)
2465
ngx_http_upstream_process_upgraded(r, 0, 1);
2471
ngx_http_upstream_upgraded_read_downstream(ngx_http_request_t *r)
2473
ngx_http_upstream_process_upgraded(r, 0, 0);
2478
ngx_http_upstream_upgraded_write_downstream(ngx_http_request_t *r)
2480
ngx_http_upstream_process_upgraded(r, 1, 1);
2485
ngx_http_upstream_upgraded_read_upstream(ngx_http_request_t *r,
2486
ngx_http_upstream_t *u)
2488
ngx_http_upstream_process_upgraded(r, 1, 0);
2493
ngx_http_upstream_upgraded_write_upstream(ngx_http_request_t *r,
2494
ngx_http_upstream_t *u)
2496
ngx_http_upstream_process_upgraded(r, 0, 1);
2501
ngx_http_upstream_process_upgraded(ngx_http_request_t *r,
2502
ngx_uint_t from_upstream, ngx_uint_t do_write)
2507
ngx_connection_t *c, *downstream, *upstream, *dst, *src;
2508
ngx_http_upstream_t *u;
2509
ngx_http_core_loc_conf_t *clcf;
2514
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
2515
"http upstream process upgraded, fu:%ui", from_upstream);
2518
upstream = u->peer.connection;
2520
if (downstream->write->timedout) {
2522
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2523
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
2527
if (upstream->read->timedout || upstream->write->timedout) {
2528
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2529
ngx_http_upstream_finalize_request(r, u, 0);
2533
if (from_upstream) {
2541
b = &u->from_client;
2543
if (r->header_in->last > r->header_in->pos) {
2549
if (b->start == NULL) {
2550
b->start = ngx_palloc(r->pool, u->conf->buffer_size);
2551
if (b->start == NULL) {
2552
ngx_http_upstream_finalize_request(r, u, 0);
2558
b->end = b->start + u->conf->buffer_size;
2560
b->tag = u->output.tag;
2568
size = b->last - b->pos;
2570
if (size && dst->write->ready) {
2572
n = dst->send(dst, b->pos, size);
2574
if (n == NGX_ERROR) {
2575
ngx_http_upstream_finalize_request(r, u, 0);
2582
if (b->pos == b->last) {
2590
size = b->end - b->last;
2592
if (size && src->read->ready) {
2594
n = src->recv(src, b->last, size);
2596
if (n == NGX_AGAIN || n == 0) {
2607
if (n == NGX_ERROR) {
2615
if ((upstream->read->eof && u->buffer.pos == u->buffer.last)
2616
|| (downstream->read->eof && u->from_client.pos == u->from_client.last)
2617
|| (downstream->read->eof && upstream->read->eof))
2619
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2620
"http upstream upgraded done");
2621
ngx_http_upstream_finalize_request(r, u, 0);
2625
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
2627
if (ngx_handle_write_event(upstream->write, u->conf->send_lowat)
2630
ngx_http_upstream_finalize_request(r, u, 0);
2634
if (upstream->write->active && !upstream->write->ready) {
2635
ngx_add_timer(upstream->write, u->conf->send_timeout);
2637
} else if (upstream->write->timer_set) {
2638
ngx_del_timer(upstream->write);
2641
if (ngx_handle_read_event(upstream->read, 0) != NGX_OK) {
2642
ngx_http_upstream_finalize_request(r, u, 0);
2646
if (upstream->read->active && !upstream->read->ready) {
2647
ngx_add_timer(upstream->read, u->conf->read_timeout);
2649
} else if (upstream->read->timer_set) {
2650
ngx_del_timer(upstream->read);
2653
if (ngx_handle_write_event(downstream->write, clcf->send_lowat)
2656
ngx_http_upstream_finalize_request(r, u, 0);
2660
if (ngx_handle_read_event(downstream->read, 0) != NGX_OK) {
2661
ngx_http_upstream_finalize_request(r, u, 0);
2665
if (downstream->write->active && !downstream->write->ready) {
2666
ngx_add_timer(downstream->write, clcf->send_timeout);
2668
} else if (downstream->write->timer_set) {
2669
ngx_del_timer(downstream->write);
1756
2675
ngx_http_upstream_process_non_buffered_downstream(ngx_http_request_t *r)
1758
ngx_http_upstream_process_non_buffered_body(r->connection->write);
1763
ngx_http_upstream_process_non_buffered_body(ngx_event_t *ev)
2678
ngx_connection_t *c;
2679
ngx_http_upstream_t *u;
2685
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2686
"http upstream process non buffered downstream");
2688
c->log->action = "sending to client";
2690
if (wev->timedout) {
2692
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2693
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_REQUEST_TIME_OUT);
2697
ngx_http_upstream_process_non_buffered_request(r, 1);
2702
ngx_http_upstream_process_non_buffered_upstream(ngx_http_request_t *r,
2703
ngx_http_upstream_t *u)
2705
ngx_connection_t *c;
2707
c = u->peer.connection;
2709
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2710
"http upstream process non buffered upstream");
2712
c->log->action = "reading upstream";
2714
if (c->read->timedout) {
2715
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2716
ngx_http_upstream_finalize_request(r, u, 0);
2720
ngx_http_upstream_process_non_buffered_request(r, 0);
2725
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
2726
ngx_uint_t do_write)
1769
ngx_uint_t do_write;
1770
ngx_connection_t *c, *downstream, *upstream;
1771
ngx_http_request_t *r;
2732
ngx_connection_t *downstream, *upstream;
1772
2733
ngx_http_upstream_t *u;
1773
2734
ngx_http_core_loc_conf_t *clcf;
1777
2736
u = r->upstream;
1780
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1781
"http upstream process non buffered downstream");
1782
c->log->action = "sending to client";
1785
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1786
"http upstream process non buffered upstream");
1787
c->log->action = "reading upstream";
1793
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
1796
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
1799
ngx_http_upstream_finalize_request(r, u, 0);
1803
2737
downstream = r->connection;
1804
2738
upstream = u->peer.connection;
1806
2740
b = &u->buffer;
1808
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1810
do_write = ev->write || u->length == 0;
2742
do_write = do_write || u->length == 0;
1956
2884
ngx_http_upstream_process_downstream(ngx_http_request_t *r)
1958
ngx_http_upstream_process_body(r->connection->write);
1963
ngx_http_upstream_process_body(ngx_event_t *ev)
1965
ngx_temp_file_t *tf;
2887
ngx_connection_t *c;
1966
2888
ngx_event_pipe_t *p;
1967
ngx_connection_t *c, *downstream;
1968
ngx_http_log_ctx_t *ctx;
1969
ngx_http_request_t *r;
1970
2889
ngx_http_upstream_t *u;
1974
2892
u = r->upstream;
1975
downstream = r->connection;
1978
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1979
"http upstream process downstream");
1980
c->log->action = "sending to client";
1983
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
1984
"http upstream process upstream");
1985
c->log->action = "reading upstream";
1988
ctx->current_request = r;
2001
ngx_add_timer(ev, p->send_timeout);
2003
if (ngx_handle_write_event(ev, p->send_lowat) == NGX_ERROR)
2005
ngx_http_upstream_finalize_request(r, u, 0);
2012
if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
2014
if (downstream->destroyed) {
2896
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2897
"http upstream process downstream");
2899
c->log->action = "sending to client";
2901
if (wev->timedout) {
2909
ngx_add_timer(wev, p->send_timeout);
2911
if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
2018
2912
ngx_http_upstream_finalize_request(r, u, 0);
2023
p->downstream_error = 1;
2025
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2918
if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
2919
ngx_http_upstream_finalize_request(r, u, 0);
2029
p->upstream_error = 1;
2030
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2924
p->downstream_error = 1;
2926
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
2034
if (ev->write && ev->delayed) {
2035
2933
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2036
2934
"http downstream delayed");
2038
if (ngx_handle_write_event(ev, p->send_lowat) == NGX_ERROR) {
2045
if (ngx_event_pipe(p, ev->write) == NGX_ABORT) {
2047
if (downstream->destroyed) {
2051
ngx_http_upstream_finalize_request(r, u, 0);
2936
if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
2937
ngx_http_upstream_finalize_request(r, u, 0);
2943
if (ngx_event_pipe(p, 1) == NGX_ABORT) {
2944
ngx_http_upstream_finalize_request(r, u, 0);
2949
ngx_http_upstream_process_request(r);
2954
ngx_http_upstream_process_upstream(ngx_http_request_t *r,
2955
ngx_http_upstream_t *u)
2957
ngx_connection_t *c;
2959
c = u->peer.connection;
2961
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
2962
"http upstream process upstream");
2964
c->log->action = "reading upstream";
2966
if (c->read->timedout) {
2967
u->pipe->upstream_error = 1;
2968
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
2971
if (ngx_event_pipe(u->pipe, 0) == NGX_ABORT) {
2972
ngx_http_upstream_finalize_request(r, u, 0);
2977
ngx_http_upstream_process_request(r);
2982
ngx_http_upstream_process_request(ngx_http_request_t *r)
2984
ngx_temp_file_t *tf;
2985
ngx_event_pipe_t *p;
2986
ngx_http_upstream_t *u;
2056
2991
if (u->peer.connection) {
2058
2993
if (u->store) {
2060
tf = u->pipe->temp_file;
2063
&& u->headers_in.status_n == NGX_HTTP_OK
2064
&& (u->headers_in.content_length_n == -1
2065
|| (u->headers_in.content_length_n == tf->offset)))
2067
ngx_http_upstream_store(r, u);
2069
} else if ((p->upstream_error
2071
&& u->headers_in.status_n != NGX_HTTP_OK))
2072
&& tf->file.fd != NGX_INVALID_FILE)
2074
if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
2076
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
2077
ngx_delete_file_n " \"%s\" failed",
2078
u->pipe->temp_file->file.name.data);
2995
if (p->upstream_eof || p->upstream_done) {
2997
tf = u->pipe->temp_file;
2999
if (u->headers_in.status_n == NGX_HTTP_OK
3000
&& (u->headers_in.content_length_n == -1
3001
|| (u->headers_in.content_length_n == tf->offset)))
3003
ngx_http_upstream_store(r, u);
2083
#if (NGX_HTTP_FILE_CACHE)
2085
if (p->upstream_done && u->cacheable) {
2086
if (ngx_http_cache_update(r) == NGX_ERROR) {
2087
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
2088
ngx_http_upstream_finalize_request(r, u, 0);
2092
} else if (p->upstream_eof && u->cacheable) {
2094
/* TODO: check length & update cache */
2096
if (ngx_http_cache_update(r) == NGX_ERROR) {
2097
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
2098
ngx_http_upstream_finalize_request(r, u, 0);
3009
#if (NGX_HTTP_CACHE)
3013
if (p->upstream_done) {
3014
ngx_http_file_cache_update(r, u->pipe->temp_file);
3016
} else if (p->upstream_eof) {
3018
tf = u->pipe->temp_file;
3020
if (u->headers_in.content_length_n == -1
3021
|| u->headers_in.content_length_n
3022
== tf->offset - (off_t) r->cache->body_start)
3024
ngx_http_file_cache_update(r, tf);
3027
ngx_http_file_cache_free(r->cache, tf);
3030
} else if (p->upstream_error) {
3031
ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
2105
3037
if (p->upstream_done || p->upstream_eof || p->upstream_error) {
2106
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
3038
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2107
3039
"http upstream exit: %p", p->out);
2109
3041
ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
2383
3343
"close http upstream connection: %d",
2384
3344
u->peer.connection->fd);
3346
if (u->peer.connection->pool) {
3347
ngx_destroy_pool(u->peer.connection->pool);
2386
3350
ngx_close_connection(u->peer.connection);
2389
3353
u->peer.connection = NULL;
2391
if (u->header_sent && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
2396
3355
if (u->pipe && u->pipe->temp_file) {
2397
3356
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2398
3357
"http upstream temp fd: %d",
2399
3358
u->pipe->temp_file->file.fd);
2404
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
2405
"http upstream cache fd: %d",
2406
u->cache->ctx.file.fd);
3361
if (u->store && u->pipe && u->pipe->temp_file
3362
&& u->pipe->temp_file->file.fd != NGX_INVALID_FILE)
3364
if (ngx_delete_file(u->pipe->temp_file->file.name.data)
3367
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
3368
ngx_delete_file_n " \"%s\" failed",
3369
u->pipe->temp_file->file.name.data);
3373
#if (NGX_HTTP_CACHE)
3379
if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
3382
valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
3385
r->cache->valid_sec = ngx_time() + valid;
3386
r->cache->error = rc;
3391
ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
3397
&& rc != NGX_HTTP_REQUEST_TIME_OUT
3398
&& (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
2410
3403
if (rc == NGX_DECLINED) {
2414
3407
r->connection->log->action = "sending to client";
2418
if (!r->post_action) {
2419
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
3411
#if (NGX_HTTP_CACHE)
3416
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
2429
3419
ngx_http_finalize_request(r, rc);
4780
ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4787
ngx_http_complex_value_t cv;
4788
ngx_http_upstream_local_t **plocal, *local;
4789
ngx_http_compile_complex_value_t ccv;
4791
plocal = (ngx_http_upstream_local_t **) (p + cmd->offset);
4793
if (*plocal != NGX_CONF_UNSET_PTR) {
4794
return "is duplicate";
4797
value = cf->args->elts;
4799
if (ngx_strcmp(value[1].data, "off") == 0) {
4804
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
4807
ccv.value = &value[1];
4808
ccv.complex_value = &cv;
4810
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
4811
return NGX_CONF_ERROR;
4814
local = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_local_t));
4815
if (local == NULL) {
4816
return NGX_CONF_ERROR;
4822
local->value = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
4823
if (local->value == NULL) {
4824
return NGX_CONF_ERROR;
4832
local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t));
4833
if (local->addr == NULL) {
4834
return NGX_CONF_ERROR;
4837
rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len);
4841
local->addr->name = value[1];
4845
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4846
"invalid address \"%V\"", &value[1]);
4850
return NGX_CONF_ERROR;
4856
ngx_http_upstream_get_local(ngx_http_request_t *r,
4857
ngx_http_upstream_local_t *local)
4863
if (local == NULL) {
4867
if (local->value == NULL) {
4871
if (ngx_http_complex_value(r, local->value, &val) != NGX_OK) {
4879
addr = ngx_palloc(r->pool, sizeof(ngx_addr_t));
4884
rc = ngx_parse_addr(r->pool, addr, val.data, val.len);
4892
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
4893
"invalid local address \"%V\"", &val);
4903
ngx_http_upstream_param_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
4910
ngx_http_upstream_param_t *param;
4912
a = (ngx_array_t **) (p + cmd->offset);
4915
*a = ngx_array_create(cf->pool, 4, sizeof(ngx_http_upstream_param_t));
4917
return NGX_CONF_ERROR;
4921
param = ngx_array_push(*a);
4922
if (param == NULL) {
4923
return NGX_CONF_ERROR;
4926
value = cf->args->elts;
4928
param->key = value[1];
4929
param->value = value[2];
4930
param->skip_empty = 0;
4932
if (cf->args->nelts == 4) {
4933
if (ngx_strcmp(value[3].data, "if_not_empty") != 0) {
4934
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4935
"invalid parameter \"%V\"", &value[3]);
4936
return NGX_CONF_ERROR;
4939
param->skip_empty = 1;
3379
4947
ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf,
3380
4948
ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev,