Mercurial > hg > nginx-vendor-1-0
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; |