comparison src/http/modules/ngx_http_ssi_filter_module.c @ 644:ad25218fd14b NGINX_1_0_12

nginx 1.0.12 *) Feature: the "TLSv1.1" and "TLSv1.2" parameters of the "ssl_protocols" directive. *) Feature: the "if" SSI command supports captures in regular expressions. *) Bugfix: the "if" SSI command did not work inside the "block" command. *) Bugfix: in AIO error handling on FreeBSD. *) Bugfix: in the OpenSSL library initialization. *) Bugfix: the "worker_cpu_affinity" directive might not work. *) Bugfix: the "limit_conn_log_level" and "limit_req_log_level" directives might not work. *) Bugfix: the "read_ahead" directive might not work combined with "try_files" and "open_file_cache". *) Bugfix: the "proxy_cache_use_stale" directive with "error" parameter did not return answer from cache if there were no live upstreams. *) Bugfix: a segmentation fault might occur in a worker process if small time was used in the "inactive" parameter of the "proxy_cache_path" directive. *) Bugfix: responses from cache might hang. *) Bugfix: in error handling while connecting to a backend. Thanks to Piotr Sikora. *) Bugfix: in the "epoll" event method. Thanks to Yichun Zhang. *) Bugfix: the $sent_http_cache_control variable might contain a wrong value if the "expires" directive was used. Thanks to Yichun Zhang. *) Bugfix: the "limit_rate" directive did not allow to use full throughput, even if limit value was very high. *) Bugfix: the "sendfile_max_chunk" directive did not work, if the "limit_rate" directive was used. *) Bugfix: nginx could not be built on Solaris; the bug had appeared in 1.0.11. *) Bugfix: in the ngx_http_scgi_module. *) Bugfix: in the ngx_http_mp4_module.
author Igor Sysoev <http://sysoev.ru>
date Mon, 06 Feb 2012 00:00:00 +0400
parents 1b80544421e8
children
comparison
equal deleted inserted replaced
643:d81e1c257a02 644:ad25218fd14b
1 1
2 /* 2 /*
3 * Copyright (C) Igor Sysoev 3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
4 */ 5 */
5 6
6 7
7 #include <ngx_config.h> 8 #include <ngx_config.h>
8 #include <ngx_core.h> 9 #include <ngx_core.h>
76 ngx_http_ssi_ctx_t *ctx); 77 ngx_http_ssi_ctx_t *ctx);
77 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r, 78 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
78 ngx_str_t *name, ngx_uint_t key); 79 ngx_str_t *name, ngx_uint_t key);
79 static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r, 80 static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r,
80 ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags); 81 ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);
82 static ngx_int_t ngx_http_ssi_regex_match(ngx_http_request_t *r,
83 ngx_str_t *pattern, ngx_str_t *str);
81 84
82 static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r, 85 static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
83 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); 86 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params);
84 static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, 87 static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data,
85 ngx_int_t rc); 88 ngx_int_t rc);
622 } 625 }
623 626
624 continue; 627 continue;
625 } 628 }
626 629
627 if (cmd->conditional
628 && (ctx->conditional == 0
629 || ctx->conditional > cmd->conditional))
630 {
631 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
632 "invalid context of SSI command: \"%V\"",
633 &ctx->command);
634 goto ssi_error;
635 }
636
637 if (!ctx->output && !cmd->block) { 630 if (!ctx->output && !cmd->block) {
638 631
639 if (ctx->block) { 632 if (ctx->block) {
640 633
641 /* reconstruct the SSI command text */ 634 /* reconstruct the SSI command text */
707 if (cmd->conditional == 0) { 700 if (cmd->conditional == 0) {
708 continue; 701 continue;
709 } 702 }
710 } 703 }
711 704
705 if (cmd->conditional
706 && (ctx->conditional == 0
707 || ctx->conditional > cmd->conditional))
708 {
709 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
710 "invalid context of SSI command: \"%V\"",
711 &ctx->command);
712 goto ssi_error;
713 }
714
712 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) { 715 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
713 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 716 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
714 "too many SSI command paramters: \"%V\"", 717 "too many SSI command paramters: \"%V\"",
715 &ctx->command); 718 &ctx->command);
716 goto ssi_error; 719 goto ssi_error;
1528 ngx_list_part_t *part; 1531 ngx_list_part_t *part;
1529 ngx_http_ssi_var_t *var; 1532 ngx_http_ssi_var_t *var;
1530 ngx_http_ssi_ctx_t *ctx; 1533 ngx_http_ssi_ctx_t *ctx;
1531 1534
1532 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module); 1535 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1536
1537 #if (NGX_PCRE)
1538 {
1539 ngx_str_t *value;
1540
1541 if (key >= '0' && key <= '9') {
1542 i = key - '0';
1543
1544 if (i < ctx->ncaptures) {
1545 value = ngx_palloc(r->pool, sizeof(ngx_str_t));
1546 if (value == NULL) {
1547 return NULL;
1548 }
1549
1550 i *= 2;
1551
1552 value->data = ctx->captures_data + ctx->captures[i];
1553 value->len = ctx->captures[i + 1] - ctx->captures[i];
1554
1555 return value;
1556 }
1557 }
1558 }
1559 #endif
1533 1560
1534 if (ctx->variables == NULL) { 1561 if (ctx->variables == NULL) {
1535 return NULL; 1562 return NULL;
1536 } 1563 }
1537 1564
1814 1841
1815 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1842 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1816 "invalid variable name in \"%V\"", text); 1843 "invalid variable name in \"%V\"", text);
1817 1844
1818 return NGX_HTTP_SSI_ERROR; 1845 return NGX_HTTP_SSI_ERROR;
1846 }
1847
1848
1849 static ngx_int_t
1850 ngx_http_ssi_regex_match(ngx_http_request_t *r, ngx_str_t *pattern,
1851 ngx_str_t *str)
1852 {
1853 #if (NGX_PCRE)
1854 int rc, *captures;
1855 u_char *p, errstr[NGX_MAX_CONF_ERRSTR];
1856 size_t size;
1857 ngx_int_t key;
1858 ngx_str_t *vv, name, value;
1859 ngx_uint_t i, n;
1860 ngx_http_ssi_ctx_t *ctx;
1861 ngx_http_ssi_var_t *var;
1862 ngx_regex_compile_t rgc;
1863
1864 ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
1865
1866 rgc.pattern = *pattern;
1867 rgc.pool = r->pool;
1868 rgc.err.len = NGX_MAX_CONF_ERRSTR;
1869 rgc.err.data = errstr;
1870
1871 if (ngx_regex_compile(&rgc) != NGX_OK) {
1872 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
1873 return NGX_HTTP_SSI_ERROR;
1874 }
1875
1876 n = (rgc.captures + 1) * 3;
1877
1878 captures = ngx_palloc(r->pool, n * sizeof(int));
1879 if (captures == NULL) {
1880 return NGX_ERROR;
1881 }
1882
1883 rc = ngx_regex_exec(rgc.regex, str, captures, n);
1884
1885 if (rc < NGX_REGEX_NO_MATCHED) {
1886 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1887 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
1888 rc, str, pattern);
1889 return NGX_HTTP_SSI_ERROR;
1890 }
1891
1892 if (rc == NGX_REGEX_NO_MATCHED) {
1893 return NGX_DECLINED;
1894 }
1895
1896 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1897
1898 ctx->ncaptures = rc;
1899 ctx->captures = captures;
1900 ctx->captures_data = str->data;
1901
1902 if (rgc.named_captures > 0) {
1903
1904 if (ctx->variables == NULL) {
1905 ctx->variables = ngx_list_create(r->pool, 4,
1906 sizeof(ngx_http_ssi_var_t));
1907 if (ctx->variables == NULL) {
1908 return NGX_ERROR;
1909 }
1910 }
1911
1912 size = rgc.name_size;
1913 p = rgc.names;
1914
1915 for (i = 0; i < (ngx_uint_t) rgc.named_captures; i++, p += size) {
1916
1917 name.data = &p[2];
1918 name.len = ngx_strlen(name.data);
1919
1920 n = 2 * ((p[0] << 8) + p[1]);
1921
1922 value.data = &str->data[captures[n]];
1923 value.len = captures[n + 1] - captures[n];
1924
1925 key = ngx_hash_strlow(name.data, name.data, name.len);
1926
1927 vv = ngx_http_ssi_get_variable(r, &name, key);
1928
1929 if (vv) {
1930 *vv = value;
1931 continue;
1932 }
1933
1934 var = ngx_list_push(ctx->variables);
1935 if (var == NULL) {
1936 return NGX_ERROR;
1937 }
1938
1939 var->name = name;
1940 var->key = key;
1941 var->value = value;
1942 }
1943 }
1944
1945 return NGX_OK;
1946
1947 #else
1948
1949 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1950 "the using of the regex \"%V\" in SSI requires PCRE library",
1951 pattern);
1952 return NGX_HTTP_SSI_ERROR;
1953
1954 #endif
1819 } 1955 }
1820 1956
1821 1957
1822 static ngx_int_t 1958 static ngx_int_t
1823 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, 1959 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2449 } else { 2585 } else {
2450 rc = ngx_strncmp(left.data, right.data, right.len); 2586 rc = ngx_strncmp(left.data, right.data, right.len);
2451 } 2587 }
2452 2588
2453 } else { 2589 } else {
2454 #if (NGX_PCRE)
2455 ngx_regex_compile_t rgc;
2456 u_char errstr[NGX_MAX_CONF_ERRSTR];
2457
2458 right.data[right.len] = '\0'; 2590 right.data[right.len] = '\0';
2459 2591
2460 ngx_memzero(&rgc, sizeof(ngx_regex_compile_t)); 2592 rc = ngx_http_ssi_regex_match(r, &right, &left);
2461 2593
2462 rgc.pattern = right; 2594 if (rc == NGX_OK) {
2463 rgc.pool = r->pool; 2595 rc = 0;
2464 rgc.err.len = NGX_MAX_CONF_ERRSTR; 2596 } else if (rc == NGX_DECLINED) {
2465 rgc.err.data = errstr; 2597 rc = -1;
2466 2598 } else {
2467 if (ngx_regex_compile(&rgc) != NGX_OK) { 2599 return rc;
2468 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err); 2600 }
2469 return NGX_HTTP_SSI_ERROR;
2470 }
2471
2472 rc = ngx_regex_exec(rgc.regex, &left, NULL, 0);
2473
2474 if (rc < NGX_REGEX_NO_MATCHED) {
2475 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
2476 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
2477 rc, &left, &right);
2478 return NGX_HTTP_SSI_ERROR;
2479 }
2480 #else
2481 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
2482 "the using of the regex \"%V\" in SSI "
2483 "requires PCRE library", &right);
2484
2485 return NGX_HTTP_SSI_ERROR;
2486 #endif
2487 } 2601 }
2488 2602
2489 if ((rc == 0 && !negative) || (rc != 0 && negative)) { 2603 if ((rc == 0 && !negative) || (rc != 0 && negative)) {
2490 ctx->output = 1; 2604 ctx->output = 1;
2491 ctx->output_chosen = 1; 2605 ctx->output_chosen = 1;