Klaus Demo nginx / 797c6ef
*) ngx_http_upstream_test_next() *) add proxy_next_upstream http_502 and http_504 *) fix http_503 Igor Sysoev 11 years ago
3 changed file(s) with 81 addition(s) and 49 deletion(s). Raw diff Collapse all Expand all
146146 { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
147147 { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
148148 { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
149 { ngx_string("http_502"), NGX_HTTP_UPSTREAM_FT_HTTP_502 },
149150 { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
151 { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
150152 { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
151153 { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
152154 { ngx_null_string, 0 }
2121 ngx_http_upstream_t *u);
2222 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev);
2323 static void ngx_http_upstream_process_header(ngx_event_t *rev);
24 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
25 ngx_http_upstream_t *u);
2426 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
2527 ngx_http_upstream_t *u);
2628 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
283285 };
284286
285287
288 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
289 { 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 },
290 { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
291 { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
292 { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
293 { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
294 { 0, 0 }
295 };
296
286297 void
287298 ngx_http_upstream_init(ngx_http_request_t *r)
288299 {
11731184
11741185 /* rc == NGX_OK */
11751186
1176 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST
1177 && r->subrequest_in_memory)
1178 {
1179 u->buffer.last = u->buffer.pos;
1180 }
1181
1182 if (u->headers_in.status_n == NGX_HTTP_INTERNAL_SERVER_ERROR) {
1183
1184 if (u->peer.tries > 1
1185 && (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500))
1186 {
1187 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500);
1188 return;
1189 }
1190
1191 #if (NGX_HTTP_CACHE)
1192
1193 if (u->peer.tries == 0
1194 && u->stale
1195 && (u->conf->use_stale & NGX_HTTP_UPSTREAM_FT_HTTP_500))
1196 {
1197 ngx_http_upstream_finalize_request(r, u,
1198 ngx_http_send_cached_response(r));
1199 return;
1200 }
1201
1202 #endif
1203 }
1204
1205 if (u->headers_in.status_n == NGX_HTTP_NOT_FOUND) {
1206
1207 if (u->peer.tries > 1
1208 && u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_404)
1209 {
1210 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_404);
1211 return;
1212 }
1213
1214 if (u->conf->intercept_404) {
1215 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1216 return;
1217 }
1218 }
1219
1220
12211187 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
1188
1189 if (r->subrequest_in_memory) {
1190 u->buffer.last = u->buffer.pos;
1191 }
1192
1193 if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
1194 return;
1195 }
12221196
12231197 if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
12241198 return;
13751349 rev->handler = ngx_http_upstream_process_body_in_memory;
13761350
13771351 ngx_http_upstream_process_body_in_memory(rev);
1352 }
1353
1354
1355 static ngx_int_t
1356 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
1357 {
1358 ngx_uint_t status;
1359 ngx_http_upstream_next_t *un;
1360
1361 if (!(u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_STATUS)) {
1362 return NGX_DECLINED;
1363 }
1364
1365 status = u->headers_in.status_n;
1366
1367 for (un = ngx_http_upstream_next_errors; un->status; un++) {
1368
1369 if (status != un->status) {
1370 continue;
1371 }
1372
1373 if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) {
1374 ngx_http_upstream_next(r, u, un->mask);
1375 return NGX_OK;
1376 }
1377
1378 if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
1379 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1380 return NGX_OK;
1381 }
1382
1383 #if (NGX_HTTP_CACHE)
1384
1385 if (u->peer.tries == 0 && u->stale && (u->conf->use_stale & un->mask)) {
1386 ngx_http_upstream_finalize_request(r, u,
1387 ngx_http_send_cached_response(r));
1388 return NGX_OK;
1389 }
1390
1391 #endif
1392 }
1393
1394 return NGX_DECLINED;
13781395 }
13791396
13801397
1919 #define NGX_HTTP_UPSTREAM_FT_TIMEOUT 0x00000004
2020 #define NGX_HTTP_UPSTREAM_FT_INVALID_HEADER 0x00000008
2121 #define NGX_HTTP_UPSTREAM_FT_HTTP_500 0x00000010
22 #define NGX_HTTP_UPSTREAM_FT_HTTP_503 0x00000020
23 #define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000040
24 #define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000080
25 #define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00000100
22 #define NGX_HTTP_UPSTREAM_FT_HTTP_502 0x00000020
23 #define NGX_HTTP_UPSTREAM_FT_HTTP_503 0x00000040
24 #define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080
25 #define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000100
26 #define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000200
27 #define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00000400
2628 #define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000
2729 #define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000
2830
31 #define NGX_HTTP_UPSTREAM_FT_STATUS (NGX_HTTP_UPSTREAM_FT_HTTP_500 \
32 |NGX_HTTP_UPSTREAM_FT_HTTP_502 \
33 |NGX_HTTP_UPSTREAM_FT_HTTP_503 \
34 |NGX_HTTP_UPSTREAM_FT_HTTP_504 \
35 |NGX_HTTP_UPSTREAM_FT_HTTP_404)
2936
3037 #define NGX_HTTP_UPSTREAM_INVALID_HEADER 40
3138
266273 };
267274
268275
276 typedef struct {
277 ngx_uint_t status;
278 ngx_uint_t mask;
279 } ngx_http_upstream_next_t;
280
281
269282 ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
270283 ngx_http_variable_value_t *v, uintptr_t data);
271284