1 
2 /*
3  * Copyright (C) Yichun Zhang (agentzh)
4  */
5 
6 
7 #ifndef DDEBUG
8 #define DDEBUG 0
9 #endif
10 #include "ddebug.h"
11 
12 
13 #include "ngx_http_array_var_util.h"
14 
15 
16 static ngx_int_t ngx_http_array_var_variable_not_found(ngx_http_request_t *r,
17     ngx_http_variable_value_t *v, uintptr_t data);
18 
19 
20 /* Modified from the ngx_strlcasestrn function in ngx_string.h
21  * Copyright (C) by Igor Sysoev */
22 u_char *
ngx_http_array_var_strlstrn(u_char * s1,u_char * last,u_char * s2,size_t n)23 ngx_http_array_var_strlstrn(u_char *s1, u_char *last, u_char *s2, size_t n)
24 {
25     ngx_uint_t  c1, c2;
26 
27     c2 = (ngx_uint_t) *s2++;
28     last -= n;
29 
30     do {
31         do {
32             if (s1 >= last) {
33                 return NULL;
34             }
35 
36             c1 = (ngx_uint_t) *s1++;
37 
38         } while (c1 != c2);
39 
40     } while (ngx_strncmp(s1, s2, n) != 0);
41 
42     return --s1;
43 }
44 
45 
46 ndk_set_var_value_pt
ngx_http_array_var_get_func_from_cmd(u_char * name,size_t name_len)47 ngx_http_array_var_get_func_from_cmd(u_char *name, size_t name_len)
48 {
49     ndk_set_var_t           *filter;
50     ngx_uint_t               i;
51     ngx_module_t           **modules;
52     ngx_module_t            *module;
53     ngx_command_t           *cmd;
54 
55 #if defined(nginx_version) && nginx_version >= 1009011
56     modules = ngx_cycle->modules;
57 #else
58     modules = ngx_modules;
59 #endif
60 
61     for (i = 0; modules[i]; i++) {
62         module = modules[i];
63         if (module->type != NGX_HTTP_MODULE) {
64             continue;
65         }
66 
67         cmd = modules[i]->commands;
68         if (cmd == NULL) {
69             continue;
70         }
71 
72         for ( /* void */ ; cmd->name.len; cmd++) {
73             if (cmd->set != ndk_set_var_value) {
74                 continue;
75             }
76 
77             filter = cmd->post;
78             if (filter == NULL) {
79                 continue;
80             }
81 
82             if (cmd->name.len != name_len
83                 || ngx_strncmp(cmd->name.data, name, name_len) != 0)
84             {
85                 continue;
86             }
87 
88             return (ndk_set_var_value_pt) filter->func;
89         }
90     }
91 
92     return NULL;
93 }
94 
95 
96 ngx_int_t
ngx_http_array_var_add_variable(ngx_conf_t * cf,ngx_str_t * name)97 ngx_http_array_var_add_variable(ngx_conf_t *cf, ngx_str_t *name)
98 {
99     ngx_http_variable_t         *v;
100 
101     v = ngx_http_add_variable(cf, name, NGX_HTTP_VAR_CHANGEABLE);
102     if (v == NULL) {
103         return NGX_ERROR;
104     }
105 
106     v->get_handler = ngx_http_array_var_variable_not_found;
107 
108     return ngx_http_get_variable_index(cf, name);
109 }
110 
111 
112 static ngx_int_t
ngx_http_array_var_variable_not_found(ngx_http_request_t * r,ngx_http_variable_value_t * v,uintptr_t data)113 ngx_http_array_var_variable_not_found(ngx_http_request_t *r,
114     ngx_http_variable_value_t *v, uintptr_t data)
115 {
116     v->not_found = 1;
117     return NGX_OK;
118 }
119