Mercurial > hg > nginx-vendor-1-0
comparison src/core/ngx_regex.c @ 546:e19e5f542878 NGINX_0_8_25
nginx 0.8.25
*) Change: now no message is written in an error log if a variable is
not found by $r->variable() method.
*) Feature: the ngx_http_degradation_module.
*) Feature: regular expression named captures.
*) Feature: now URI part is not required a "proxy_pass" directive if
variables are used.
*) Feature: now the "msie_padding" directive works for Chrome too.
*) Bugfix: a segmentation fault occurred in a worker process on low
memory condition; the bug had appeared in 0.8.18.
*) Bugfix: nginx sent gzipped responses to clients those do not support
gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared
in 0.8.16.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 16 Nov 2009 00:00:00 +0300 |
parents | 984bb0b1399b |
children | 697030d79811 |
comparison
equal
deleted
inserted
replaced
545:91e4b06e1a01 | 546:e19e5f542878 |
---|---|
21 pcre_malloc = ngx_regex_malloc; | 21 pcre_malloc = ngx_regex_malloc; |
22 pcre_free = ngx_regex_free; | 22 pcre_free = ngx_regex_free; |
23 } | 23 } |
24 | 24 |
25 | 25 |
26 ngx_regex_t * | 26 static ngx_inline void |
27 ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool, | 27 ngx_regex_malloc_init(ngx_pool_t *pool) |
28 ngx_str_t *err) | 28 { |
29 { | |
30 int erroff; | |
31 const char *errstr; | |
32 ngx_regex_t *re; | |
33 #if (NGX_THREADS) | 29 #if (NGX_THREADS) |
34 ngx_core_tls_t *tls; | 30 ngx_core_tls_t *tls; |
35 | |
36 #if (NGX_SUPPRESS_WARN) | |
37 tls = NULL; | |
38 #endif | |
39 | 31 |
40 if (ngx_threaded) { | 32 if (ngx_threaded) { |
41 tls = ngx_thread_get_tls(ngx_core_tls_key); | 33 tls = ngx_thread_get_tls(ngx_core_tls_key); |
42 tls->pool = pool; | 34 tls->pool = pool; |
43 } else { | 35 return; |
44 ngx_pcre_pool = pool; | |
45 } | 36 } |
46 | 37 |
47 #else | 38 #else |
48 | 39 |
49 ngx_pcre_pool = pool; | 40 ngx_pcre_pool = pool; |
50 | 41 |
51 #endif | 42 #endif |
52 | 43 } |
53 re = pcre_compile((const char *) pattern->data, (int) options, | 44 |
45 | |
46 static ngx_inline void | |
47 ngx_regex_malloc_done(void) | |
48 { | |
49 #if (NGX_THREADS) | |
50 ngx_core_tls_t *tls; | |
51 | |
52 if (ngx_threaded) { | |
53 tls = ngx_thread_get_tls(ngx_core_tls_key); | |
54 tls->pool = NULL; | |
55 return; | |
56 } | |
57 | |
58 #else | |
59 | |
60 ngx_pcre_pool = NULL; | |
61 | |
62 #endif | |
63 } | |
64 | |
65 | |
66 ngx_int_t | |
67 ngx_regex_compile(ngx_regex_compile_t *rc) | |
68 { | |
69 int n, erroff; | |
70 char *p; | |
71 const char *errstr; | |
72 ngx_regex_t *re; | |
73 | |
74 ngx_regex_malloc_init(rc->pool); | |
75 | |
76 re = pcre_compile((const char *) rc->pattern.data, (int) rc->options, | |
54 &errstr, &erroff, NULL); | 77 &errstr, &erroff, NULL); |
55 | 78 |
79 /* ensure that there is no current pool */ | |
80 ngx_regex_malloc_done(); | |
81 | |
56 if (re == NULL) { | 82 if (re == NULL) { |
57 if ((size_t) erroff == pattern->len) { | 83 if ((size_t) erroff == rc->pattern.len) { |
58 ngx_snprintf(err->data, err->len - 1, | 84 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, |
59 "pcre_compile() failed: %s in \"%s\"%Z", | 85 "pcre_compile() failed: %s in \"%V\"", |
60 errstr, pattern->data); | 86 errstr, &rc->pattern) |
87 - rc->err.data; | |
88 | |
61 } else { | 89 } else { |
62 ngx_snprintf(err->data, err->len - 1, | 90 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, |
63 "pcre_compile() failed: %s in \"%s\" at \"%s\"%Z", | 91 "pcre_compile() failed: %s in \"%V\" at \"%s\"", |
64 errstr, pattern->data, pattern->data + erroff); | 92 errstr, &rc->pattern, rc->pattern.data + erroff) |
93 - rc->err.data; | |
65 } | 94 } |
66 } | 95 |
67 | 96 return NGX_ERROR; |
68 /* ensure that there is no current pool */ | 97 } |
69 | 98 |
70 #if (NGX_THREADS) | 99 rc->regex = re; |
71 if (ngx_threaded) { | 100 |
72 tls->pool = NULL; | 101 n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures); |
73 } else { | 102 if (n < 0) { |
74 ngx_pcre_pool = NULL; | 103 p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d"; |
75 } | 104 goto failed; |
76 #else | 105 } |
77 ngx_pcre_pool = NULL; | 106 |
78 #endif | 107 if (rc->captures == 0) { |
79 | 108 return NGX_OK; |
80 return re; | 109 } |
110 | |
111 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures); | |
112 if (n < 0) { | |
113 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d"; | |
114 goto failed; | |
115 } | |
116 | |
117 if (rc->named_captures == 0) { | |
118 return NGX_OK; | |
119 } | |
120 | |
121 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size); | |
122 if (n < 0) { | |
123 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d"; | |
124 goto failed; | |
125 } | |
126 | |
127 n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names); | |
128 if (n < 0) { | |
129 p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d"; | |
130 goto failed; | |
131 } | |
132 | |
133 return NGX_OK; | |
134 | |
135 failed: | |
136 | |
137 rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n) | |
138 - rc->err.data; | |
139 return NGX_OK; | |
81 } | 140 } |
82 | 141 |
83 | 142 |
84 ngx_int_t | 143 ngx_int_t |
85 ngx_regex_capture_count(ngx_regex_t *re) | 144 ngx_regex_capture_count(ngx_regex_t *re) |
93 if (rc < 0) { | 152 if (rc < 0) { |
94 return (ngx_int_t) rc; | 153 return (ngx_int_t) rc; |
95 } | 154 } |
96 | 155 |
97 return (ngx_int_t) n; | 156 return (ngx_int_t) n; |
98 } | |
99 | |
100 | |
101 ngx_int_t | |
102 ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size) | |
103 { | |
104 int rc; | |
105 | |
106 rc = pcre_exec(re, NULL, (const char *) s->data, s->len, 0, 0, | |
107 captures, size); | |
108 | |
109 if (rc == -1) { | |
110 return NGX_REGEX_NO_MATCHED; | |
111 } | |
112 | |
113 return rc; | |
114 } | 157 } |
115 | 158 |
116 | 159 |
117 ngx_int_t | 160 ngx_int_t |
118 ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log) | 161 ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log) |
131 continue; | 174 continue; |
132 } | 175 } |
133 | 176 |
134 if (n < 0) { | 177 if (n < 0) { |
135 ngx_log_error(NGX_LOG_ALERT, log, 0, | 178 ngx_log_error(NGX_LOG_ALERT, log, 0, |
136 ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"", | 179 ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"", |
137 n, s, re[i].name); | 180 n, s, re[i].name); |
138 return NGX_ERROR; | 181 return NGX_ERROR; |
139 } | 182 } |
140 | 183 |
141 /* match */ | 184 /* match */ |
155 ngx_core_tls_t *tls; | 198 ngx_core_tls_t *tls; |
156 | 199 |
157 if (ngx_threaded) { | 200 if (ngx_threaded) { |
158 tls = ngx_thread_get_tls(ngx_core_tls_key); | 201 tls = ngx_thread_get_tls(ngx_core_tls_key); |
159 pool = tls->pool; | 202 pool = tls->pool; |
203 | |
160 } else { | 204 } else { |
161 pool = ngx_pcre_pool; | 205 pool = ngx_pcre_pool; |
162 } | 206 } |
207 | |
163 #else | 208 #else |
209 | |
164 pool = ngx_pcre_pool; | 210 pool = ngx_pcre_pool; |
211 | |
165 #endif | 212 #endif |
166 | 213 |
167 if (pool) { | 214 if (pool) { |
168 return ngx_palloc(pool, size); | 215 return ngx_palloc(pool, size); |
169 } | 216 } |