Branch data Line data Source code
1 : : #define DDEBUG 0
2 : : #include "ddebug.h"
3 : :
4 : : #include "ngx_http_echo_foreach.h"
5 : : #include "ngx_http_echo_util.h"
6 : :
7 : : #include <nginx.h>
8 : :
9 : : ngx_int_t
10 : 0 : ngx_http_echo_it_variable(ngx_http_request_t *r,
11 : : ngx_http_variable_value_t *v, uintptr_t data)
12 : : {
13 : : ngx_http_echo_ctx_t *ctx;
14 : : ngx_uint_t i;
15 : : ngx_array_t *choices;
16 : : ngx_str_t *choice_elts, *choice;
17 : :
18 : 0 : ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
19 : :
20 [ # # ]: 0 : if (ctx->foreach != NULL) {
21 : 0 : choices = ctx->foreach->choices;
22 : 0 : i = ctx->foreach->next_choice;
23 [ # # ]: 0 : if (i < choices->nelts) {
24 : 0 : choice_elts = choices->elts;
25 : 0 : choice = &choice_elts[i];
26 : :
27 : 0 : v->len = choice->len;
28 : 0 : v->data = choice->data;
29 : 0 : v->valid = 1;
30 : 0 : v->no_cacheable = 1;
31 : 0 : v->not_found = 0;
32 : : }
33 : :
34 : 0 : return NGX_OK;
35 : : }
36 : :
37 : 0 : v->not_found = 1;
38 : :
39 : 0 : return NGX_OK;
40 : : }
41 : :
42 : :
43 : : ngx_int_t
44 : 0 : ngx_http_echo_exec_echo_foreach_split(ngx_http_request_t *r,
45 : : ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
46 : : {
47 : : ngx_http_echo_loc_conf_t *elcf;
48 : : ngx_str_t *delimiter, *compound;
49 : : u_char *pos, *last, *end;
50 : : ngx_str_t *choice;
51 : : ngx_str_t *computed_arg_elts;
52 : : ngx_array_t *cmds;
53 : : ngx_http_echo_cmd_t *cmd;
54 : : ngx_http_echo_cmd_t *cmd_elts;
55 : :
56 [ # # ]: 0 : if (ctx->foreach != NULL) {
57 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
58 : : "Nested echo_foreach not supported yet.");
59 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
60 : : }
61 : :
62 [ # # ]: 0 : if (computed_args->nelts < 2) {
63 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
64 : : "echo_foreach should take at least two arguments. "
65 : : "(if your delimiter starts with \"-\", preceding it with a "
66 : : "\"--\".)");
67 : :
68 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
69 : : }
70 : :
71 : 0 : computed_arg_elts = computed_args->elts;
72 : :
73 : 0 : compound = &computed_arg_elts[1];
74 : :
75 : : dd("HEY coumpound len: %u", compound->len);
76 : :
77 : 0 : ctx->foreach = ngx_palloc(r->pool, sizeof(ngx_http_echo_foreach_ctx_t));
78 : :
79 [ # # ]: 0 : if (ctx->foreach == NULL) {
80 : 0 : return NGX_ERROR;
81 : : }
82 : :
83 : 0 : ctx->foreach->cmd_index = ctx->next_handler_cmd;
84 : :
85 : 0 : ctx->foreach->next_choice = 0;
86 : :
87 : 0 : ctx->foreach->choices = ngx_array_create(r->pool, 10, sizeof(ngx_str_t));
88 [ # # ]: 0 : if (ctx->foreach->choices == NULL) {
89 : 0 : return NGX_ERROR;
90 : : }
91 : :
92 : 0 : delimiter = &computed_arg_elts[0];
93 : :
94 : 0 : pos = compound->data;
95 : 0 : end = compound->data + compound->len;
96 : :
97 [ # # ]: 0 : while ((last = ngx_http_echo_strlstrn(pos, end, delimiter->data,
98 : : delimiter->len - 1)) != NULL)
99 : : {
100 : : dd("entered the loop");
101 : :
102 [ # # ]: 0 : if (last == pos) {
103 : : dd("!!! len == 0");
104 : 0 : pos = last + delimiter->len;
105 : 0 : continue;
106 : : }
107 : :
108 : 0 : choice = ngx_array_push(ctx->foreach->choices);
109 [ # # ]: 0 : if (choice == NULL) {
110 : 0 : return NGX_ERROR;
111 : : }
112 : :
113 : 0 : choice->data = pos;
114 : 0 : choice->len = last - pos;
115 : 0 : pos = last + delimiter->len;
116 : : }
117 : :
118 [ # # ]: 0 : if (pos < end) {
119 : 0 : choice = ngx_array_push(ctx->foreach->choices);
120 [ # # ]: 0 : if (choice == NULL) {
121 : 0 : return NGX_ERROR;
122 : : }
123 : :
124 : 0 : choice->data = pos;
125 : 0 : choice->len = end - pos;
126 : : }
127 : :
128 [ # # ]: 0 : if (ctx->foreach->choices->nelts == 0) {
129 : : /* skip the foreach body entirely */
130 : 0 : elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
131 : 0 : cmds = elcf->handler_cmds;
132 : 0 : cmd_elts = cmds->elts;
133 [ # # ]: 0 : for (; ctx->next_handler_cmd < cmds->nelts;
134 : 0 : ctx->next_handler_cmd++) {
135 : 0 : cmd = &cmd_elts[ctx->next_handler_cmd + 1];
136 [ # # ]: 0 : if (cmd->opcode == echo_opcode_echo_end) {
137 : 0 : return NGX_OK;
138 : : }
139 : : }
140 : :
141 : : }
142 : :
143 : 0 : return NGX_OK;
144 : : }
145 : :
146 : :
147 : : ngx_int_t
148 : 0 : ngx_http_echo_exec_echo_end(ngx_http_request_t *r,
149 : : ngx_http_echo_ctx_t *ctx)
150 : : {
151 [ # # ]: 0 : if (ctx->foreach == NULL) {
152 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
153 : : "Found a echo_end that has no corresponding echo_foreach "
154 : : "before it.");
155 : 0 : return NGX_ERROR;
156 : : }
157 : :
158 : 0 : ctx->foreach->next_choice++;
159 : :
160 [ # # ]: 0 : if (ctx->foreach->next_choice >= ctx->foreach->choices->nelts) {
161 : : /* TODO We need to explicitly free the foreach ctx from
162 : : * the pool */
163 : 0 : ctx->foreach = NULL;
164 : :
165 : 0 : return NGX_OK;
166 : : }
167 : :
168 : : dd("echo_end: ++ next_choice (total: %u): %u",
169 : : (unsigned) ctx->foreach->choices->nelts,
170 : : (unsigned) ctx->foreach->next_choice);
171 : :
172 : : /* the main handler dispatcher loop will increment
173 : : * ctx->next_handler_cmd for us anyway. */
174 : 0 : ctx->next_handler_cmd = ctx->foreach->cmd_index;
175 : :
176 : 0 : return NGX_OK;
177 : : }
178 : :
|