1e18a033bSKonstantin Ananyev
2e18a033bSKonstantin Ananyev/*
3e18a033bSKonstantin Ananyev * Copyright (C) Igor Sysoev
4e18a033bSKonstantin Ananyev * Copyright (C) Nginx, Inc.
5e18a033bSKonstantin Ananyev */
6e18a033bSKonstantin Ananyev
7e18a033bSKonstantin Ananyev
8e18a033bSKonstantin Ananyev#include <ngx_config.h>
9e18a033bSKonstantin Ananyev#include <ngx_core.h>
10e18a033bSKonstantin Ananyev
11e18a033bSKonstantin Ananyev
12e18a033bSKonstantin Ananyevtypedef struct {
13e18a033bSKonstantin Ananyev    ngx_flag_t  pcre_jit;
14e18a033bSKonstantin Ananyev} ngx_regex_conf_t;
15e18a033bSKonstantin Ananyev
16e18a033bSKonstantin Ananyev
17e18a033bSKonstantin Ananyevstatic void * ngx_libc_cdecl ngx_regex_malloc(size_t size);
18e18a033bSKonstantin Ananyevstatic void ngx_libc_cdecl ngx_regex_free(void *p);
19e18a033bSKonstantin Ananyev#if (NGX_HAVE_PCRE_JIT)
20e18a033bSKonstantin Ananyevstatic void ngx_pcre_free_studies(void *data);
21e18a033bSKonstantin Ananyev#endif
22e18a033bSKonstantin Ananyev
23e18a033bSKonstantin Ananyevstatic ngx_int_t ngx_regex_module_init(ngx_cycle_t *cycle);
24e18a033bSKonstantin Ananyev
25e18a033bSKonstantin Ananyevstatic void *ngx_regex_create_conf(ngx_cycle_t *cycle);
26e18a033bSKonstantin Ananyevstatic char *ngx_regex_init_conf(ngx_cycle_t *cycle, void *conf);
27e18a033bSKonstantin Ananyev
28e18a033bSKonstantin Ananyevstatic char *ngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data);
29e18a033bSKonstantin Ananyevstatic ngx_conf_post_t  ngx_regex_pcre_jit_post = { ngx_regex_pcre_jit };
30e18a033bSKonstantin Ananyev
31e18a033bSKonstantin Ananyev
32e18a033bSKonstantin Ananyevstatic ngx_command_t  ngx_regex_commands[] = {
33e18a033bSKonstantin Ananyev
34e18a033bSKonstantin Ananyev    { ngx_string("pcre_jit"),
35e18a033bSKonstantin Ananyev      NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG,
36e18a033bSKonstantin Ananyev      ngx_conf_set_flag_slot,
37e18a033bSKonstantin Ananyev      0,
38e18a033bSKonstantin Ananyev      offsetof(ngx_regex_conf_t, pcre_jit),
39e18a033bSKonstantin Ananyev      &ngx_regex_pcre_jit_post },
40e18a033bSKonstantin Ananyev
41e18a033bSKonstantin Ananyev      ngx_null_command
42e18a033bSKonstantin Ananyev};
43e18a033bSKonstantin Ananyev
44e18a033bSKonstantin Ananyev
45e18a033bSKonstantin Ananyevstatic ngx_core_module_t  ngx_regex_module_ctx = {
46e18a033bSKonstantin Ananyev    ngx_string("regex"),
47e18a033bSKonstantin Ananyev    ngx_regex_create_conf,
48e18a033bSKonstantin Ananyev    ngx_regex_init_conf
49e18a033bSKonstantin Ananyev};
50e18a033bSKonstantin Ananyev
51e18a033bSKonstantin Ananyev
52e18a033bSKonstantin Ananyevngx_module_t  ngx_regex_module = {
53e18a033bSKonstantin Ananyev    NGX_MODULE_V1,
54e18a033bSKonstantin Ananyev    &ngx_regex_module_ctx,                 /* module context */
55e18a033bSKonstantin Ananyev    ngx_regex_commands,                    /* module directives */
56e18a033bSKonstantin Ananyev    NGX_CORE_MODULE,                       /* module type */
57e18a033bSKonstantin Ananyev    NULL,                                  /* init master */
58e18a033bSKonstantin Ananyev    ngx_regex_module_init,                 /* init module */
59e18a033bSKonstantin Ananyev    NULL,                                  /* init process */
60e18a033bSKonstantin Ananyev    NULL,                                  /* init thread */
61e18a033bSKonstantin Ananyev    NULL,                                  /* exit thread */
62e18a033bSKonstantin Ananyev    NULL,                                  /* exit process */
63e18a033bSKonstantin Ananyev    NULL,                                  /* exit master */
64e18a033bSKonstantin Ananyev    NGX_MODULE_V1_PADDING
65e18a033bSKonstantin Ananyev};
66e18a033bSKonstantin Ananyev
67e18a033bSKonstantin Ananyev
68e18a033bSKonstantin Ananyevstatic ngx_pool_t  *ngx_pcre_pool;
69e18a033bSKonstantin Ananyevstatic ngx_list_t  *ngx_pcre_studies;
70e18a033bSKonstantin Ananyev
71e18a033bSKonstantin Ananyev
72e18a033bSKonstantin Ananyevvoid
73e18a033bSKonstantin Ananyevngx_regex_init(void)
74e18a033bSKonstantin Ananyev{
75e18a033bSKonstantin Ananyev    pcre_malloc = ngx_regex_malloc;
76e18a033bSKonstantin Ananyev    pcre_free = ngx_regex_free;
77e18a033bSKonstantin Ananyev}
78e18a033bSKonstantin Ananyev
79e18a033bSKonstantin Ananyev
80e18a033bSKonstantin Ananyevstatic ngx_inline void
81e18a033bSKonstantin Ananyevngx_regex_malloc_init(ngx_pool_t *pool)
82e18a033bSKonstantin Ananyev{
83e18a033bSKonstantin Ananyev    ngx_pcre_pool = pool;
84e18a033bSKonstantin Ananyev}
85e18a033bSKonstantin Ananyev
86e18a033bSKonstantin Ananyev
87e18a033bSKonstantin Ananyevstatic ngx_inline void
88e18a033bSKonstantin Ananyevngx_regex_malloc_done(void)
89e18a033bSKonstantin Ananyev{
90e18a033bSKonstantin Ananyev    ngx_pcre_pool = NULL;
91e18a033bSKonstantin Ananyev}
92e18a033bSKonstantin Ananyev
93e18a033bSKonstantin Ananyev
94e18a033bSKonstantin Ananyevngx_int_t
95e18a033bSKonstantin Ananyevngx_regex_compile(ngx_regex_compile_t *rc)
96e18a033bSKonstantin Ananyev{
97e18a033bSKonstantin Ananyev    int               n, erroff;
98e18a033bSKonstantin Ananyev    char             *p;
99e18a033bSKonstantin Ananyev    pcre             *re;
100e18a033bSKonstantin Ananyev    const char       *errstr;
101e18a033bSKonstantin Ananyev    ngx_regex_elt_t  *elt;
102e18a033bSKonstantin Ananyev
103e18a033bSKonstantin Ananyev    ngx_regex_malloc_init(rc->pool);
104e18a033bSKonstantin Ananyev
105e18a033bSKonstantin Ananyev    re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
106e18a033bSKonstantin Ananyev                      &errstr, &erroff, NULL);
107e18a033bSKonstantin Ananyev
108e18a033bSKonstantin Ananyev    /* ensure that there is no current pool */
109e18a033bSKonstantin Ananyev    ngx_regex_malloc_done();
110e18a033bSKonstantin Ananyev
111e18a033bSKonstantin Ananyev    if (re == NULL) {
112e18a033bSKonstantin Ananyev        if ((size_t) erroff == rc->pattern.len) {
113e18a033bSKonstantin Ananyev           rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
114e18a033bSKonstantin Ananyev                              "pcre_compile() failed: %s in \"%V\"",
115e18a033bSKonstantin Ananyev                               errstr, &rc->pattern)
116e18a033bSKonstantin Ananyev                      - rc->err.data;
117e18a033bSKonstantin Ananyev
118e18a033bSKonstantin Ananyev        } else {
119e18a033bSKonstantin Ananyev           rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
120e18a033bSKonstantin Ananyev                              "pcre_compile() failed: %s in \"%V\" at \"%s\"",
121e18a033bSKonstantin Ananyev                               errstr, &rc->pattern, rc->pattern.data + erroff)
122e18a033bSKonstantin Ananyev                      - rc->err.data;
123e18a033bSKonstantin Ananyev        }
124e18a033bSKonstantin Ananyev
125e18a033bSKonstantin Ananyev        return NGX_ERROR;
126e18a033bSKonstantin Ananyev    }
127e18a033bSKonstantin Ananyev
128e18a033bSKonstantin Ananyev    rc->regex = ngx_pcalloc(rc->pool, sizeof(ngx_regex_t));
129e18a033bSKonstantin Ananyev    if (rc->regex == NULL) {
130e18a033bSKonstantin Ananyev        goto nomem;
131e18a033bSKonstantin Ananyev    }
132e18a033bSKonstantin Ananyev
133e18a033bSKonstantin Ananyev    rc->regex->code = re;
134e18a033bSKonstantin Ananyev
135e18a033bSKonstantin Ananyev    /* do not study at runtime */
136e18a033bSKonstantin Ananyev
137e18a033bSKonstantin Ananyev    if (ngx_pcre_studies != NULL) {
138e18a033bSKonstantin Ananyev        elt = ngx_list_push(ngx_pcre_studies);
139e18a033bSKonstantin Ananyev        if (elt == NULL) {
140e18a033bSKonstantin Ananyev            goto nomem;
141e18a033bSKonstantin Ananyev        }
142e18a033bSKonstantin Ananyev
143e18a033bSKonstantin Ananyev        elt->regex = rc->regex;
144e18a033bSKonstantin Ananyev        elt->name = rc->pattern.data;
145e18a033bSKonstantin Ananyev    }
146e18a033bSKonstantin Ananyev
147e18a033bSKonstantin Ananyev    n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
148e18a033bSKonstantin Ananyev    if (n < 0) {
149e18a033bSKonstantin Ananyev        p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
150e18a033bSKonstantin Ananyev        goto failed;
151e18a033bSKonstantin Ananyev    }
152e18a033bSKonstantin Ananyev
153e18a033bSKonstantin Ananyev    if (rc->captures == 0) {
154e18a033bSKonstantin Ananyev        return NGX_OK;
155e18a033bSKonstantin Ananyev    }
156e18a033bSKonstantin Ananyev
157e18a033bSKonstantin Ananyev    n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
158e18a033bSKonstantin Ananyev    if (n < 0) {
159e18a033bSKonstantin Ananyev        p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
160e18a033bSKonstantin Ananyev        goto failed;
161e18a033bSKonstantin Ananyev    }
162e18a033bSKonstantin Ananyev
163e18a033bSKonstantin Ananyev    if (rc->named_captures == 0) {
164e18a033bSKonstantin Ananyev        return NGX_OK;
165e18a033bSKonstantin Ananyev    }
166e18a033bSKonstantin Ananyev
167e18a033bSKonstantin Ananyev    n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
168e18a033bSKonstantin Ananyev    if (n < 0) {
169e18a033bSKonstantin Ananyev        p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
170e18a033bSKonstantin Ananyev        goto failed;
171e18a033bSKonstantin Ananyev    }
172e18a033bSKonstantin Ananyev
173e18a033bSKonstantin Ananyev    n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
174e18a033bSKonstantin Ananyev    if (n < 0) {
175e18a033bSKonstantin Ananyev        p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
176e18a033bSKonstantin Ananyev        goto failed;
177e18a033bSKonstantin Ananyev    }
178e18a033bSKonstantin Ananyev
179e18a033bSKonstantin Ananyev    return NGX_OK;
180e18a033bSKonstantin Ananyev
181e18a033bSKonstantin Ananyevfailed:
182e18a033bSKonstantin Ananyev
183e18a033bSKonstantin Ananyev    rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
184e18a033bSKonstantin Ananyev                  - rc->err.data;
185e18a033bSKonstantin Ananyev    return NGX_ERROR;
186e18a033bSKonstantin Ananyev
187e18a033bSKonstantin Ananyevnomem:
188e18a033bSKonstantin Ananyev
189e18a033bSKonstantin Ananyev    rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
190e18a033bSKonstantin Ananyev                               "regex \"%V\" compilation failed: no memory",
191e18a033bSKonstantin Ananyev                               &rc->pattern)
192e18a033bSKonstantin Ananyev                  - rc->err.data;
193e18a033bSKonstantin Ananyev    return NGX_ERROR;
194e18a033bSKonstantin Ananyev}
195e18a033bSKonstantin Ananyev
196e18a033bSKonstantin Ananyev
197e18a033bSKonstantin Ananyevngx_int_t
198e18a033bSKonstantin Ananyevngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
199e18a033bSKonstantin Ananyev{
200e18a033bSKonstantin Ananyev    ngx_int_t         n;
201e18a033bSKonstantin Ananyev    ngx_uint_t        i;
202e18a033bSKonstantin Ananyev    ngx_regex_elt_t  *re;
203e18a033bSKonstantin Ananyev
204e18a033bSKonstantin Ananyev    re = a->elts;
205e18a033bSKonstantin Ananyev
206e18a033bSKonstantin Ananyev    for (i = 0; i < a->nelts; i++) {
207e18a033bSKonstantin Ananyev
208e18a033bSKonstantin Ananyev        n = ngx_regex_exec(re[i].regex, s, NULL, 0);
209e18a033bSKonstantin Ananyev
210e18a033bSKonstantin Ananyev        if (n == NGX_REGEX_NO_MATCHED) {
211e18a033bSKonstantin Ananyev            continue;
212e18a033bSKonstantin Ananyev        }
213e18a033bSKonstantin Ananyev
214e18a033bSKonstantin Ananyev        if (n < 0) {
215e18a033bSKonstantin Ananyev            ngx_log_error(NGX_LOG_ALERT, log, 0,
216e18a033bSKonstantin Ananyev                          ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
217e18a033bSKonstantin Ananyev                          n, s, re[i].name);
218e18a033bSKonstantin Ananyev            return NGX_ERROR;
219e18a033bSKonstantin Ananyev        }
220e18a033bSKonstantin Ananyev
221e18a033bSKonstantin Ananyev        /* match */
222e18a033bSKonstantin Ananyev
223e18a033bSKonstantin Ananyev        return NGX_OK;
224e18a033bSKonstantin Ananyev    }
225e18a033bSKonstantin Ananyev
226e18a033bSKonstantin Ananyev    return NGX_DECLINED;
227e18a033bSKonstantin Ananyev}
228e18a033bSKonstantin Ananyev
229e18a033bSKonstantin Ananyev
230e18a033bSKonstantin Ananyevstatic void * ngx_libc_cdecl
231e18a033bSKonstantin Ananyevngx_regex_malloc(size_t size)
232e18a033bSKonstantin Ananyev{
233e18a033bSKonstantin Ananyev    ngx_pool_t      *pool;
234e18a033bSKonstantin Ananyev    pool = ngx_pcre_pool;
235e18a033bSKonstantin Ananyev
236e18a033bSKonstantin Ananyev    if (pool) {
237e18a033bSKonstantin Ananyev        return ngx_palloc(pool, size);
238e18a033bSKonstantin Ananyev    }
239e18a033bSKonstantin Ananyev
240e18a033bSKonstantin Ananyev    return NULL;
241e18a033bSKonstantin Ananyev}
242e18a033bSKonstantin Ananyev
243e18a033bSKonstantin Ananyev
244e18a033bSKonstantin Ananyevstatic void ngx_libc_cdecl
245e18a033bSKonstantin Ananyevngx_regex_free(void *p)
246e18a033bSKonstantin Ananyev{
247e18a033bSKonstantin Ananyev    return;
248e18a033bSKonstantin Ananyev}
249e18a033bSKonstantin Ananyev
250e18a033bSKonstantin Ananyev
251e18a033bSKonstantin Ananyev#if (NGX_HAVE_PCRE_JIT)
252e18a033bSKonstantin Ananyev
253e18a033bSKonstantin Ananyevstatic void
254e18a033bSKonstantin Ananyevngx_pcre_free_studies(void *data)
255e18a033bSKonstantin Ananyev{
256e18a033bSKonstantin Ananyev    ngx_list_t *studies = data;
257e18a033bSKonstantin Ananyev
258e18a033bSKonstantin Ananyev    ngx_uint_t        i;
259e18a033bSKonstantin Ananyev    ngx_list_part_t  *part;
260e18a033bSKonstantin Ananyev    ngx_regex_elt_t  *elts;
261e18a033bSKonstantin Ananyev
262e18a033bSKonstantin Ananyev    part = &studies->part;
263e18a033bSKonstantin Ananyev    elts = part->elts;
264e18a033bSKonstantin Ananyev
265e18a033bSKonstantin Ananyev    for (i = 0 ; /* void */ ; i++) {
266e18a033bSKonstantin Ananyev
267e18a033bSKonstantin Ananyev        if (i >= part->nelts) {
268e18a033bSKonstantin Ananyev            if (part->next == NULL) {
269e18a033bSKonstantin Ananyev                break;
270e18a033bSKonstantin Ananyev            }
271e18a033bSKonstantin Ananyev
272e18a033bSKonstantin Ananyev            part = part->next;
273e18a033bSKonstantin Ananyev            elts = part->elts;
274e18a033bSKonstantin Ananyev            i = 0;
275e18a033bSKonstantin Ananyev        }
276e18a033bSKonstantin Ananyev
277e18a033bSKonstantin Ananyev        if (elts[i].regex->extra != NULL) {
278e18a033bSKonstantin Ananyev            pcre_free_study(elts[i].regex->extra);
279e18a033bSKonstantin Ananyev        }
280e18a033bSKonstantin Ananyev    }
281e18a033bSKonstantin Ananyev}
282e18a033bSKonstantin Ananyev
283e18a033bSKonstantin Ananyev#endif
284e18a033bSKonstantin Ananyev
285e18a033bSKonstantin Ananyev
286e18a033bSKonstantin Ananyevstatic ngx_int_t
287e18a033bSKonstantin Ananyevngx_regex_module_init(ngx_cycle_t *cycle)
288e18a033bSKonstantin Ananyev{
289e18a033bSKonstantin Ananyev    int               opt;
290e18a033bSKonstantin Ananyev    const char       *errstr;
291e18a033bSKonstantin Ananyev    ngx_uint_t        i;
292e18a033bSKonstantin Ananyev    ngx_list_part_t  *part;
293e18a033bSKonstantin Ananyev    ngx_regex_elt_t  *elts;
294e18a033bSKonstantin Ananyev
295e18a033bSKonstantin Ananyev    opt = 0;
296e18a033bSKonstantin Ananyev
297e18a033bSKonstantin Ananyev#if (NGX_HAVE_PCRE_JIT)
298e18a033bSKonstantin Ananyev    {
299e18a033bSKonstantin Ananyev    ngx_regex_conf_t    *rcf;
300e18a033bSKonstantin Ananyev    ngx_pool_cleanup_t  *cln;
301e18a033bSKonstantin Ananyev
302e18a033bSKonstantin Ananyev    rcf = (ngx_regex_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_regex_module);
303e18a033bSKonstantin Ananyev
304e18a033bSKonstantin Ananyev    if (rcf->pcre_jit) {
305e18a033bSKonstantin Ananyev        opt = PCRE_STUDY_JIT_COMPILE;
306e18a033bSKonstantin Ananyev
307e18a033bSKonstantin Ananyev        /*
308e18a033bSKonstantin Ananyev         * The PCRE JIT compiler uses mmap for its executable codes, so we
309e18a033bSKonstantin Ananyev         * have to explicitly call the pcre_free_study() function to free
310e18a033bSKonstantin Ananyev         * this memory.
311e18a033bSKonstantin Ananyev         */
312e18a033bSKonstantin Ananyev
313e18a033bSKonstantin Ananyev        cln = ngx_pool_cleanup_add(cycle->pool, 0);
314e18a033bSKonstantin Ananyev        if (cln == NULL) {
315e18a033bSKonstantin Ananyev            return NGX_ERROR;
316e18a033bSKonstantin Ananyev        }
317e18a033bSKonstantin Ananyev
318e18a033bSKonstantin Ananyev        cln->handler = ngx_pcre_free_studies;
319e18a033bSKonstantin Ananyev        cln->data = ngx_pcre_studies;
320e18a033bSKonstantin Ananyev    }
321e18a033bSKonstantin Ananyev    }
322e18a033bSKonstantin Ananyev#endif
323e18a033bSKonstantin Ananyev
324e18a033bSKonstantin Ananyev    ngx_regex_malloc_init(cycle->pool);
325e18a033bSKonstantin Ananyev
326e18a033bSKonstantin Ananyev    part = &ngx_pcre_studies->part;
327e18a033bSKonstantin Ananyev    elts = part->elts;
328e18a033bSKonstantin Ananyev
329e18a033bSKonstantin Ananyev    for (i = 0 ; /* void */ ; i++) {
330e18a033bSKonstantin Ananyev
331e18a033bSKonstantin Ananyev        if (i >= part->nelts) {
332e18a033bSKonstantin Ananyev            if (part->next == NULL) {
333e18a033bSKonstantin Ananyev                break;
334e18a033bSKonstantin Ananyev            }
335e18a033bSKonstantin Ananyev
336e18a033bSKonstantin Ananyev            part = part->next;
337e18a033bSKonstantin Ananyev            elts = part->elts;
338e18a033bSKonstantin Ananyev            i = 0;
339e18a033bSKonstantin Ananyev        }
340e18a033bSKonstantin Ananyev
341e18a033bSKonstantin Ananyev        elts[i].regex->extra = pcre_study(elts[i].regex->code, opt, &errstr);
342e18a033bSKonstantin Ananyev
343e18a033bSKonstantin Ananyev        if (errstr != NULL) {
344e18a033bSKonstantin Ananyev            ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
345e18a033bSKonstantin Ananyev                          "pcre_study() failed: %s in \"%s\"",
346e18a033bSKonstantin Ananyev                          errstr, elts[i].name);
347e18a033bSKonstantin Ananyev        }
348e18a033bSKonstantin Ananyev
349e18a033bSKonstantin Ananyev#if (NGX_HAVE_PCRE_JIT)
350e18a033bSKonstantin Ananyev        if (opt & PCRE_STUDY_JIT_COMPILE) {
351e18a033bSKonstantin Ananyev            int jit, n;
352e18a033bSKonstantin Ananyev
353e18a033bSKonstantin Ananyev            jit = 0;
354e18a033bSKonstantin Ananyev            n = pcre_fullinfo(elts[i].regex->code, elts[i].regex->extra,
355e18a033bSKonstantin Ananyev                              PCRE_INFO_JIT, &jit);
356e18a033bSKonstantin Ananyev
357e18a033bSKonstantin Ananyev            if (n != 0 || jit != 1) {
358e18a033bSKonstantin Ananyev                ngx_log_error(NGX_LOG_INFO, cycle->log, 0,
359e18a033bSKonstantin Ananyev                              "JIT compiler does not support pattern: \"%s\"",
360e18a033bSKonstantin Ananyev                              elts[i].name);
361e18a033bSKonstantin Ananyev            }
362e18a033bSKonstantin Ananyev        }
363e18a033bSKonstantin Ananyev#endif
364e18a033bSKonstantin Ananyev    }
365e18a033bSKonstantin Ananyev
366e18a033bSKonstantin Ananyev    ngx_regex_malloc_done();
367e18a033bSKonstantin Ananyev
368e18a033bSKonstantin Ananyev    ngx_pcre_studies = NULL;
369e18a033bSKonstantin Ananyev
370e18a033bSKonstantin Ananyev    return NGX_OK;
371e18a033bSKonstantin Ananyev}
372e18a033bSKonstantin Ananyev
373e18a033bSKonstantin Ananyev
374e18a033bSKonstantin Ananyevstatic void *
375e18a033bSKonstantin Ananyevngx_regex_create_conf(ngx_cycle_t *cycle)
376e18a033bSKonstantin Ananyev{
377e18a033bSKonstantin Ananyev    ngx_regex_conf_t  *rcf;
378e18a033bSKonstantin Ananyev
379e18a033bSKonstantin Ananyev    rcf = ngx_pcalloc(cycle->pool, sizeof(ngx_regex_conf_t));
380e18a033bSKonstantin Ananyev    if (rcf == NULL) {
381e18a033bSKonstantin Ananyev        return NULL;
382e18a033bSKonstantin Ananyev    }
383e18a033bSKonstantin Ananyev
384e18a033bSKonstantin Ananyev    rcf->pcre_jit = NGX_CONF_UNSET;
385e18a033bSKonstantin Ananyev
386e18a033bSKonstantin Ananyev    ngx_pcre_studies = ngx_list_create(cycle->pool, 8, sizeof(ngx_regex_elt_t));
387e18a033bSKonstantin Ananyev    if (ngx_pcre_studies == NULL) {
388e18a033bSKonstantin Ananyev        return NULL;
389e18a033bSKonstantin Ananyev    }
390e18a033bSKonstantin Ananyev
391e18a033bSKonstantin Ananyev    return rcf;
392e18a033bSKonstantin Ananyev}
393e18a033bSKonstantin Ananyev
394e18a033bSKonstantin Ananyev
395e18a033bSKonstantin Ananyevstatic char *
396e18a033bSKonstantin Ananyevngx_regex_init_conf(ngx_cycle_t *cycle, void *conf)
397e18a033bSKonstantin Ananyev{
398e18a033bSKonstantin Ananyev    ngx_regex_conf_t *rcf = conf;
399e18a033bSKonstantin Ananyev
400e18a033bSKonstantin Ananyev    ngx_conf_init_value(rcf->pcre_jit, 0);
401e18a033bSKonstantin Ananyev
402e18a033bSKonstantin Ananyev    return NGX_CONF_OK;
403e18a033bSKonstantin Ananyev}
404e18a033bSKonstantin Ananyev
405e18a033bSKonstantin Ananyev
406e18a033bSKonstantin Ananyevstatic char *
407e18a033bSKonstantin Ananyevngx_regex_pcre_jit(ngx_conf_t *cf, void *post, void *data)
408e18a033bSKonstantin Ananyev{
409e18a033bSKonstantin Ananyev    ngx_flag_t  *fp = data;
410e18a033bSKonstantin Ananyev
411e18a033bSKonstantin Ananyev    if (*fp == 0) {
412e18a033bSKonstantin Ananyev        return NGX_CONF_OK;
413e18a033bSKonstantin Ananyev    }
414e18a033bSKonstantin Ananyev
415e18a033bSKonstantin Ananyev#if (NGX_HAVE_PCRE_JIT)
416e18a033bSKonstantin Ananyev    {
417e18a033bSKonstantin Ananyev    int  jit, r;
418e18a033bSKonstantin Ananyev
419e18a033bSKonstantin Ananyev    jit = 0;
420e18a033bSKonstantin Ananyev    r = pcre_config(PCRE_CONFIG_JIT, &jit);
421e18a033bSKonstantin Ananyev
422