xref: /unit/src/nxt_conf_validation.c (revision 216:07257705cd64)
1 
2 /*
3  * Copyright (C) Valentin V. Bartenev
4  * Copyright (C) NGINX, Inc.
5  */
6 
7 #include <nxt_main.h>
8 #include <nxt_conf.h>
9 #include <nxt_application.h>
10 
11 
12 typedef struct {
13     nxt_str_t   name;
14     nxt_uint_t  type;
15     nxt_int_t   (*validator)(nxt_conf_value_t *conf, nxt_conf_value_t *value,
16                              void *data);
17     void        *data;
18 } nxt_conf_vldt_object_t;
19 
20 
21 typedef nxt_int_t (*nxt_conf_vldt_member_t)(nxt_conf_value_t *conf,
22                                             nxt_str_t *name,
23                                             nxt_conf_value_t *value);
24 
25 static nxt_int_t nxt_conf_vldt_listener(nxt_conf_value_t *conf, nxt_str_t *name,
26     nxt_conf_value_t *value);
27 static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_value_t *conf,
28     nxt_conf_value_t *value, void *data);
29 static nxt_int_t nxt_conf_vldt_app(nxt_conf_value_t *conf, nxt_str_t *name,
30     nxt_conf_value_t *value);
31 static nxt_int_t nxt_conf_vldt_object(nxt_conf_value_t *conf,
32     nxt_conf_value_t *value, void *data);
33 static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_value_t *conf,
34     nxt_conf_value_t *value, void *data);
35 
36 
37 static nxt_conf_vldt_object_t  nxt_conf_vldt_root_members[] = {
38     { nxt_string("listeners"),
39       NXT_CONF_OBJECT,
40       &nxt_conf_vldt_object_iterator,
41       (void *) &nxt_conf_vldt_listener },
42 
43     { nxt_string("applications"),
44       NXT_CONF_OBJECT,
45       &nxt_conf_vldt_object_iterator,
46       (void *) &nxt_conf_vldt_app },
47 
48     { nxt_null_string, 0, NULL, NULL }
49 };
50 
51 
52 static nxt_conf_vldt_object_t  nxt_conf_vldt_listener_members[] = {
53     { nxt_string("application"),
54       NXT_CONF_STRING,
55       &nxt_conf_vldt_app_name,
56       NULL },
57 
58     { nxt_null_string, 0, NULL, NULL }
59 };
60 
61 
62 static nxt_conf_vldt_object_t  nxt_conf_vldt_python_members[] = {
63     { nxt_string("type"),
64       NXT_CONF_STRING,
65       NULL,
66       NULL },
67 
68     { nxt_string("workers"),
69       NXT_CONF_INTEGER,
70       NULL,
71       NULL },
72 
73     { nxt_string("user"),
74       NXT_CONF_STRING,
75       NULL,
76       NULL },
77 
78     { nxt_string("group"),
79       NXT_CONF_STRING,
80       NULL,
81       NULL },
82 
83     { nxt_string("path"),
84       NXT_CONF_STRING,
85       NULL,
86       NULL },
87 
88     { nxt_string("module"),
89       NXT_CONF_STRING,
90       NULL,
91       NULL },
92 
93     { nxt_null_string, 0, NULL, NULL }
94 };
95 
96 
97 static nxt_conf_vldt_object_t  nxt_conf_vldt_php_members[] = {
98     { nxt_string("type"),
99       NXT_CONF_STRING,
100       NULL,
101       NULL },
102 
103     { nxt_string("workers"),
104       NXT_CONF_INTEGER,
105       NULL,
106       NULL },
107 
108     { nxt_string("user"),
109       NXT_CONF_STRING,
110       NULL,
111       NULL },
112 
113     { nxt_string("group"),
114       NXT_CONF_STRING,
115       NULL,
116       NULL },
117 
118     { nxt_string("root"),
119       NXT_CONF_STRING,
120       NULL,
121       NULL },
122 
123     { nxt_string("script"),
124       NXT_CONF_STRING,
125       NULL,
126       NULL },
127 
128     { nxt_string("index"),
129       NXT_CONF_STRING,
130       NULL,
131       NULL },
132 
133     { nxt_null_string, 0, NULL, NULL }
134 };
135 
136 
137 static nxt_conf_vldt_object_t  nxt_conf_vldt_go_members[] = {
138     { nxt_string("type"),
139       NXT_CONF_STRING,
140       NULL,
141       NULL },
142 
143     { nxt_string("workers"),
144       NXT_CONF_INTEGER,
145       NULL,
146       NULL },
147 
148     { nxt_string("user"),
149       NXT_CONF_STRING,
150       NULL,
151       NULL },
152 
153     { nxt_string("group"),
154       NXT_CONF_STRING,
155       NULL,
156       NULL },
157 
158     { nxt_string("executable"),
159       NXT_CONF_STRING,
160       NULL,
161       NULL },
162 
163     { nxt_null_string, 0, NULL, NULL }
164 };
165 
166 
167 nxt_int_t
168 nxt_conf_validate(nxt_conf_value_t *value)
169 {
170     if (nxt_conf_type(value) != NXT_CONF_OBJECT) {
171         return NXT_ERROR;
172     }
173 
174     return nxt_conf_vldt_object(value, value, nxt_conf_vldt_root_members);
175 }
176 
177 
178 static nxt_int_t
179 nxt_conf_vldt_listener(nxt_conf_value_t *conf, nxt_str_t *name,
180     nxt_conf_value_t *value)
181 {
182     return nxt_conf_vldt_object(conf, value, nxt_conf_vldt_listener_members);
183 }
184 
185 
186 static nxt_int_t
187 nxt_conf_vldt_app_name(nxt_conf_value_t *conf, nxt_conf_value_t *value,
188     void *data)
189 {
190     nxt_str_t         name;
191     nxt_conf_value_t  *apps, *app;
192 
193     static nxt_str_t  apps_str = nxt_string("applications");
194 
195     apps = nxt_conf_get_object_member(conf, &apps_str, NULL);
196 
197     if (nxt_slow_path(apps == NULL)) {
198         return NXT_ERROR;
199     }
200 
201     nxt_conf_get_string(value, &name);
202 
203     app = nxt_conf_get_object_member(apps, &name, NULL);
204 
205     if (nxt_slow_path(app == NULL)) {
206         return NXT_ERROR;
207     }
208 
209     return NXT_OK;
210 }
211 
212 
213 static nxt_int_t
214 nxt_conf_vldt_app(nxt_conf_value_t *conf, nxt_str_t *name,
215     nxt_conf_value_t *value)
216 {
217     nxt_str_t              type;
218     nxt_uint_t             n;
219     nxt_thread_t           *thread;
220     nxt_conf_value_t       *type_value;
221     nxt_app_lang_module_t  *lang;
222 
223     static nxt_str_t  type_str = nxt_string("type");
224 
225     static void  *members[] = {
226         nxt_conf_vldt_python_members,
227         nxt_conf_vldt_php_members,
228         nxt_conf_vldt_go_members,
229     };
230 
231     type_value = nxt_conf_get_object_member(value, &type_str, NULL);
232 
233     if (nxt_slow_path(type_value == NULL)) {
234         return NXT_ERROR;
235     }
236 
237     if (nxt_conf_type(type_value) != NXT_CONF_STRING) {
238         return NXT_ERROR;
239     }
240 
241     nxt_conf_get_string(type_value, &type);
242 
243     thread = nxt_thread();
244 
245     lang = nxt_app_lang_module(thread->runtime, &type);
246     if (lang == NULL) {
247         return NXT_ERROR;
248     }
249 
250     n = nxt_app_parse_type(&lang->type);
251     if (n != NXT_APP_UNKNOWN) {
252         return nxt_conf_vldt_object(conf, value, members[n]);
253     }
254 
255     return NXT_ERROR;
256 }
257 
258 
259 static nxt_int_t
260 nxt_conf_vldt_object(nxt_conf_value_t *conf, nxt_conf_value_t *value,
261     void *data)
262 {
263     uint32_t                index;
264     nxt_str_t               name;
265     nxt_conf_value_t        *member;
266     nxt_conf_vldt_object_t  *vldt;
267 
268     index = 0;
269 
270     for ( ;; ) {
271         member = nxt_conf_next_object_member(value, &name, &index);
272 
273         if (member == NULL) {
274             return NXT_OK;
275         }
276 
277         vldt = data;
278 
279         for ( ;; ) {
280             if (vldt->name.length == 0) {
281                 return NXT_ERROR;
282             }
283 
284             if (!nxt_strstr_eq(&vldt->name, &name)) {
285                 vldt++;
286                 continue;
287             }
288 
289             if (nxt_conf_type(member) != vldt->type) {
290                 return NXT_ERROR;
291             }
292 
293             if (vldt->validator != NULL
294                 && vldt->validator(conf, member, vldt->data) != NXT_OK)
295             {
296                 return NXT_ERROR;
297             }
298 
299             break;
300         }
301     }
302 }
303 
304 
305 static nxt_int_t
306 nxt_conf_vldt_object_iterator(nxt_conf_value_t *conf, nxt_conf_value_t *value,
307     void *data)
308 {
309     uint32_t                index;
310     nxt_str_t               name;
311     nxt_conf_value_t        *member;
312     nxt_conf_vldt_member_t  validator;
313 
314     validator = (nxt_conf_vldt_member_t) data;
315     index = 0;
316 
317     for ( ;; ) {
318         member = nxt_conf_next_object_member(value, &name, &index);
319 
320         if (member == NULL) {
321             return NXT_OK;
322         }
323 
324         if (validator(conf, &name, member) != NXT_OK) {
325             return NXT_ERROR;
326         }
327     }
328 }
329