Mercurial > hg > nginx
comparison src/http/modules/ngx_http_uwsgi_module.c @ 4358:94b995c7c614 stable-1.0
Merge of r4275, r4276, r4278, r4279:
Fixes for proxy_set_header, fastcgi/scgi/uwsgi_param inheritance:
*) Fixed proxy_set_header inheritance with proxy_cache (ticket #45).
Headers cleared with cache enabled (If-Modified-Since etc.) might be
cleared in unrelated servers/locations without proxy_cache enabled
if proxy_cache was used in some server/location.
Example config which triggered the problem:
proxy_set_header X-Test "test";
server { location /1 { proxy_cache name; proxy_pass ... } }
server { location /2 { proxy_pass ... } }
Another one:
server {
proxy_cache name;
location /1 { proxy_pass ... }
location /2 { proxy_cache off; proxy_pass ... }
}
In both cases If-Modified-Since header wasn't sent to backend in
location /2.
Fix is to not modify conf->headers_source, but instead merge user-supplied
headers from conf->headers_source and default headers (either cache or not)
into separate headers_merged array.
*) Fixed proxy_set_header inheritance with proxy_set_body.
*) Separate functions to merge fastcgi/scgi/uwsgi params.
No functional changes.
*) Fixed fastcgi/scgi/uwsgi_param inheritance. The following problems were
fixed:
1. Directive fastcgi_cache affected headers sent to backends in unrelated
servers / locations (see ticket #45).
2. If-Unmodified-Since, If-Match and If-Range headers were sent to
backends if fastcgi_cache was used.
3. Cache-related headers were sent to backends if there were no
fastcgi_param directives and fastcgi_cache was used at server level.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 14 Dec 2011 15:13:25 +0000 |
parents | 94049ec3eeda |
children | 2b2d51cdbd97 |
comparison
equal
deleted
inserted
replaced
4357:efd515ace6bb | 4358:94b995c7c614 |
---|---|
48 ngx_int_t rc); | 48 ngx_int_t rc); |
49 | 49 |
50 static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf); | 50 static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf); |
51 static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, | 51 static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, |
52 void *child); | 52 void *child); |
53 static ngx_int_t ngx_http_uwsgi_merge_params(ngx_conf_t *cf, | |
54 ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev); | |
53 | 55 |
54 static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, | 56 static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, |
55 void *conf); | 57 void *conf); |
56 static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, | 58 static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, |
57 void *conf); | 59 void *conf); |
1110 ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) | 1112 ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) |
1111 { | 1113 { |
1112 ngx_http_uwsgi_loc_conf_t *prev = parent; | 1114 ngx_http_uwsgi_loc_conf_t *prev = parent; |
1113 ngx_http_uwsgi_loc_conf_t *conf = child; | 1115 ngx_http_uwsgi_loc_conf_t *conf = child; |
1114 | 1116 |
1115 u_char *p; | |
1116 size_t size; | 1117 size_t size; |
1117 uintptr_t *code; | |
1118 ngx_uint_t i; | |
1119 ngx_array_t headers_names; | |
1120 ngx_keyval_t *src; | |
1121 ngx_hash_key_t *hk; | |
1122 ngx_hash_init_t hash; | 1118 ngx_hash_init_t hash; |
1123 ngx_http_core_loc_conf_t *clcf; | 1119 ngx_http_core_loc_conf_t *clcf; |
1124 ngx_http_script_compile_t sc; | |
1125 ngx_http_script_copy_code_t *copy; | |
1126 | 1120 |
1127 if (conf->upstream.store != 0) { | 1121 if (conf->upstream.store != 0) { |
1128 ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0); | 1122 ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0); |
1129 | 1123 |
1130 if (conf->upstream.store_lengths == NULL) { | 1124 if (conf->upstream.store_lengths == NULL) { |
1363 } | 1357 } |
1364 | 1358 |
1365 ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0); | 1359 ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0); |
1366 ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0); | 1360 ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0); |
1367 | 1361 |
1362 if (ngx_http_uwsgi_merge_params(cf, conf, prev) != NGX_OK) { | |
1363 return NGX_CONF_ERROR; | |
1364 } | |
1365 | |
1366 return NGX_CONF_OK; | |
1367 } | |
1368 | |
1369 | |
1370 static ngx_int_t | |
1371 ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf, | |
1372 ngx_http_uwsgi_loc_conf_t *prev) | |
1373 { | |
1374 u_char *p; | |
1375 size_t size; | |
1376 uintptr_t *code; | |
1377 ngx_uint_t i, nsrc; | |
1378 ngx_array_t headers_names; | |
1379 #if (NGX_HTTP_CACHE) | |
1380 ngx_array_t params_merged; | |
1381 #endif | |
1382 ngx_keyval_t *src; | |
1383 ngx_hash_key_t *hk; | |
1384 ngx_hash_init_t hash; | |
1385 ngx_http_script_compile_t sc; | |
1386 ngx_http_script_copy_code_t *copy; | |
1387 | |
1368 if (conf->params_source == NULL) { | 1388 if (conf->params_source == NULL) { |
1369 conf->flushes = prev->flushes; | |
1370 conf->params_len = prev->params_len; | |
1371 conf->params = prev->params; | |
1372 conf->params_source = prev->params_source; | 1389 conf->params_source = prev->params_source; |
1373 conf->headers_hash = prev->headers_hash; | 1390 |
1374 | 1391 if (prev->headers_hash.buckets |
1375 #if (NGX_HTTP_CACHE) | 1392 #if (NGX_HTTP_CACHE) |
1376 | 1393 && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)) |
1377 if (conf->params_source == NULL) { | |
1378 | |
1379 if ((conf->upstream.cache == NULL) | |
1380 == (prev->upstream.cache == NULL)) | |
1381 { | |
1382 return NGX_CONF_OK; | |
1383 } | |
1384 | |
1385 /* 6 is a number of ngx_http_uwsgi_cache_headers entries */ | |
1386 conf->params_source = ngx_array_create(cf->pool, 6, | |
1387 sizeof(ngx_keyval_t)); | |
1388 if (conf->params_source == NULL) { | |
1389 return NGX_CONF_ERROR; | |
1390 } | |
1391 } | |
1392 #else | |
1393 | |
1394 if (conf->params_source == NULL) { | |
1395 return NGX_CONF_OK; | |
1396 } | |
1397 | |
1398 #endif | 1394 #endif |
1395 ) | |
1396 { | |
1397 conf->flushes = prev->flushes; | |
1398 conf->params_len = prev->params_len; | |
1399 conf->params = prev->params; | |
1400 conf->headers_hash = prev->headers_hash; | |
1401 conf->header_params = prev->header_params; | |
1402 | |
1403 return NGX_OK; | |
1404 } | |
1405 } | |
1406 | |
1407 if (conf->params_source == NULL | |
1408 #if (NGX_HTTP_CACHE) | |
1409 && (conf->upstream.cache == NULL) | |
1410 #endif | |
1411 ) | |
1412 { | |
1413 conf->headers_hash.buckets = (void *) 1; | |
1414 return NGX_OK; | |
1399 } | 1415 } |
1400 | 1416 |
1401 conf->params_len = ngx_array_create(cf->pool, 64, 1); | 1417 conf->params_len = ngx_array_create(cf->pool, 64, 1); |
1402 if (conf->params_len == NULL) { | 1418 if (conf->params_len == NULL) { |
1403 return NGX_CONF_ERROR; | 1419 return NGX_ERROR; |
1404 } | 1420 } |
1405 | 1421 |
1406 conf->params = ngx_array_create(cf->pool, 512, 1); | 1422 conf->params = ngx_array_create(cf->pool, 512, 1); |
1407 if (conf->params == NULL) { | 1423 if (conf->params == NULL) { |
1408 return NGX_CONF_ERROR; | 1424 return NGX_ERROR; |
1409 } | 1425 } |
1410 | 1426 |
1411 if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) | 1427 if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) |
1412 != NGX_OK) | 1428 != NGX_OK) |
1413 { | 1429 { |
1414 return NGX_CONF_ERROR; | 1430 return NGX_ERROR; |
1415 } | 1431 } |
1416 | 1432 |
1417 src = conf->params_source->elts; | 1433 if (conf->params_source) { |
1434 src = conf->params_source->elts; | |
1435 nsrc = conf->params_source->nelts; | |
1436 | |
1437 } else { | |
1438 src = NULL; | |
1439 nsrc = 0; | |
1440 } | |
1418 | 1441 |
1419 #if (NGX_HTTP_CACHE) | 1442 #if (NGX_HTTP_CACHE) |
1420 | 1443 |
1421 if (conf->upstream.cache) { | 1444 if (conf->upstream.cache) { |
1422 ngx_keyval_t *h, *s; | 1445 ngx_keyval_t *h, *s; |
1423 | 1446 |
1424 for (h = ngx_http_uwsgi_cache_headers; h->key.len; h++) { | 1447 if (ngx_array_init(¶ms_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t)) |
1425 | 1448 != NGX_OK) |
1426 for (i = 0; i < conf->params_source->nelts; i++) { | 1449 { |
1450 return NGX_ERROR; | |
1451 } | |
1452 | |
1453 for (i = 0; i < nsrc; i++) { | |
1454 | |
1455 s = ngx_array_push(¶ms_merged); | |
1456 if (s == NULL) { | |
1457 return NGX_ERROR; | |
1458 } | |
1459 | |
1460 *s = src[i]; | |
1461 } | |
1462 | |
1463 h = ngx_http_uwsgi_cache_headers; | |
1464 | |
1465 while (h->key.len) { | |
1466 | |
1467 src = params_merged.elts; | |
1468 nsrc = params_merged.nelts; | |
1469 | |
1470 for (i = 0; i < nsrc; i++) { | |
1427 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { | 1471 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { |
1428 goto next; | 1472 goto next; |
1429 } | 1473 } |
1430 } | 1474 } |
1431 | 1475 |
1432 s = ngx_array_push(conf->params_source); | 1476 s = ngx_array_push(¶ms_merged); |
1433 if (s == NULL) { | 1477 if (s == NULL) { |
1434 return NGX_CONF_ERROR; | 1478 return NGX_ERROR; |
1435 } | 1479 } |
1436 | 1480 |
1437 *s = *h; | 1481 *s = *h; |
1438 | 1482 |
1439 src = conf->params_source->elts; | |
1440 | |
1441 next: | 1483 next: |
1442 | 1484 |
1443 h++; | 1485 h++; |
1444 } | 1486 } |
1487 | |
1488 src = params_merged.elts; | |
1489 nsrc = params_merged.nelts; | |
1445 } | 1490 } |
1446 | 1491 |
1447 #endif | 1492 #endif |
1448 | 1493 |
1449 for (i = 0; i < conf->params_source->nelts; i++) { | 1494 for (i = 0; i < nsrc; i++) { |
1450 | 1495 |
1451 if (src[i].key.len > sizeof("HTTP_") - 1 | 1496 if (src[i].key.len > sizeof("HTTP_") - 1 |
1452 && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) | 1497 && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) |
1453 { | 1498 { |
1454 hk = ngx_array_push(&headers_names); | 1499 hk = ngx_array_push(&headers_names); |
1455 if (hk == NULL) { | 1500 if (hk == NULL) { |
1456 return NGX_CONF_ERROR; | 1501 return NGX_ERROR; |
1457 } | 1502 } |
1458 | 1503 |
1459 hk->key.len = src[i].key.len - 5; | 1504 hk->key.len = src[i].key.len - 5; |
1460 hk->key.data = src[i].key.data + 5; | 1505 hk->key.data = src[i].key.data + 5; |
1461 hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len); | 1506 hk->key_hash = ngx_hash_key_lc(hk->key.data, hk->key.len); |
1467 } | 1512 } |
1468 | 1513 |
1469 copy = ngx_array_push_n(conf->params_len, | 1514 copy = ngx_array_push_n(conf->params_len, |
1470 sizeof(ngx_http_script_copy_code_t)); | 1515 sizeof(ngx_http_script_copy_code_t)); |
1471 if (copy == NULL) { | 1516 if (copy == NULL) { |
1472 return NGX_CONF_ERROR; | 1517 return NGX_ERROR; |
1473 } | 1518 } |
1474 | 1519 |
1475 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; | 1520 copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code; |
1476 copy->len = src[i].key.len; | 1521 copy->len = src[i].key.len; |
1477 | 1522 |
1480 + src[i].key.len + sizeof(uintptr_t) - 1) | 1525 + src[i].key.len + sizeof(uintptr_t) - 1) |
1481 & ~(sizeof(uintptr_t) - 1); | 1526 & ~(sizeof(uintptr_t) - 1); |
1482 | 1527 |
1483 copy = ngx_array_push_n(conf->params, size); | 1528 copy = ngx_array_push_n(conf->params, size); |
1484 if (copy == NULL) { | 1529 if (copy == NULL) { |
1485 return NGX_CONF_ERROR; | 1530 return NGX_ERROR; |
1486 } | 1531 } |
1487 | 1532 |
1488 copy->code = ngx_http_script_copy_code; | 1533 copy->code = ngx_http_script_copy_code; |
1489 copy->len = src[i].key.len; | 1534 copy->len = src[i].key.len; |
1490 | 1535 |
1499 sc.flushes = &conf->flushes; | 1544 sc.flushes = &conf->flushes; |
1500 sc.lengths = &conf->params_len; | 1545 sc.lengths = &conf->params_len; |
1501 sc.values = &conf->params; | 1546 sc.values = &conf->params; |
1502 | 1547 |
1503 if (ngx_http_script_compile(&sc) != NGX_OK) { | 1548 if (ngx_http_script_compile(&sc) != NGX_OK) { |
1504 return NGX_CONF_ERROR; | 1549 return NGX_ERROR; |
1505 } | 1550 } |
1506 | 1551 |
1507 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); | 1552 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
1508 if (code == NULL) { | 1553 if (code == NULL) { |
1509 return NGX_CONF_ERROR; | 1554 return NGX_ERROR; |
1510 } | 1555 } |
1511 | 1556 |
1512 *code = (uintptr_t) NULL; | 1557 *code = (uintptr_t) NULL; |
1513 | 1558 |
1514 | 1559 |
1515 code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); | 1560 code = ngx_array_push_n(conf->params, sizeof(uintptr_t)); |
1516 if (code == NULL) { | 1561 if (code == NULL) { |
1517 return NGX_CONF_ERROR; | 1562 return NGX_ERROR; |
1518 } | 1563 } |
1519 | 1564 |
1520 *code = (uintptr_t) NULL; | 1565 *code = (uintptr_t) NULL; |
1521 } | 1566 } |
1522 | 1567 |
1523 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); | 1568 code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t)); |
1524 if (code == NULL) { | 1569 if (code == NULL) { |
1525 return NGX_CONF_ERROR; | 1570 return NGX_ERROR; |
1526 } | 1571 } |
1527 | 1572 |
1528 *code = (uintptr_t) NULL; | 1573 *code = (uintptr_t) NULL; |
1529 | 1574 |
1530 conf->header_params = headers_names.nelts; | 1575 conf->header_params = headers_names.nelts; |
1535 hash.bucket_size = 64; | 1580 hash.bucket_size = 64; |
1536 hash.name = "uwsgi_params_hash"; | 1581 hash.name = "uwsgi_params_hash"; |
1537 hash.pool = cf->pool; | 1582 hash.pool = cf->pool; |
1538 hash.temp_pool = NULL; | 1583 hash.temp_pool = NULL; |
1539 | 1584 |
1540 if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK) | 1585 return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts); |
1541 { | |
1542 return NGX_CONF_ERROR; | |
1543 } | |
1544 | |
1545 return NGX_CONF_OK; | |
1546 } | 1586 } |
1547 | 1587 |
1548 | 1588 |
1549 static char * | 1589 static char * |
1550 ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1590 ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |