comparison src/http/ngx_http_upstream.c @ 2268:33556140681a

*) ngx_http_upstream_test_next() *) add proxy_next_upstream http_502 and http_504 *) fix http_503
author Igor Sysoev <igor@sysoev.ru>
date Tue, 30 Sep 2008 15:39:02 +0000
parents 920be89a3d2d
children c77f4710595c
comparison
equal deleted inserted replaced
2267:920be89a3d2d 2268:33556140681a
20 ngx_http_upstream_t *u); 20 ngx_http_upstream_t *u);
21 static void ngx_http_upstream_send_request(ngx_http_request_t *r, 21 static void ngx_http_upstream_send_request(ngx_http_request_t *r,
22 ngx_http_upstream_t *u); 22 ngx_http_upstream_t *u);
23 static void ngx_http_upstream_send_request_handler(ngx_event_t *wev); 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); 24 static void ngx_http_upstream_process_header(ngx_event_t *rev);
25 static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
26 ngx_http_upstream_t *u);
25 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, 27 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
26 ngx_http_upstream_t *u); 28 ngx_http_upstream_t *u);
27 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c); 29 static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
28 static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev); 30 static void ngx_http_upstream_process_body_in_memory(ngx_event_t *rev);
29 static void ngx_http_upstream_send_response(ngx_http_request_t *r, 31 static void ngx_http_upstream_send_response(ngx_http_request_t *r,
282 284
283 { ngx_null_string, NULL, NULL, 0, 0, 0 } 285 { ngx_null_string, NULL, NULL, 0, 0, 0 }
284 }; 286 };
285 287
286 288
289 static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
290 { 500, NGX_HTTP_UPSTREAM_FT_HTTP_500 },
291 { 502, NGX_HTTP_UPSTREAM_FT_HTTP_502 },
292 { 503, NGX_HTTP_UPSTREAM_FT_HTTP_503 },
293 { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
294 { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
295 { 0, 0 }
296 };
297
287 void 298 void
288 ngx_http_upstream_init(ngx_http_request_t *r) 299 ngx_http_upstream_init(ngx_http_request_t *r)
289 { 300 {
290 ngx_str_t *host; 301 ngx_str_t *host;
291 ngx_uint_t i; 302 ngx_uint_t i;
1172 return; 1183 return;
1173 } 1184 }
1174 1185
1175 /* rc == NGX_OK */ 1186 /* rc == NGX_OK */
1176 1187
1177 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST
1178 && r->subrequest_in_memory)
1179 {
1180 u->buffer.last = u->buffer.pos;
1181 }
1182
1183 if (u->headers_in.status_n == NGX_HTTP_INTERNAL_SERVER_ERROR) {
1184
1185 if (u->peer.tries > 1
1186 && (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500))
1187 {
1188 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500);
1189 return;
1190 }
1191
1192 #if (NGX_HTTP_CACHE)
1193
1194 if (u->peer.tries == 0
1195 && u->stale
1196 && (u->conf->use_stale & NGX_HTTP_UPSTREAM_FT_HTTP_500))
1197 {
1198 ngx_http_upstream_finalize_request(r, u,
1199 ngx_http_send_cached_response(r));
1200 return;
1201 }
1202
1203 #endif
1204 }
1205
1206 if (u->headers_in.status_n == NGX_HTTP_NOT_FOUND) {
1207
1208 if (u->peer.tries > 1
1209 && u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_404)
1210 {
1211 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_404);
1212 return;
1213 }
1214
1215 if (u->conf->intercept_404) {
1216 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1217 return;
1218 }
1219 }
1220
1221
1222 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) { 1188 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
1189
1190 if (r->subrequest_in_memory) {
1191 u->buffer.last = u->buffer.pos;
1192 }
1193
1194 if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
1195 return;
1196 }
1223 1197
1224 if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) { 1198 if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
1225 return; 1199 return;
1226 } 1200 }
1227 } 1201 }
1374 } 1348 }
1375 1349
1376 rev->handler = ngx_http_upstream_process_body_in_memory; 1350 rev->handler = ngx_http_upstream_process_body_in_memory;
1377 1351
1378 ngx_http_upstream_process_body_in_memory(rev); 1352 ngx_http_upstream_process_body_in_memory(rev);
1353 }
1354
1355
1356 static ngx_int_t
1357 ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
1358 {
1359 ngx_uint_t status;
1360 ngx_http_upstream_next_t *un;
1361
1362 if (!(u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_STATUS)) {
1363 return NGX_DECLINED;
1364 }
1365
1366 status = u->headers_in.status_n;
1367
1368 for (un = ngx_http_upstream_next_errors; un->status; un++) {
1369
1370 if (status != un->status) {
1371 continue;
1372 }
1373
1374 if (u->peer.tries > 1 && (u->conf->next_upstream & un->mask)) {
1375 ngx_http_upstream_next(r, u, un->mask);
1376 return NGX_OK;
1377 }
1378
1379 if (status == NGX_HTTP_NOT_FOUND && u->conf->intercept_404) {
1380 ngx_http_upstream_finalize_request(r, u, NGX_HTTP_NOT_FOUND);
1381 return NGX_OK;
1382 }
1383
1384 #if (NGX_HTTP_CACHE)
1385
1386 if (u->peer.tries == 0 && u->stale && (u->conf->use_stale & un->mask)) {
1387 ngx_http_upstream_finalize_request(r, u,
1388 ngx_http_send_cached_response(r));
1389 return NGX_OK;
1390 }
1391
1392 #endif
1393 }
1394
1395 return NGX_DECLINED;
1379 } 1396 }
1380 1397
1381 1398
1382 static ngx_int_t 1399 static ngx_int_t
1383 ngx_http_upstream_intercept_errors(ngx_http_request_t *r, 1400 ngx_http_upstream_intercept_errors(ngx_http_request_t *r,