comparison src/http/modules/ngx_http_uwsgi_module.c @ 3568:7cfbc51bac01

uwsgi cache
author Igor Sysoev <igor@sysoev.ru>
date Fri, 04 Jun 2010 12:55:01 +0000
parents 9bbfce117cfb
children 8b55806ceb97
comparison
equal deleted inserted replaced
3567:9bbfce117cfb 3568:7cfbc51bac01
22 ngx_hash_t headers_hash; 22 ngx_hash_t headers_hash;
23 ngx_uint_t header_params; 23 ngx_uint_t header_params;
24 24
25 ngx_array_t *uwsgi_lengths; 25 ngx_array_t *uwsgi_lengths;
26 ngx_array_t *uwsgi_values; 26 ngx_array_t *uwsgi_values;
27
28 #if (NGX_HTTP_CACHE)
29 ngx_http_complex_value_t cache_key;
30 #endif
27 31
28 ngx_str_t uwsgi_string; 32 ngx_str_t uwsgi_string;
29 33
30 ngx_uint_t modifier1; 34 ngx_uint_t modifier1;
31 ngx_uint_t modifier2; 35 ngx_uint_t modifier2;
63 static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, 67 static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
64 void *conf); 68 void *conf);
65 static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd, 69 static char *ngx_http_uwsgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
66 void *conf); 70 void *conf);
67 71
72 #if (NGX_HTTP_CACHE)
73 static ngx_int_t ngx_http_uwsgi_create_key(ngx_http_request_t *r);
74 static char *ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd,
75 void *conf);
76 static char *ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
77 void *conf);
78 #endif
79
68 80
69 static ngx_conf_num_bounds_t ngx_http_uwsgi_modifier_bounds = { 81 static ngx_conf_num_bounds_t ngx_http_uwsgi_modifier_bounds = {
70 ngx_conf_check_num_bounds, 0, 255 82 ngx_conf_check_num_bounds, 0, 255
71 }; 83 };
72 84
91 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL }, 103 { ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
92 { ngx_null_string, 0 } 104 { ngx_null_string, 0 }
93 }; 105 };
94 106
95 107
108 ngx_module_t ngx_http_uwsgi_module;
109
110
96 static ngx_command_t ngx_http_uwsgi_commands[] = { 111 static ngx_command_t ngx_http_uwsgi_commands[] = {
97 112
98 { ngx_string("uwsgi_pass"), 113 { ngx_string("uwsgi_pass"),
99 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1, 114 NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
100 ngx_http_uwsgi_pass, 115 ngx_http_uwsgi_pass,
204 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 219 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
205 ngx_conf_set_size_slot, 220 ngx_conf_set_size_slot,
206 NGX_HTTP_LOC_CONF_OFFSET, 221 NGX_HTTP_LOC_CONF_OFFSET,
207 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf), 222 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.busy_buffers_size_conf),
208 NULL }, 223 NULL },
224
225 #if (NGX_HTTP_CACHE)
226
227 { ngx_string("uwsgi_cache"),
228 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
229 ngx_http_uwsgi_cache,
230 NGX_HTTP_LOC_CONF_OFFSET,
231 0,
232 NULL },
233
234 { ngx_string("uwsgi_cache_key"),
235 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
236 ngx_http_uwsgi_cache_key,
237 NGX_HTTP_LOC_CONF_OFFSET,
238 0,
239 NULL },
240
241 { ngx_string("uwsgi_cache_path"),
242 NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
243 ngx_http_file_cache_set_slot,
244 0,
245 0,
246 &ngx_http_uwsgi_module },
247
248 { ngx_string("uwsgi_no_cache"),
249 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
250 ngx_http_no_cache_set_slot,
251 NGX_HTTP_LOC_CONF_OFFSET,
252 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.no_cache),
253 NULL },
254
255 { ngx_string("uwsgi_cache_valid"),
256 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
257 ngx_http_file_cache_valid_set_slot,
258 NGX_HTTP_LOC_CONF_OFFSET,
259 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_valid),
260 NULL },
261
262 { ngx_string("uwsgi_cache_min_uses"),
263 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
264 ngx_conf_set_num_slot,
265 NGX_HTTP_LOC_CONF_OFFSET,
266 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_min_uses),
267 NULL },
268
269 { ngx_string("uwsgi_cache_use_stale"),
270 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
271 ngx_conf_set_bitmask_slot,
272 NGX_HTTP_LOC_CONF_OFFSET,
273 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_use_stale),
274 &ngx_http_uwsgi_next_upstream_masks },
275
276 { ngx_string("uwsgi_cache_methods"),
277 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
278 ngx_conf_set_bitmask_slot,
279 NGX_HTTP_LOC_CONF_OFFSET,
280 offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_methods),
281 &ngx_http_upstream_cache_method_mask },
282
283 #endif
209 284
210 { ngx_string("uwsgi_temp_path"), 285 { ngx_string("uwsgi_temp_path"),
211 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, 286 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
212 ngx_conf_set_path_slot, 287 ngx_conf_set_path_slot,
213 NGX_HTTP_LOC_CONF_OFFSET, 288 NGX_HTTP_LOC_CONF_OFFSET,
304 NGX_MODULE_V1_PADDING 379 NGX_MODULE_V1_PADDING
305 }; 380 };
306 381
307 382
308 static ngx_str_t ngx_http_uwsgi_hide_headers[] = { 383 static ngx_str_t ngx_http_uwsgi_hide_headers[] = {
309 ngx_string("Status"),
310 ngx_string("X-Accel-Expires"), 384 ngx_string("X-Accel-Expires"),
311 ngx_string("X-Accel-Redirect"), 385 ngx_string("X-Accel-Redirect"),
312 ngx_string("X-Accel-Limit-Rate"), 386 ngx_string("X-Accel-Limit-Rate"),
313 ngx_string("X-Accel-Buffering"), 387 ngx_string("X-Accel-Buffering"),
314 ngx_string("X-Accel-Charset"), 388 ngx_string("X-Accel-Charset"),
315 ngx_null_string 389 ngx_null_string
316 }; 390 };
317 391
318 392
393 #if (NGX_HTTP_CACHE)
394
395 static ngx_str_t ngx_http_uwsgi_hide_cache_headers[] = {
396 ngx_string("X-Accel-Expires"),
397 ngx_string("X-Accel-Redirect"),
398 ngx_string("X-Accel-Limit-Rate"),
399 ngx_string("X-Accel-Buffering"),
400 ngx_string("X-Accel-Charset"),
401 ngx_string("Set-Cookie"),
402 ngx_string("P3P"),
403 ngx_null_string
404 };
405
406
407 static ngx_keyval_t ngx_http_uwsgi_cache_headers[] = {
408 { ngx_string("HTTP_IF_MODIFIED_SINCE"), ngx_string("") },
409 { ngx_string("HTTP_IF_UNMODIFIED_SINCE"), ngx_string("") },
410 { ngx_string("HTTP_IF_NONE_MATCH"), ngx_string("") },
411 { ngx_string("HTTP_IF_MATCH"), ngx_string("") },
412 { ngx_string("HTTP_RANGE"), ngx_string("") },
413 { ngx_string("HTTP_IF_RANGE"), ngx_string("") },
414 { ngx_null_string, ngx_null_string }
415 };
416
417 #endif
418
419
319 static ngx_path_init_t ngx_http_uwsgi_temp_path = { 420 static ngx_path_init_t ngx_http_uwsgi_temp_path = {
320 ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 } 421 ngx_string(NGX_HTTP_UWSGI_TEMP_PATH), { 1, 2, 0 }
321 }; 422 };
322 423
323 424
360 ngx_str_set(&u->schema, "uwsgi://"); 461 ngx_str_set(&u->schema, "uwsgi://");
361 u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module; 462 u->output.tag = (ngx_buf_tag_t) &ngx_http_uwsgi_module;
362 463
363 u->conf = &uwcf->upstream; 464 u->conf = &uwcf->upstream;
364 465
466 #if (NGX_HTTP_CACHE)
467 u->create_key = ngx_http_uwsgi_create_key;
468 #endif
365 u->create_request = ngx_http_uwsgi_create_request; 469 u->create_request = ngx_http_uwsgi_create_request;
366 u->reinit_request = ngx_http_uwsgi_reinit_request; 470 u->reinit_request = ngx_http_uwsgi_reinit_request;
367 u->process_header = ngx_http_uwsgi_process_status_line; 471 u->process_header = ngx_http_uwsgi_process_status_line;
368 u->abort_request = ngx_http_uwsgi_abort_request; 472 u->abort_request = ngx_http_uwsgi_abort_request;
369 u->finalize_request = ngx_http_uwsgi_finalize_request; 473 u->finalize_request = ngx_http_uwsgi_finalize_request;
436 r->upstream->resolved->port = u.port; 540 r->upstream->resolved->port = u.port;
437 } 541 }
438 542
439 return NGX_OK; 543 return NGX_OK;
440 } 544 }
545
546
547 #if (NGX_HTTP_CACHE)
548
549 static ngx_int_t
550 ngx_http_uwsgi_create_key(ngx_http_request_t *r)
551 {
552 ngx_str_t *key;
553 ngx_http_uwsgi_loc_conf_t *uwcf;
554
555 key = ngx_array_push(&r->cache->keys);
556 if (key == NULL) {
557 return NGX_ERROR;
558 }
559
560 uwcf = ngx_http_get_module_loc_conf(r, ngx_http_uwsgi_module);
561
562 if (ngx_http_complex_value(r, &uwcf->cache_key, key) != NGX_OK) {
563 return NGX_ERROR;
564 }
565
566 return NGX_OK;
567 }
568
569 #endif
441 570
442 571
443 static ngx_int_t 572 static ngx_int_t
444 ngx_http_uwsgi_create_request(ngx_http_request_t *r) 573 ngx_http_uwsgi_create_request(ngx_http_request_t *r)
445 { 574 {
1169 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE; 1298 conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
1170 1299
1171 conf->upstream.pass_request_headers = NGX_CONF_UNSET; 1300 conf->upstream.pass_request_headers = NGX_CONF_UNSET;
1172 conf->upstream.pass_request_body = NGX_CONF_UNSET; 1301 conf->upstream.pass_request_body = NGX_CONF_UNSET;
1173 1302
1303 #if (NGX_HTTP_CACHE)
1304 conf->upstream.cache = NGX_CONF_UNSET_PTR;
1305 conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
1306 conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
1307 #endif
1308
1174 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; 1309 conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
1175 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; 1310 conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
1176 1311
1177 conf->upstream.intercept_errors = NGX_CONF_UNSET; 1312 conf->upstream.intercept_errors = NGX_CONF_UNSET;
1178 1313
1190 ngx_http_uwsgi_loc_conf_t *conf = child; 1325 ngx_http_uwsgi_loc_conf_t *conf = child;
1191 1326
1192 u_char *p; 1327 u_char *p;
1193 size_t size; 1328 size_t size;
1194 uintptr_t *code; 1329 uintptr_t *code;
1330 ngx_str_t *hide;
1195 ngx_uint_t i; 1331 ngx_uint_t i;
1196 ngx_array_t headers_names; 1332 ngx_array_t headers_names;
1197 ngx_keyval_t *src; 1333 ngx_keyval_t *src;
1198 ngx_hash_key_t *hk; 1334 ngx_hash_key_t *hk;
1199 ngx_hash_init_t hash; 1335 ngx_hash_init_t hash;
1348 != NGX_OK) 1484 != NGX_OK)
1349 { 1485 {
1350 return NGX_CONF_ERROR; 1486 return NGX_CONF_ERROR;
1351 } 1487 }
1352 1488
1489 #if (NGX_HTTP_CACHE)
1490
1491 ngx_conf_merge_ptr_value(conf->upstream.cache,
1492 prev->upstream.cache, NULL);
1493
1494 if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
1495 ngx_shm_zone_t *shm_zone;
1496
1497 shm_zone = conf->upstream.cache;
1498
1499 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
1500 "\"uwsgi_cache\" zone \"%V\" is unknown",
1501 &shm_zone->shm.name);
1502
1503 return NGX_CONF_ERROR;
1504 }
1505
1506 ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
1507 prev->upstream.cache_min_uses, 1);
1508
1509 ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
1510 prev->upstream.cache_use_stale,
1511 (NGX_CONF_BITMASK_SET
1512 |NGX_HTTP_UPSTREAM_FT_OFF));
1513
1514 if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
1515 conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
1516 |NGX_HTTP_UPSTREAM_FT_OFF;
1517 }
1518
1519 if (conf->upstream.cache_methods == 0) {
1520 conf->upstream.cache_methods = prev->upstream.cache_methods;
1521 }
1522
1523 conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
1524
1525 ngx_conf_merge_ptr_value(conf->upstream.no_cache,
1526 prev->upstream.no_cache, NULL);
1527
1528 ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
1529 prev->upstream.cache_valid, NULL);
1530
1531 if (conf->cache_key.value.data == NULL) {
1532 conf->cache_key = prev->cache_key;
1533 }
1534
1535 #endif
1536
1353 ngx_conf_merge_value(conf->upstream.pass_request_headers, 1537 ngx_conf_merge_value(conf->upstream.pass_request_headers,
1354 prev->upstream.pass_request_headers, 1); 1538 prev->upstream.pass_request_headers, 1);
1355 ngx_conf_merge_value(conf->upstream.pass_request_body, 1539 ngx_conf_merge_value(conf->upstream.pass_request_body,
1356 prev->upstream.pass_request_body, 1); 1540 prev->upstream.pass_request_body, 1);
1357 1541
1362 1546
1363 hash.max_size = 512; 1547 hash.max_size = 512;
1364 hash.bucket_size = ngx_align(64, ngx_cacheline_size); 1548 hash.bucket_size = ngx_align(64, ngx_cacheline_size);
1365 hash.name = "uwsgi_hide_headers_hash"; 1549 hash.name = "uwsgi_hide_headers_hash";
1366 1550
1551 #if (NGX_HTTP_CACHE)
1552
1553 hide = conf->upstream.cache ? ngx_http_uwsgi_hide_cache_headers:
1554 ngx_http_uwsgi_hide_headers;
1555 #else
1556
1557 hide = ngx_http_uwsgi_hide_headers;
1558
1559 #endif
1560
1367 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, 1561 if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
1368 &prev->upstream, 1562 &prev->upstream, hide, &hash)
1369 ngx_http_uwsgi_hide_headers, &hash)
1370 != NGX_OK) 1563 != NGX_OK)
1371 { 1564 {
1372 return NGX_CONF_ERROR; 1565 return NGX_CONF_ERROR;
1373 } 1566 }
1374 1567
1389 conf->params_len = prev->params_len; 1582 conf->params_len = prev->params_len;
1390 conf->params = prev->params; 1583 conf->params = prev->params;
1391 conf->params_source = prev->params_source; 1584 conf->params_source = prev->params_source;
1392 conf->headers_hash = prev->headers_hash; 1585 conf->headers_hash = prev->headers_hash;
1393 1586
1587 #if (NGX_HTTP_CACHE)
1588
1589 if (conf->params_source == NULL) {
1590
1591 if ((conf->upstream.cache == NULL)
1592 == (prev->upstream.cache == NULL))
1593 {
1594 return NGX_CONF_OK;
1595 }
1596
1597 /* 6 is a number of ngx_http_uwsgi_cache_headers entries */
1598 conf->params_source = ngx_array_create(cf->pool, 6,
1599 sizeof(ngx_keyval_t));
1600 if (conf->params_source == NULL) {
1601 return NGX_CONF_ERROR;
1602 }
1603 }
1604 #else
1605
1394 if (conf->params_source == NULL) { 1606 if (conf->params_source == NULL) {
1395 return NGX_CONF_OK; 1607 return NGX_CONF_OK;
1396 } 1608 }
1609
1610 #endif
1397 } 1611 }
1398 1612
1399 conf->params_len = ngx_array_create(cf->pool, 64, 1); 1613 conf->params_len = ngx_array_create(cf->pool, 64, 1);
1400 if (conf->params_len == NULL) { 1614 if (conf->params_len == NULL) {
1401 return NGX_CONF_ERROR; 1615 return NGX_CONF_ERROR;
1411 { 1625 {
1412 return NGX_CONF_ERROR; 1626 return NGX_CONF_ERROR;
1413 } 1627 }
1414 1628
1415 src = conf->params_source->elts; 1629 src = conf->params_source->elts;
1630
1631 #if (NGX_HTTP_CACHE)
1632
1633 if (conf->upstream.cache) {
1634 ngx_keyval_t *h, *s;
1635
1636 for (h = ngx_http_uwsgi_cache_headers; h->key.len; h++) {
1637
1638 for (i = 0; i < conf->params_source->nelts; i++) {
1639 if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
1640 goto next;
1641 }
1642 }
1643
1644 s = ngx_array_push(conf->params_source);
1645 if (s == NULL) {
1646 return NGX_CONF_ERROR;
1647 }
1648
1649 *s = *h;
1650
1651 src = conf->params_source->elts;
1652
1653 next:
1654
1655 h++;
1656 }
1657 }
1658
1659 #endif
1660
1416 for (i = 0; i < conf->params_source->nelts; i++) { 1661 for (i = 0; i < conf->params_source->nelts; i++) {
1417 1662
1418 if (src[i].key.len > sizeof("HTTP_") - 1 1663 if (src[i].key.len > sizeof("HTTP_") - 1
1419 && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0) 1664 && ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
1420 { 1665 {
1587 return "is duplicate"; 1832 return "is duplicate";
1588 } 1833 }
1589 1834
1590 value = cf->args->elts; 1835 value = cf->args->elts;
1591 1836
1837 if (ngx_strcmp(value[1].data, "off") == 0) {
1838 uwcf->upstream.store = 0;
1839 return NGX_CONF_OK;
1840 }
1841
1842 #if (NGX_HTTP_CACHE)
1843
1844 if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR
1845 && uwcf->upstream.cache != NULL)
1846 {
1847 return "is incompatible with \"uwsgi_cache\"";
1848 }
1849
1850 #endif
1851
1592 if (ngx_strcmp(value[1].data, "on") == 0) { 1852 if (ngx_strcmp(value[1].data, "on") == 0) {
1593 uwcf->upstream.store = 1; 1853 uwcf->upstream.store = 1;
1594 return NGX_CONF_OK;
1595 }
1596
1597 if (ngx_strcmp(value[1].data, "off") == 0) {
1598 uwcf->upstream.store = 0;
1599 return NGX_CONF_OK; 1854 return NGX_CONF_OK;
1600 } 1855 }
1601 1856
1602 /* include the terminating '\0' into script */ 1857 /* include the terminating '\0' into script */
1603 value[1].len++; 1858 value[1].len++;
1616 return NGX_CONF_ERROR; 1871 return NGX_CONF_ERROR;
1617 } 1872 }
1618 1873
1619 return NGX_CONF_OK; 1874 return NGX_CONF_OK;
1620 } 1875 }
1876
1877
1878 #if (NGX_HTTP_CACHE)
1879
1880 static char *
1881 ngx_http_uwsgi_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1882 {
1883 ngx_http_uwsgi_loc_conf_t *uwcf = conf;
1884
1885 ngx_str_t *value;
1886
1887 value = cf->args->elts;
1888
1889 if (uwcf->upstream.cache != NGX_CONF_UNSET_PTR) {
1890 return "is duplicate";
1891 }
1892
1893 if (ngx_strcmp(value[1].data, "off") == 0) {
1894 uwcf->upstream.cache = NULL;
1895 return NGX_CONF_OK;
1896 }
1897
1898 if (uwcf->upstream.store > 0 || uwcf->upstream.store_lengths) {
1899 return "is incompatible with \"uwsgi_store\"";
1900 }
1901
1902 uwcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
1903 &ngx_http_uwsgi_module);
1904 if (uwcf->upstream.cache == NULL) {
1905 return NGX_CONF_ERROR;
1906 }
1907
1908 return NGX_CONF_OK;
1909 }
1910
1911
1912 static char *
1913 ngx_http_uwsgi_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
1914 {
1915 ngx_http_uwsgi_loc_conf_t *uwcf = conf;
1916
1917 ngx_str_t *value;
1918 ngx_http_compile_complex_value_t ccv;
1919
1920 value = cf->args->elts;
1921
1922 if (uwcf->cache_key.value.len) {
1923 return "is duplicate";
1924 }
1925
1926 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
1927
1928 ccv.cf = cf;
1929 ccv.value = &value[1];
1930 ccv.complex_value = &uwcf->cache_key;
1931
1932 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
1933 return NGX_CONF_ERROR;
1934 }
1935
1936 return NGX_CONF_OK;
1937 }
1938
1939 #endif