comparison src/http/ngx_http_upstream.c @ 412:b246022ef454 NGINX_0_7_18

nginx 0.7.18 *) Change: the "underscores_in_headers" directive; now nginx does not allows underscores in a client request header line names. *) Feature: the ngx_http_secure_link_module. *) Feature: the "real_ip_header" directive supports any header. *) Feature: the "log_subrequest" directive. *) Feature: the $realpath_root variable. *) Feature: the "http_502" and "http_504" parameters of the "proxy_next_upstream" directive. *) Bugfix: the "http_503" parameter of the "proxy_next_upstream" or "fastcgi_next_upstream" directives did not work. *) Bugfix: nginx might send a "Transfer-Encoding: chunked" heaer line for HEAD requests. *) Bugfix: now accept threshold depends on worker_connections.
author Igor Sysoev <http://sysoev.ru>
date Mon, 13 Oct 2008 00:00:00 +0400
parents a8e3f1441eec
children b4f69f2ef02c
comparison
equal deleted inserted replaced
411:b453a4324c60 412:b246022ef454
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);
27 static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
28 ngx_http_upstream_t *u);
25 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);
26 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);
27 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,
28 ngx_http_upstream_t *u); 32 ngx_http_upstream_t *u);
29 static void 33 static void
280 284
281 { ngx_null_string, NULL, NULL, 0, 0, 0 } 285 { ngx_null_string, NULL, NULL, 0, 0, 0 }
282 }; 286 };
283 287
284 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
285 void 298 void
286 ngx_http_upstream_init(ngx_http_request_t *r) 299 ngx_http_upstream_init(ngx_http_request_t *r)
287 { 300 {
288 ngx_str_t *host; 301 ngx_str_t *host;
289 ngx_uint_t i; 302 ngx_uint_t i;
1045 ngx_list_part_t *part; 1058 ngx_list_part_t *part;
1046 ngx_table_elt_t *h; 1059 ngx_table_elt_t *h;
1047 ngx_connection_t *c; 1060 ngx_connection_t *c;
1048 ngx_http_request_t *r; 1061 ngx_http_request_t *r;
1049 ngx_http_upstream_t *u; 1062 ngx_http_upstream_t *u;
1050 ngx_http_err_page_t *err_page;
1051 ngx_http_core_loc_conf_t *clcf;
1052 ngx_http_upstream_header_t *hh; 1063 ngx_http_upstream_header_t *hh;
1053 ngx_http_upstream_main_conf_t *umcf; 1064 ngx_http_upstream_main_conf_t *umcf;
1054 1065
1055 c = rev->data; 1066 c = rev->data;
1056 r = c->data; 1067 r = c->data;
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 1188 if (u->headers_in.status_n >= NGX_HTTP_BAD_REQUEST) {
1178 && r->subrequest_in_memory) 1189
1179 { 1190 if (r->subrequest_in_memory) {
1180 u->buffer.last = u->buffer.pos; 1191 u->buffer.last = u->buffer.pos;
1181 } 1192 }
1182 1193
1183 if (u->headers_in.status_n == NGX_HTTP_INTERNAL_SERVER_ERROR) { 1194 if (ngx_http_upstream_test_next(r, u) == NGX_OK) {
1184 1195 return;
1185 if (u->peer.tries > 1 1196 }
1186 && (u->conf->next_upstream & NGX_HTTP_UPSTREAM_FT_HTTP_500)) 1197
1187 { 1198 if (ngx_http_upstream_intercept_errors(r, u) == NGX_OK) {
1188 ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_HTTP_500); 1199 return;
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
1223 && u->conf->intercept_errors)
1224 {
1225 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1226
1227 if (clcf->error_pages) {
1228
1229 err_page = clcf->error_pages->elts;
1230 for (i = 0; i < clcf->error_pages->nelts; i++) {
1231 if (err_page[i].status == (ngx_int_t) u->headers_in.status_n) {
1232
1233 if (u->headers_in.status_n == NGX_HTTP_UNAUTHORIZED) {
1234
1235 r->headers_out.www_authenticate =
1236 ngx_list_push(&r->headers_out.headers);
1237
1238 if (r->headers_out.www_authenticate == NULL) {
1239 ngx_http_upstream_finalize_request(r, u,
1240 NGX_HTTP_INTERNAL_SERVER_ERROR);
1241 return;
1242 }
1243
1244 *r->headers_out.www_authenticate =
1245 *u->headers_in.www_authenticate;
1246 }
1247
1248 ngx_http_upstream_finalize_request(r, u,
1249 u->headers_in.status_n);
1250 return;
1251 }
1252 }
1253 } 1200 }
1254 } 1201 }
1255 1202
1256 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); 1203 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
1257 1204
1401 } 1348 }
1402 1349
1403 rev->handler = ngx_http_upstream_process_body_in_memory; 1350 rev->handler = ngx_http_upstream_process_body_in_memory;
1404 1351
1405 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;
1396 }
1397
1398
1399 static ngx_int_t
1400 ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
1401 ngx_http_upstream_t *u)
1402 {
1403 ngx_int_t status;
1404 ngx_uint_t i;
1405 ngx_table_elt_t *h;
1406 ngx_http_err_page_t *err_page;
1407 ngx_http_core_loc_conf_t *clcf;
1408
1409 if (!u->conf->intercept_errors) {
1410 return NGX_DECLINED;
1411 }
1412
1413 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
1414
1415 if (clcf->error_pages == NULL) {
1416 return NGX_DECLINED;
1417 }
1418
1419 status = u->headers_in.status_n;
1420
1421 err_page = clcf->error_pages->elts;
1422 for (i = 0; i < clcf->error_pages->nelts; i++) {
1423
1424 if (err_page[i].status == status) {
1425
1426 if (status == NGX_HTTP_UNAUTHORIZED) {
1427
1428 h = ngx_list_push(&r->headers_out.headers);
1429
1430 if (h == NULL) {
1431 ngx_http_upstream_finalize_request(r, u,
1432 NGX_HTTP_INTERNAL_SERVER_ERROR);
1433 return NGX_OK;
1434 }
1435
1436 *h = *u->headers_in.www_authenticate;
1437
1438 r->headers_out.www_authenticate = h;
1439 }
1440
1441 ngx_http_upstream_finalize_request(r, u, status);
1442
1443 return NGX_OK;
1444 }
1445 }
1446
1447 return NGX_DECLINED;
1406 } 1448 }
1407 1449
1408 1450
1409 static ngx_int_t 1451 static ngx_int_t
1410 ngx_http_upstream_test_connect(ngx_connection_t *c) 1452 ngx_http_upstream_test_connect(ngx_connection_t *c)