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 }