comparison src/http/modules/ngx_http_ssi_filter_module.c @ 656:9d21dad0b5a1 NGINX_1_1_12

nginx 1.1.12 *) Change: a "proxy_pass" directive without URI part now uses changed URI after redirection with the "error_page" directive; Thanks to Lanshun Zhou. *) Feature: the "proxy/fastcgi/scgi/uwsgi_cache_lock", "proxy/fastcgi/scgi/uwsgi_cache_lock_timeout" directives. *) Feature: the "pcre_jit" directive. *) Feature: the "if" SSI command supports captures in regular expressions. *) Bugfix: the "if" SSI command did not work inside the "block" command. *) Bugfix: the "limit_conn_log_level" and "limit_req_log_level" directives might not work. *) 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: a "proxy_pass" directive without URI part always used original request URI if variables were used. *) Bugfix: a "proxy_pass" directive without URI part might use original request after redirection with the "try_files" directive; Thanks to Lanshun Zhou. *) Bugfix: in the ngx_http_scgi_module. *) Bugfix: in the ngx_http_mp4_module. *) Bugfix: nginx could not be built on Solaris; the bug had appeared in 1.1.9.
author Igor Sysoev <http://sysoev.ru>
date Mon, 26 Dec 2011 00:00:00 +0400
parents f200748c0ac8
children d0f7a625f27c
comparison
equal deleted inserted replaced
655:189afff6503f 656:9d21dad0b5a1
76 ngx_http_ssi_ctx_t *ctx); 76 ngx_http_ssi_ctx_t *ctx);
77 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r, 77 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
78 ngx_str_t *name, ngx_uint_t key); 78 ngx_str_t *name, ngx_uint_t key);
79 static ngx_int_t ngx_http_ssi_evaluate_string(ngx_http_request_t *r, 79 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); 80 ngx_http_ssi_ctx_t *ctx, ngx_str_t *text, ngx_uint_t flags);
81 static ngx_int_t ngx_http_ssi_regex_match(ngx_http_request_t *r,
82 ngx_str_t *pattern, ngx_str_t *str);
81 83
82 static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r, 84 static ngx_int_t ngx_http_ssi_include(ngx_http_request_t *r,
83 ngx_http_ssi_ctx_t *ctx, ngx_str_t **params); 85 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, 86 static ngx_int_t ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data,
85 ngx_int_t rc); 87 ngx_int_t rc);
622 } 624 }
623 625
624 continue; 626 continue;
625 } 627 }
626 628
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) { 629 if (!ctx->output && !cmd->block) {
638 630
639 if (ctx->block) { 631 if (ctx->block) {
640 632
641 /* reconstruct the SSI command text */ 633 /* reconstruct the SSI command text */
707 if (cmd->conditional == 0) { 699 if (cmd->conditional == 0) {
708 continue; 700 continue;
709 } 701 }
710 } 702 }
711 703
704 if (cmd->conditional
705 && (ctx->conditional == 0
706 || ctx->conditional > cmd->conditional))
707 {
708 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
709 "invalid context of SSI command: \"%V\"",
710 &ctx->command);
711 goto ssi_error;
712 }
713
712 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) { 714 if (ctx->params.nelts > NGX_HTTP_SSI_MAX_PARAMS) {
713 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 715 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
714 "too many SSI command paramters: \"%V\"", 716 "too many SSI command paramters: \"%V\"",
715 &ctx->command); 717 &ctx->command);
716 goto ssi_error; 718 goto ssi_error;
1528 ngx_list_part_t *part; 1530 ngx_list_part_t *part;
1529 ngx_http_ssi_var_t *var; 1531 ngx_http_ssi_var_t *var;
1530 ngx_http_ssi_ctx_t *ctx; 1532 ngx_http_ssi_ctx_t *ctx;
1531 1533
1532 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module); 1534 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1535
1536 #if (NGX_PCRE)
1537 {
1538 ngx_str_t *value;
1539
1540 if (key >= '0' && key <= '9') {
1541 i = key - '0';
1542
1543 if (i < ctx->ncaptures) {
1544 value = ngx_palloc(r->pool, sizeof(ngx_str_t));
1545 if (value == NULL) {
1546 return NULL;
1547 }
1548
1549 i *= 2;
1550
1551 value->data = ctx->captures_data + ctx->captures[i];
1552 value->len = ctx->captures[i + 1] - ctx->captures[i];
1553
1554 return value;
1555 }
1556 }
1557 }
1558 #endif
1533 1559
1534 if (ctx->variables == NULL) { 1560 if (ctx->variables == NULL) {
1535 return NULL; 1561 return NULL;
1536 } 1562 }
1537 1563
1814 1840
1815 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1841 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1816 "invalid variable name in \"%V\"", text); 1842 "invalid variable name in \"%V\"", text);
1817 1843
1818 return NGX_HTTP_SSI_ERROR; 1844 return NGX_HTTP_SSI_ERROR;
1845 }
1846
1847
1848 static ngx_int_t
1849 ngx_http_ssi_regex_match(ngx_http_request_t *r, ngx_str_t *pattern,
1850 ngx_str_t *str)
1851 {
1852 #if (NGX_PCRE)
1853 int rc, *captures;
1854 u_char *p, errstr[NGX_MAX_CONF_ERRSTR];
1855 size_t size;
1856 ngx_int_t key;
1857 ngx_str_t *vv, name, value;
1858 ngx_uint_t i, n;
1859 ngx_http_ssi_ctx_t *ctx;
1860 ngx_http_ssi_var_t *var;
1861 ngx_regex_compile_t rgc;
1862
1863 ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
1864
1865 rgc.pattern = *pattern;
1866 rgc.pool = r->pool;
1867 rgc.err.len = NGX_MAX_CONF_ERRSTR;
1868 rgc.err.data = errstr;
1869
1870 if (ngx_regex_compile(&rgc) != NGX_OK) {
1871 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
1872 return NGX_HTTP_SSI_ERROR;
1873 }
1874
1875 n = (rgc.captures + 1) * 3;
1876
1877 captures = ngx_palloc(r->pool, n * sizeof(int));
1878 if (captures == NULL) {
1879 return NGX_ERROR;
1880 }
1881
1882 rc = ngx_regex_exec(rgc.regex, str, captures, n);
1883
1884 if (rc < NGX_REGEX_NO_MATCHED) {
1885 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1886 ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
1887 rc, str, pattern);
1888 return NGX_HTTP_SSI_ERROR;
1889 }
1890
1891 if (rc == NGX_REGEX_NO_MATCHED) {
1892 return NGX_DECLINED;
1893 }
1894
1895 ctx = ngx_http_get_module_ctx(r->main, ngx_http_ssi_filter_module);
1896
1897 ctx->ncaptures = rc;
1898 ctx->captures = captures;
1899 ctx->captures_data = str->data;
1900
1901 if (rgc.named_captures > 0) {
1902
1903 if (ctx->variables == NULL) {
1904 ctx->variables = ngx_list_create(r->pool, 4,
1905 sizeof(ngx_http_ssi_var_t));
1906 if (ctx->variables == NULL) {
1907 return NGX_ERROR;
1908 }
1909 }
1910
1911 size = rgc.name_size;
1912 p = rgc.names;
1913
1914 for (i = 0; i < (ngx_uint_t) rgc.named_captures; i++, p += size) {
1915
1916 name.data = &p[2];
1917 name.len = ngx_strlen(name.data);
1918
1919 n = 2 * ((p[0] << 8) + p[1]);
1920
1921 value.data = &str->data[captures[n]];
1922 value.len = captures[n + 1] - captures[n];
1923
1924 key = ngx_hash_strlow(name.data, name.data, name.len);
1925
1926 vv = ngx_http_ssi_get_variable(r, &name, key);
1927
1928 if (vv) {
1929 *vv = value;
1930 continue;
1931 }
1932
1933 var = ngx_list_push(ctx->variables);
1934 if (var == NULL) {
1935 return NGX_ERROR;
1936 }
1937
1938 var->name = name;
1939 var->key = key;
1940 var->value = value;
1941 }
1942 }
1943
1944 return NGX_OK;
1945
1946 #else
1947
1948 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
1949 "the using of the regex \"%V\" in SSI requires PCRE library",
1950 pattern);
1951 return NGX_HTTP_SSI_ERROR;
1952
1953 #endif
1819 } 1954 }
1820 1955
1821 1956
1822 static ngx_int_t 1957 static ngx_int_t
1823 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx, 1958 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
2449 } else { 2584 } else {
2450 rc = ngx_strncmp(left.data, right.data, right.len); 2585 rc = ngx_strncmp(left.data, right.data, right.len);
2451 } 2586 }
2452 2587
2453 } else { 2588 } 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'; 2589 right.data[right.len] = '\0';
2459 2590
2460 ngx_memzero(&rgc, sizeof(ngx_regex_compile_t)); 2591 rc = ngx_http_ssi_regex_match(r, &right, &left);
2461 2592
2462 rgc.pattern = right; 2593 if (rc == NGX_OK) {
2463 rgc.pool = r->pool; 2594 rc = 0;
2464 rgc.err.len = NGX_MAX_CONF_ERRSTR; 2595 } else if (rc == NGX_DECLINED) {
2465 rgc.err.data = errstr; 2596 rc = -1;
2466 2597 } else {
2467 if (ngx_regex_compile(&rgc) != NGX_OK) { 2598 return rc;
2468 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err); 2599 }
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 } 2600 }
2488 2601
2489 if ((rc == 0 && !negative) || (rc != 0 && negative)) { 2602 if ((rc == 0 && !negative) || (rc != 0 && negative)) {
2490 ctx->output = 1; 2603 ctx->output = 1;
2491 ctx->output_chosen = 1; 2604 ctx->output_chosen = 1;