Branch data Line data Source code
1 : : #define DDEBUG 0
2 : : #include "ddebug.h"
3 : :
4 : : #include "ngx_http_echo_handler.h"
5 : : #include "ngx_http_echo_filter.h"
6 : : #include "ngx_http_echo_request_info.h"
7 : :
8 : : #include <nginx.h>
9 : : #include <ngx_config.h>
10 : : #include <ngx_log.h>
11 : :
12 : : /* config init handler */
13 : : static void * ngx_http_echo_create_conf(ngx_conf_t *cf);
14 : :
15 : : /* config directive handlers */
16 : : static char * ngx_http_echo_echo(ngx_conf_t *cf, ngx_command_t *cmd,
17 : : void *conf);
18 : :
19 : : static char * ngx_http_echo_echo_request_body(ngx_conf_t *cf,
20 : : ngx_command_t *cmd, void *conf);
21 : :
22 : : static char * ngx_http_echo_echo_sleep(ngx_conf_t *cf, ngx_command_t *cmd,
23 : : void *conf);
24 : :
25 : : static char * ngx_http_echo_echo_flush(ngx_conf_t *cf, ngx_command_t *cmd,
26 : : void *conf);
27 : :
28 : : static char * ngx_http_echo_echo_blocking_sleep(ngx_conf_t *cf,
29 : : ngx_command_t *cmd, void *conf);
30 : :
31 : : static char * ngx_http_echo_echo_reset_timer(ngx_conf_t *cf,
32 : : ngx_command_t *cmd, void *conf);
33 : :
34 : : static char * ngx_http_echo_echo_before_body(ngx_conf_t *cf,
35 : : ngx_command_t *cmd, void *conf);
36 : :
37 : : static char * ngx_http_echo_echo_after_body(ngx_conf_t *cf,
38 : : ngx_command_t *cmd, void *conf);
39 : :
40 : : static char * ngx_http_echo_echo_location_async(ngx_conf_t *cf,
41 : : ngx_command_t *cmd, void *conf);
42 : :
43 : : static char * ngx_http_echo_echo_location(ngx_conf_t *cf,
44 : : ngx_command_t *cmd, void *conf);
45 : :
46 : : static char * ngx_http_echo_echo_subrequest_async(ngx_conf_t *cf,
47 : : ngx_command_t *cmd, void *conf);
48 : :
49 : : static char * ngx_http_echo_echo_subrequest(ngx_conf_t *cf,
50 : : ngx_command_t *cmd, void *conf);
51 : :
52 : : static char * ngx_http_echo_echo_duplicate(ngx_conf_t *cf,
53 : : ngx_command_t *cmd, void *conf);
54 : :
55 : : static char * ngx_http_echo_echo_read_request_body(ngx_conf_t *cf,
56 : : ngx_command_t *cmd, void *conf);
57 : :
58 : : static char * ngx_http_echo_echo_foreach_split(ngx_conf_t *cf,
59 : : ngx_command_t *cmd, void *conf);
60 : :
61 : : static char * ngx_http_echo_echo_end(ngx_conf_t *cf,
62 : : ngx_command_t *cmd, void *conf);
63 : :
64 : : static char * ngx_http_echo_echo_abort_parent(ngx_conf_t *cf,
65 : : ngx_command_t *cmd, void *conf);
66 : :
67 : : static char * ngx_http_echo_echo_exec(ngx_conf_t *cf,
68 : : ngx_command_t *cmd, void *conf);
69 : :
70 : : static char * ngx_http_echo_helper(ngx_http_echo_opcode_t opcode,
71 : : ngx_http_echo_cmd_category_t cat,
72 : : ngx_conf_t *cf, ngx_command_t *cmd, void* conf);
73 : :
74 : :
75 : : static ngx_http_module_t ngx_http_echo_module_ctx = {
76 : : /* TODO we could add our own variables here... */
77 : : ngx_http_echo_handler_init, /* preconfiguration */
78 : : ngx_http_echo_filter_init, /* postconfiguration */
79 : :
80 : : NULL, /* create main configuration */
81 : : NULL, /* init main configuration */
82 : :
83 : : NULL, /* create server configuration */
84 : : NULL, /* merge server configuration */
85 : :
86 : : ngx_http_echo_create_conf, /* create location configuration */
87 : : NULL /* merge location configuration */
88 : : };
89 : :
90 : :
91 : : static ngx_command_t ngx_http_echo_commands[] = {
92 : :
93 : : { ngx_string("echo"),
94 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_ANY,
95 : : ngx_http_echo_echo,
96 : : NGX_HTTP_LOC_CONF_OFFSET,
97 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
98 : : NULL },
99 : :
100 : : { ngx_string("echo_request_body"),
101 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_NOARGS,
102 : : ngx_http_echo_echo_request_body,
103 : : NGX_HTTP_LOC_CONF_OFFSET,
104 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
105 : : NULL },
106 : :
107 : : { ngx_string("echo_sleep"),
108 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
109 : : ngx_http_echo_echo_sleep,
110 : : NGX_HTTP_LOC_CONF_OFFSET,
111 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
112 : : NULL },
113 : :
114 : : { ngx_string("echo_flush"),
115 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_NOARGS,
116 : : ngx_http_echo_echo_flush,
117 : : NGX_HTTP_LOC_CONF_OFFSET,
118 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
119 : : NULL },
120 : :
121 : : { ngx_string("echo_blocking_sleep"),
122 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
123 : : ngx_http_echo_echo_blocking_sleep,
124 : : NGX_HTTP_LOC_CONF_OFFSET,
125 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
126 : : NULL },
127 : :
128 : : { ngx_string("echo_reset_timer"),
129 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_NOARGS,
130 : : ngx_http_echo_echo_reset_timer,
131 : : NGX_HTTP_LOC_CONF_OFFSET,
132 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
133 : : NULL },
134 : :
135 : : { ngx_string("echo_before_body"),
136 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_ANY,
137 : : ngx_http_echo_echo_before_body,
138 : : NGX_HTTP_LOC_CONF_OFFSET,
139 : : offsetof(ngx_http_echo_loc_conf_t, before_body_cmds),
140 : : NULL },
141 : :
142 : : { ngx_string("echo_after_body"),
143 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_ANY,
144 : : ngx_http_echo_echo_after_body,
145 : : NGX_HTTP_LOC_CONF_OFFSET,
146 : : offsetof(ngx_http_echo_loc_conf_t, after_body_cmds),
147 : : NULL },
148 : :
149 : : { ngx_string("echo_location_async"),
150 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE12,
151 : : ngx_http_echo_echo_location_async,
152 : : NGX_HTTP_LOC_CONF_OFFSET,
153 : : 0,
154 : : NULL },
155 : :
156 : : { ngx_string("echo_location"),
157 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE12,
158 : : ngx_http_echo_echo_location,
159 : : NGX_HTTP_LOC_CONF_OFFSET,
160 : : 0,
161 : : NULL },
162 : :
163 : : { ngx_string("echo_subrequest_async"),
164 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_2MORE,
165 : : ngx_http_echo_echo_subrequest_async,
166 : : NGX_HTTP_LOC_CONF_OFFSET,
167 : : 0,
168 : : NULL },
169 : :
170 : : { ngx_string("echo_subrequest"),
171 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_2MORE,
172 : : ngx_http_echo_echo_subrequest,
173 : : NGX_HTTP_LOC_CONF_OFFSET,
174 : : 0,
175 : : NULL },
176 : :
177 : : { ngx_string("echo_duplicate"),
178 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_2MORE,
179 : : ngx_http_echo_echo_duplicate,
180 : : NGX_HTTP_LOC_CONF_OFFSET,
181 : : 0,
182 : : NULL },
183 : :
184 : : { ngx_string("echo_read_request_body"),
185 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_NOARGS,
186 : : ngx_http_echo_echo_read_request_body,
187 : : NGX_HTTP_LOC_CONF_OFFSET,
188 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
189 : : NULL },
190 : :
191 : : { ngx_string("echo_foreach_split"),
192 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_2MORE,
193 : : ngx_http_echo_echo_foreach_split,
194 : : NGX_HTTP_LOC_CONF_OFFSET,
195 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
196 : : NULL },
197 : :
198 : : { ngx_string("echo_end"),
199 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_NOARGS,
200 : : ngx_http_echo_echo_end,
201 : : NGX_HTTP_LOC_CONF_OFFSET,
202 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
203 : : NULL },
204 : :
205 : : { ngx_string("echo_abort_parent"),
206 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_NOARGS,
207 : : ngx_http_echo_echo_abort_parent,
208 : : NGX_HTTP_LOC_CONF_OFFSET,
209 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
210 : : NULL },
211 : :
212 : : { ngx_string("echo_exec"),
213 : : NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE12,
214 : : ngx_http_echo_echo_exec,
215 : : NGX_HTTP_LOC_CONF_OFFSET,
216 : : offsetof(ngx_http_echo_loc_conf_t, handler_cmds),
217 : : NULL },
218 : :
219 : : ngx_null_command
220 : : };
221 : :
222 : :
223 : : ngx_module_t ngx_http_echo_module = {
224 : : NGX_MODULE_V1,
225 : : &ngx_http_echo_module_ctx, /* module context */
226 : : ngx_http_echo_commands, /* module directives */
227 : : NGX_HTTP_MODULE, /* module type */
228 : : NULL, /* init master */
229 : : NULL, /* init module */
230 : : NULL, /* init process */
231 : : NULL, /* init thread */
232 : : NULL, /* exit thread */
233 : : NULL, /* exit process */
234 : : NULL, /* exit master */
235 : : NGX_MODULE_V1_PADDING
236 : : };
237 : :
238 : :
239 : : static void *
240 : 360 : ngx_http_echo_create_conf(ngx_conf_t *cf)
241 : : {
242 : : ngx_http_echo_loc_conf_t *conf;
243 : 360 : conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_echo_loc_conf_t));
244 [ - + ]: 360 : if (conf == NULL) {
245 : 0 : return NGX_CONF_ERROR;
246 : : }
247 : :
248 : 360 : return conf;
249 : : }
250 : :
251 : :
252 : : static char *
253 : 72 : ngx_http_echo_helper(ngx_http_echo_opcode_t opcode,
254 : : ngx_http_echo_cmd_category_t cat,
255 : : ngx_conf_t *cf, ngx_command_t *cmd, void* conf)
256 : : {
257 : : ngx_http_core_loc_conf_t *clcf;
258 : : /* ngx_http_echo_loc_conf_t *ulcf = conf; */
259 : : ngx_array_t **args_ptr;
260 : : ngx_http_script_compile_t sc;
261 : : ngx_str_t *raw_args;
262 : : ngx_http_echo_arg_template_t *arg;
263 : : ngx_array_t **cmds_ptr;
264 : : ngx_http_echo_cmd_t *echo_cmd;
265 : : ngx_uint_t i, n;
266 : :
267 : : /* cmds_ptr points to ngx_http_echo_loc_conf_t's
268 : : * handler_cmds, before_body_cmds, or after_body_cmds
269 : : * array, depending on the actual offset */
270 : 72 : cmds_ptr = (ngx_array_t**)(((u_char*)conf) + cmd->offset);
271 : :
272 [ + + ]: 72 : if (*cmds_ptr == NULL) {
273 : 63 : *cmds_ptr = ngx_array_create(cf->pool, 1,
274 : : sizeof(ngx_http_echo_cmd_t));
275 : :
276 [ - + ]: 63 : if (*cmds_ptr == NULL) {
277 : 0 : return NGX_CONF_ERROR;
278 : : }
279 : :
280 [ + - ]: 63 : if (cat == echo_handler_cmd) {
281 : : dd("registering the content handler");
282 : : /* register the content handler */
283 : 63 : clcf = ngx_http_conf_get_module_loc_conf(cf,
284 : : ngx_http_core_module);
285 : :
286 : : dd("registering the content handler (2)");
287 : 63 : clcf->handler = ngx_http_echo_handler;
288 : :
289 : : } else {
290 : : dd("filter used = 1");
291 : 0 : ngx_http_echo_filter_used = 1;
292 : : }
293 : : }
294 : :
295 : 72 : echo_cmd = ngx_array_push(*cmds_ptr);
296 : :
297 [ - + ]: 72 : if (echo_cmd == NULL) {
298 : 0 : return NGX_CONF_ERROR;
299 : : }
300 : :
301 : 72 : echo_cmd->opcode = opcode;
302 : :
303 : 72 : args_ptr = &echo_cmd->args;
304 : 72 : *args_ptr = ngx_array_create(cf->pool, 1,
305 : : sizeof(ngx_http_echo_arg_template_t));
306 : :
307 [ - + ]: 72 : if (*args_ptr == NULL) {
308 : 0 : return NGX_CONF_ERROR;
309 : : }
310 : :
311 : 72 : raw_args = cf->args->elts;
312 : :
313 : : /* we skip the first arg and start from the second */
314 : :
315 [ + + ]: 145 : for (i = 1 ; i < cf->args->nelts; i++) {
316 : 73 : arg = ngx_array_push(*args_ptr);
317 : :
318 [ - + ]: 73 : if (arg == NULL) {
319 : 0 : return NGX_CONF_ERROR;
320 : : }
321 : :
322 : 73 : arg->raw_value = raw_args[i];
323 : :
324 : : dd("found raw arg %s", raw_args[i].data);
325 : :
326 : 73 : arg->lengths = NULL;
327 : 73 : arg->values = NULL;
328 : :
329 : 73 : n = ngx_http_script_variables_count(&arg->raw_value);
330 : :
331 [ + + ]: 73 : if (n > 0) {
332 : 31 : ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
333 : :
334 : 31 : sc.cf = cf;
335 : 31 : sc.source = &arg->raw_value;
336 : 31 : sc.lengths = &arg->lengths;
337 : 31 : sc.values = &arg->values;
338 : 31 : sc.variables = n;
339 : 31 : sc.complete_lengths = 1;
340 : 31 : sc.complete_values = 1;
341 : :
342 [ - + ]: 31 : if (ngx_http_script_compile(&sc) != NGX_OK) {
343 : 0 : return NGX_CONF_ERROR;
344 : : }
345 : : }
346 : : } /* end for */
347 : :
348 : 72 : return NGX_CONF_OK;
349 : : }
350 : :
351 : :
352 : : static char *
353 : 66 : ngx_http_echo_echo(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
354 : : {
355 : : dd("in echo_echo...");
356 : 66 : return ngx_http_echo_helper(echo_opcode_echo,
357 : : echo_handler_cmd,
358 : : cf, cmd, conf);
359 : : }
360 : :
361 : :
362 : : static char *
363 : 2 : ngx_http_echo_echo_request_body(ngx_conf_t *cf,
364 : : ngx_command_t *cmd, void *conf)
365 : : {
366 : : dd("in echo_echo_request_body...");
367 : 2 : return ngx_http_echo_helper(echo_opcode_echo_request_body,
368 : : echo_handler_cmd,
369 : : cf, cmd, conf);
370 : : }
371 : :
372 : :
373 : : static char *
374 : 0 : ngx_http_echo_echo_sleep(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
375 : : {
376 : : dd("in echo_sleep...");
377 : 0 : return ngx_http_echo_helper(echo_opcode_echo_sleep,
378 : : echo_handler_cmd,
379 : : cf, cmd, conf);
380 : : }
381 : :
382 : :
383 : : static char *
384 : 0 : ngx_http_echo_echo_flush(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
385 : : {
386 : : dd("in echo_flush...");
387 : 0 : return ngx_http_echo_helper(echo_opcode_echo_flush,
388 : : echo_handler_cmd,
389 : : cf, cmd, conf);
390 : : }
391 : :
392 : :
393 : : static char *
394 : 0 : ngx_http_echo_echo_blocking_sleep(ngx_conf_t *cf, ngx_command_t *cmd,
395 : : void *conf)
396 : : {
397 : : dd("in echo_blocking_sleep...");
398 : 0 : return ngx_http_echo_helper(echo_opcode_echo_blocking_sleep,
399 : : echo_handler_cmd,
400 : : cf, cmd, conf);
401 : : }
402 : :
403 : :
404 : : static char *
405 : 0 : ngx_http_echo_echo_reset_timer(ngx_conf_t *cf,
406 : : ngx_command_t *cmd, void *conf)
407 : : {
408 : 0 : return ngx_http_echo_helper(echo_opcode_echo_reset_timer,
409 : : echo_handler_cmd,
410 : : cf, cmd, conf);
411 : : }
412 : :
413 : :
414 : : static char *
415 : 0 : ngx_http_echo_echo_before_body(ngx_conf_t *cf,
416 : : ngx_command_t *cmd, void *conf)
417 : : {
418 : : dd("processing echo_before_body directive...");
419 : 0 : return ngx_http_echo_helper(echo_opcode_echo_before_body,
420 : : echo_filter_cmd,
421 : : cf, cmd, conf);
422 : : }
423 : :
424 : :
425 : : static char *
426 : 0 : ngx_http_echo_echo_after_body(ngx_conf_t *cf,
427 : : ngx_command_t *cmd, void *conf)
428 : : {
429 : 0 : return ngx_http_echo_helper(echo_opcode_echo_after_body,
430 : : echo_filter_cmd,
431 : : cf, cmd, conf);
432 : : }
433 : :
434 : :
435 : : static char *
436 : 0 : ngx_http_echo_echo_location_async(ngx_conf_t *cf, ngx_command_t *cmd,
437 : : void *conf)
438 : : {
439 : :
440 : : #if ! defined(nginx_version)
441 : :
442 : : ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
443 : : "Directive echo_location_async does not work with nginx "
444 : : "versions ealier than 0.7.46.");
445 : :
446 : : return NGX_CONF_ERROR;
447 : :
448 : : #else
449 : :
450 : 0 : return ngx_http_echo_helper(echo_opcode_echo_location_async,
451 : : echo_handler_cmd,
452 : : cf, cmd, conf);
453 : :
454 : : #endif
455 : :
456 : : }
457 : :
458 : :
459 : : static char *
460 : 2 : ngx_http_echo_echo_location(ngx_conf_t *cf, ngx_command_t *cmd,
461 : : void *conf)
462 : : {
463 : :
464 : : #if ! defined(nginx_version)
465 : :
466 : : ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
467 : : "Directive echo_location does not work with nginx "
468 : : "versions ealier than 0.7.46.");
469 : :
470 : : return NGX_CONF_ERROR;
471 : :
472 : : #else
473 : :
474 : 2 : return ngx_http_echo_helper(echo_opcode_echo_location,
475 : : echo_handler_cmd,
476 : : cf, cmd, conf);
477 : :
478 : : #endif
479 : :
480 : : }
481 : :
482 : :
483 : : static char *
484 : 0 : ngx_http_echo_echo_subrequest_async(ngx_conf_t *cf, ngx_command_t *cmd,
485 : : void *conf)
486 : : {
487 : :
488 : : #if ! defined(nginx_version)
489 : :
490 : : ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
491 : : "Directive echo_subrequest_async does not work with nginx "
492 : : "versions ealier than 0.7.46.");
493 : :
494 : : return NGX_CONF_ERROR;
495 : :
496 : : #else
497 : :
498 : 0 : return ngx_http_echo_helper(echo_opcode_echo_subrequest_async,
499 : : echo_handler_cmd,
500 : : cf, cmd, conf);
501 : :
502 : : #endif
503 : :
504 : : }
505 : :
506 : :
507 : : static char *
508 : 0 : ngx_http_echo_echo_subrequest(ngx_conf_t *cf, ngx_command_t *cmd,
509 : : void *conf)
510 : : {
511 : :
512 : : #if ! defined(nginx_version)
513 : :
514 : : ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
515 : : "Directive echo_subrequest does not work with nginx "
516 : : "versions ealier than 0.7.46.");
517 : :
518 : : return NGX_CONF_ERROR;
519 : :
520 : : #else
521 : :
522 : 0 : return ngx_http_echo_helper(echo_opcode_echo_subrequest,
523 : : echo_handler_cmd,
524 : : cf, cmd, conf);
525 : :
526 : : #endif
527 : :
528 : : }
529 : :
530 : :
531 : : static char *
532 : 0 : ngx_http_echo_echo_duplicate(ngx_conf_t *cf,
533 : : ngx_command_t *cmd, void *conf)
534 : : {
535 : 0 : return ngx_http_echo_helper(echo_opcode_echo_duplicate,
536 : : echo_handler_cmd,
537 : : cf, cmd, conf);
538 : : }
539 : :
540 : :
541 : : static char *
542 : 2 : ngx_http_echo_echo_read_request_body(ngx_conf_t *cf,
543 : : ngx_command_t *cmd, void *conf)
544 : : {
545 : 2 : return ngx_http_echo_helper(
546 : : echo_opcode_echo_read_request_body,
547 : : echo_handler_cmd,
548 : : cf, cmd, conf);
549 : : }
550 : :
551 : :
552 : : static char *
553 : 0 : ngx_http_echo_echo_foreach_split(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
554 : : {
555 : 0 : return ngx_http_echo_helper(
556 : : echo_opcode_echo_foreach_split,
557 : : echo_handler_cmd,
558 : : cf, cmd, conf);
559 : : }
560 : :
561 : :
562 : : static char *
563 : 0 : ngx_http_echo_echo_end(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
564 : : {
565 : 0 : return ngx_http_echo_helper(
566 : : echo_opcode_echo_end,
567 : : echo_handler_cmd,
568 : : cf, cmd, conf);
569 : : }
570 : :
571 : :
572 : : static char *
573 : 0 : ngx_http_echo_echo_abort_parent(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
574 : : {
575 : 0 : return ngx_http_echo_helper(
576 : : echo_opcode_echo_abort_parent,
577 : : echo_handler_cmd,
578 : : cf, cmd, conf);
579 : : }
580 : :
581 : :
582 : : static char *
583 : 0 : ngx_http_echo_echo_exec(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
584 : : {
585 : 0 : return ngx_http_echo_helper(
586 : : echo_opcode_echo_exec,
587 : : echo_handler_cmd,
588 : : cf, cmd, conf);
589 : : }
590 : :
|