Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 1050 lines (785 sloc) 27.341 kb
3a3b15e Added sources of eval module
Valery Kholodkov authored
1
2 /*
3 * Copyright (C) 2009 Valery Kholodkov
4 */
5
6
47c5323 Yichun Zhang made DDEBUG defineable from outside.
agentzh authored
7 #ifndef DDEBUG
dd6f706 Yichun Zhang turned off ddebug.
agentzh authored
8 #define DDEBUG 0
47c5323 Yichun Zhang made DDEBUG defineable from outside.
agentzh authored
9 #endif
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
10 #include "ddebug.h"
2fc79cb Yichun Zhang now we report an error at config time if used with nginx 0.8.42 ~ 0.8.53...
agentzh authored
11
12 #include <nginx.h>
3a3b15e Added sources of eval module
Valery Kholodkov authored
13 #include <ngx_config.h>
14 #include <ngx_core.h>
15 #include <ngx_http.h>
16
172d8ba Yichun Zhang now we can properly unescape "+" to whitespace.
agentzh authored
17
18 static void ngx_unescape_uri_patched(u_char **dst, u_char **src,
19 size_t size, ngx_uint_t type);
20
21
3a3b15e Added sources of eval module
Valery Kholodkov authored
22 typedef struct {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
23 ngx_http_variable_t *variable;
24 ngx_uint_t index;
25 } ngx_http_eval_variable_t;
26
27 typedef struct {
28 ngx_array_t *variables;
3a3b15e Added sources of eval module
Valery Kholodkov authored
29 ngx_str_t eval_location;
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
30 ngx_flag_t escalate;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
31 ngx_str_t override_content_type;
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
32 ngx_flag_t subrequest_in_memory;
33 size_t buffer_size;
3a3b15e Added sources of eval module
Valery Kholodkov authored
34 } ngx_http_eval_loc_conf_t;
35
36 typedef struct {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
37 ngx_http_eval_loc_conf_t *base_conf;
38 ngx_http_variable_value_t **values;
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
39 unsigned int done:1;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
40 unsigned int in_progress:1;
ba6ab8e Valery Kholodkov Avoid producing duplicate headers when using escalation is on
vkholodkov authored
41 ngx_int_t status;
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
42 ngx_buf_t buffer;
3a3b15e Added sources of eval module
Valery Kholodkov authored
43 } ngx_http_eval_ctx_t;
44
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
45 typedef ngx_int_t (*ngx_http_eval_format_handler_pt)(ngx_http_request_t *r,
46 ngx_http_eval_ctx_t *ctx);
47
48 typedef struct {
49 ngx_str_t content_type;
50 ngx_http_eval_format_handler_pt handler;
51 } ngx_http_eval_format_t;
52
53 static ngx_int_t
54 ngx_http_eval_init_variables(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx,
55 ngx_http_eval_loc_conf_t *ecf);
56
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
57 static ngx_int_t ngx_http_eval_post_subrequest_handler(ngx_http_request_t *r, void *data, ngx_int_t rc);
3a3b15e Added sources of eval module
Valery Kholodkov authored
58
59 static void *ngx_http_eval_create_loc_conf(ngx_conf_t *cf);
60 static char *ngx_http_eval_merge_loc_conf(ngx_conf_t *cf, void *parent,
61 void *child);
62
63 static char *ngx_http_eval_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
64
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
65 static char *ngx_http_eval_subrequest_in_memory(ngx_conf_t *cf,
66 ngx_command_t *cmd, void *conf);
67
68 static ngx_int_t ngx_http_eval_header_filter(ngx_http_request_t *r);
69 static ngx_int_t ngx_http_eval_body_filter(ngx_http_request_t *r,
70 ngx_chain_t *in);
71
72 static void ngx_http_eval_discard_bufs(ngx_pool_t *pool, ngx_chain_t *in);
73
3a3b15e Added sources of eval module
Valery Kholodkov authored
74 static ngx_int_t ngx_http_eval_init(ngx_conf_t *cf);
75
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
76 static ngx_int_t ngx_http_eval_octet_stream(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx);
77 static ngx_int_t ngx_http_eval_plain_text(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx);
78 static ngx_int_t ngx_http_eval_urlencoded(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx);
79
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
80 static ngx_flag_t ngx_http_eval_requires_filter = 1;
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
81
82 static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
83 static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
84
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
85 static ngx_http_eval_format_t ngx_http_eval_formats[] = {
86 { ngx_string("application/octet-stream"), ngx_http_eval_octet_stream },
87 { ngx_string("text/plain"), ngx_http_eval_plain_text },
88 { ngx_string("application/x-www-form-urlencoded"), ngx_http_eval_urlencoded },
89
90 { ngx_null_string, ngx_http_eval_plain_text }
91 };
92
3a3b15e Added sources of eval module
Valery Kholodkov authored
93 static ngx_command_t ngx_http_eval_commands[] = {
94
95 { ngx_string("eval"),
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
96 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE|NGX_CONF_BLOCK,
3a3b15e Added sources of eval module
Valery Kholodkov authored
97 ngx_http_eval_block,
98 NGX_HTTP_LOC_CONF_OFFSET,
99 0,
100 NULL },
101
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
102 { ngx_string("eval_escalate"),
103 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
104 ngx_conf_set_flag_slot,
105 NGX_HTTP_LOC_CONF_OFFSET,
106 offsetof(ngx_http_eval_loc_conf_t, escalate),
107 NULL },
108
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
109 { ngx_string("eval_override_content_type"),
110 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
111 ngx_conf_set_str_slot,
112 NGX_HTTP_LOC_CONF_OFFSET,
113 offsetof(ngx_http_eval_loc_conf_t, override_content_type),
114 NULL },
115
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
116 { ngx_string("eval_subrequest_in_memory"),
117 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
118 ngx_http_eval_subrequest_in_memory,
119 NGX_HTTP_LOC_CONF_OFFSET,
120 offsetof(ngx_http_eval_loc_conf_t, subrequest_in_memory),
121 NULL },
122
123 { ngx_string("eval_buffer_size"),
124 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
125 ngx_conf_set_size_slot,
126 NGX_HTTP_LOC_CONF_OFFSET,
127 offsetof(ngx_http_eval_loc_conf_t, buffer_size),
128 NULL },
129
3a3b15e Added sources of eval module
Valery Kholodkov authored
130 ngx_null_command
131 };
132
133 static ngx_http_module_t ngx_http_eval_module_ctx = {
134 NULL, /* preconfiguration */
135 ngx_http_eval_init, /* postconfiguration */
136
137 NULL, /* create main configuration */
138 NULL, /* init main configuration */
139
140 NULL, /* create server configuration */
141 NULL, /* merge server configuration */
142
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
143 ngx_http_eval_create_loc_conf, /* create location configuration */
144 ngx_http_eval_merge_loc_conf /* merge location configuration */
3a3b15e Added sources of eval module
Valery Kholodkov authored
145 };
146
147 ngx_module_t ngx_http_eval_module = {
148 NGX_MODULE_V1,
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
149 &ngx_http_eval_module_ctx, /* module context */
150 ngx_http_eval_commands, /* module directives */
3a3b15e Added sources of eval module
Valery Kholodkov authored
151 NGX_HTTP_MODULE, /* module type */
152 NULL, /* init master */
153 NULL, /* init module */
154 NULL, /* init process */
155 NULL, /* init thread */
156 NULL, /* exit thread */
157 NULL, /* exit process */
158 NULL, /* exit master */
159 NGX_MODULE_V1_PADDING
160 };
161
162 static ngx_int_t
163 ngx_http_eval_handler(ngx_http_request_t *r)
164 {
f9825f5 Yichun Zhang removed the code that modifies subrequests' r->uri because it's very bug...
agentzh authored
165 /* size_t loc_len; */
3a3b15e Added sources of eval module
Valery Kholodkov authored
166 ngx_str_t args;
11f7161 Restore $uri variable in subrequests
Valery Kholodkov authored
167 ngx_str_t subrequest_uri;
3a3b15e Added sources of eval module
Valery Kholodkov authored
168 ngx_uint_t flags;
f9825f5 Yichun Zhang removed the code that modifies subrequests' r->uri because it's very bug...
agentzh authored
169 /* ngx_http_core_loc_conf_t *clcf; */
3a3b15e Added sources of eval module
Valery Kholodkov authored
170 ngx_http_eval_loc_conf_t *ecf;
171 ngx_http_eval_ctx_t *ctx;
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
172 ngx_http_eval_ctx_t *sr_ctx;
3a3b15e Added sources of eval module
Valery Kholodkov authored
173 ngx_http_request_t *sr;
174 ngx_int_t rc;
175 ngx_http_post_subrequest_t *psr;
11f7161 Restore $uri variable in subrequests
Valery Kholodkov authored
176 u_char *p;
177
f9825f5 Yichun Zhang removed the code that modifies subrequests' r->uri because it's very bug...
agentzh authored
178 /*
11f7161 Restore $uri variable in subrequests
Valery Kholodkov authored
179 if(r != r->main) {
180 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
181
182 loc_len = r->valid_location ? clcf->name.len : 0;
183
184 if(r->uri.len != loc_len) {
185 r->uri.data += loc_len;
186 r->uri.len -= loc_len;
187 }
188 else {
189 r->uri.len = 1;
190 }
191 }
f9825f5 Yichun Zhang removed the code that modifies subrequests' r->uri because it's very bug...
agentzh authored
192 */
3a3b15e Added sources of eval module
Valery Kholodkov authored
193
194 ecf = ngx_http_get_module_loc_conf(r, ngx_http_eval_module);
195
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
196 if(ecf->variables == NULL || !ecf->variables->nelts) {
3a3b15e Added sources of eval module
Valery Kholodkov authored
197 return NGX_DECLINED;
198 }
199
200 ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module);
201
202 if(ctx == NULL) {
203 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_eval_ctx_t));
204 if (ctx == NULL) {
205 return NGX_HTTP_INTERNAL_SERVER_ERROR;
206 }
207
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
208 ctx->base_conf = ecf;
209
3a3b15e Added sources of eval module
Valery Kholodkov authored
210 ngx_http_set_ctx(r, ctx, ngx_http_eval_module);
211 }
212
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
213 if (ctx->done) {
214 dd("subrequest done");
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
215 if(!ecf->escalate || ctx->status == NGX_OK || ctx->status == NGX_HTTP_OK) {
ba6ab8e Valery Kholodkov Avoid producing duplicate headers when using escalation is on
vkholodkov authored
216 return NGX_DECLINED;
217 }
218
501c9e4 Yichun Zhang now we disable subrequest in memory by default.
agentzh authored
219 dd("status: %d", (int) ctx->status);
220
ba6ab8e Valery Kholodkov Avoid producing duplicate headers when using escalation is on
vkholodkov authored
221 return ctx->status;
3a3b15e Added sources of eval module
Valery Kholodkov authored
222 }
223
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
224 if (ctx->in_progress) {
501c9e4 Yichun Zhang now we disable subrequest in memory by default.
agentzh authored
225 dd("still in progress");
226 return NGX_DONE;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
227 }
228
3a3b15e Added sources of eval module
Valery Kholodkov authored
229 psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
230 if (psr == NULL) {
231 return NGX_ERROR;
232 }
233
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
234 if(ngx_http_eval_init_variables(r, ctx, ecf) != NGX_OK) {
235 return NGX_ERROR;
236 }
3a3b15e Added sources of eval module
Valery Kholodkov authored
237
ac4ab36 Yichun Zhang inherit the parent request's query_string within the eval block.
agentzh authored
238 args = r->args;
3a3b15e Added sources of eval module
Valery Kholodkov authored
239 flags = 0;
240
11f7161 Restore $uri variable in subrequests
Valery Kholodkov authored
241 subrequest_uri.len = ecf->eval_location.len + r->uri.len;
242
243 p = subrequest_uri.data = ngx_palloc(r->pool, subrequest_uri.len);
244
245 if(p == NULL) {
246 return NGX_ERROR;
247 }
248
249 p = ngx_copy(p, ecf->eval_location.data, ecf->eval_location.len);
250 p = ngx_copy(p, r->uri.data, r->uri.len);
251
252 if (ngx_http_parse_unsafe_uri(r, &subrequest_uri, &args, &flags) != NGX_OK) {
3a3b15e Added sources of eval module
Valery Kholodkov authored
253 return NGX_ERROR;
254 }
255
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
256 psr->handler = ngx_http_eval_post_subrequest_handler;
3a3b15e Added sources of eval module
Valery Kholodkov authored
257 psr->data = ctx;
258
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
259 flags |= NGX_HTTP_SUBREQUEST_WAITED;
260
261 dd("subrequest in memory : %d", (int) ecf->subrequest_in_memory);
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
262
263 if (ecf->subrequest_in_memory) {
264 flags |= NGX_HTTP_SUBREQUEST_IN_MEMORY;
265 } else {
266 }
3a3b15e Added sources of eval module
Valery Kholodkov authored
267
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
268 dd("issue subrequest");
269
11f7161 Restore $uri variable in subrequests
Valery Kholodkov authored
270 rc = ngx_http_subrequest(r, &subrequest_uri, &args, &sr, psr, flags);
3a3b15e Added sources of eval module
Valery Kholodkov authored
271
272 if (rc == NGX_ERROR || rc == NGX_DONE) {
273 return rc;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
274 }
3a3b15e Added sources of eval module
Valery Kholodkov authored
275
1e11ff5 Valery Kholodkov Avoid receiving body in any evaluating subrequests
vkholodkov authored
276 sr->discard_body = 1;
277
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
278 ctx->in_progress = 1;
279
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
280 /* XXX we don't allow eval in subrequests, i think? */
281 sr_ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_eval_ctx_t));
282 if (sr_ctx == NULL) {
283 return NGX_HTTP_INTERNAL_SERVER_ERROR;
284 }
285
286 ngx_http_set_ctx(sr, sr_ctx, ngx_http_eval_module);
287
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
288 dd("wait for subrequest to complete");
289
399657b Yichun Zhang now we return NGX_DONE for the changes in nginx 0.8.54.
agentzh authored
290 return NGX_DONE;
3a3b15e Added sources of eval module
Valery Kholodkov authored
291 }
292
293 static ngx_int_t
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
294 ngx_http_eval_init_variables(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx,
295 ngx_http_eval_loc_conf_t *ecf)
296 {
297 ngx_uint_t i;
298 ngx_http_eval_variable_t *variable;
299
300 ctx->values = ngx_pcalloc(r->pool, ecf->variables->nelts * sizeof(ngx_http_variable_value_t*));
301
302 if (ctx->values == NULL) {
303 return NGX_ERROR;
304 }
305
306 variable = ecf->variables->elts;
307
308 for(i = 0;i<ecf->variables->nelts;i++) {
309 ctx->values[i] = r->variables + variable[i].index;
310
311 ctx->values[i]->valid = 0;
312 ctx->values[i]->not_found = 1;
313 }
314
315 return NGX_OK;
316 }
317
318 static ngx_int_t
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
319 ngx_http_eval_post_subrequest_handler(ngx_http_request_t *r, void *data, ngx_int_t rc)
3a3b15e Added sources of eval module
Valery Kholodkov authored
320 {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
321 ngx_http_eval_ctx_t *ctx = data;
322 ngx_http_eval_format_t *f = ngx_http_eval_formats;
323 ngx_str_t content_type;
3a3b15e Added sources of eval module
Valery Kholodkov authored
324
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
325 if(ctx->base_conf->override_content_type.len) {
326 content_type.data = ctx->base_conf->override_content_type.data;
327 content_type.len = ctx->base_conf->override_content_type.len;
328 }
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
329 else if(r->headers_out.content_type.len) {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
330 content_type.data = r->headers_out.content_type.data;
331 content_type.len = r->headers_out.content_type.len;
332 }
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
333 else {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
334 content_type.data = (u_char*)"application/octet-stream";
335 content_type.len = sizeof("application/octet-stream") - 1;
336 }
337
f8e1daf Yichun Zhang fixed a nasty bug in discarded_bufs.
agentzh authored
338 dd("content_type: %.*s", (int) content_type.len, content_type.data);
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
339
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
340 while(f->content_type.len) {
341
342 if(!ngx_strncasecmp(f->content_type.data, content_type.data,
343 f->content_type.len))
344 {
345 f->handler(r, ctx);
346 break;
347 }
348
349 f++;
3a3b15e Added sources of eval module
Valery Kholodkov authored
350 }
351
352 ctx->done = 1;
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
353 /* dd("rc == %d", rc); */
ba6ab8e Valery Kholodkov Avoid producing duplicate headers when using escalation is on
vkholodkov authored
354 ctx->status = rc;
3a3b15e Added sources of eval module
Valery Kholodkov authored
355
4eb2a02 Yichun Zhang added a test for using ngx_eval in named locations. this exposes an issu...
agentzh authored
356 #if 0
357 /* work-around a bug in the nginx core (ngx_http_named_location)
358 */
359 r->parent->write_event_handler = ngx_http_core_run_phases;
360 #endif
361
ba6ab8e Valery Kholodkov Avoid producing duplicate headers when using escalation is on
vkholodkov authored
362 return NGX_OK;
3a3b15e Added sources of eval module
Valery Kholodkov authored
363 }
364
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
365 /*
366 * The next two evaluation methods assume we have at least one varible.
367 *
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
368 * ngx_http_eval_handler must guarantee this. *
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
369 */
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
370 static ngx_int_t
371 ngx_http_eval_octet_stream(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx)
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
372 {
373 ngx_http_variable_value_t *value = ctx->values[0];
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
374 ngx_http_eval_ctx_t *sr_ctx;
375
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
376 dd("eval octet stream");
377
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
378 sr_ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module);
379
380 if (sr_ctx && sr_ctx->buffer.start) {
381 value->len = sr_ctx->buffer.last - sr_ctx->buffer.pos;
382 value->data = sr_ctx->buffer.pos;
383 value->valid = 1;
384 value->not_found = 0;
385
386 return NGX_OK;
387 }
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
388
389 if (r->upstream) {
390 value->len = r->upstream->buffer.last - r->upstream->buffer.pos;
391 value->data = r->upstream->buffer.pos;
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
392 dd("found upstream buffer %d: %.*s", (int) value->len,
393 (int) value->len, value->data);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
394 value->valid = 1;
395 value->not_found = 0;
541f54a Yichun Zhang updated README.
agentzh authored
396 dd("XXX no cacheable: %d", (int) value->no_cacheable);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
397 }
398
399 return NGX_OK;
400 }
401
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
402 static ngx_int_t
403 ngx_http_eval_plain_text(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx)
404 {
405 ngx_int_t rc;
406 u_char *p;
407 ngx_http_variable_value_t *value = ctx->values[0];
408
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
409 dd("eval plain text");
410
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
411 rc = ngx_http_eval_octet_stream(r, ctx);
412
413 if(rc != NGX_OK) {
414 return rc;
415 }
416
417 /*
418 * Remove trailing spaces and control characters
419 */
420 if(value->valid) {
421 p = value->data + value->len;
422
423 while(p != value->data) {
424 p--;
425
426 if(*p != CR && *p != LF && *p != '\t' && *p != ' ')
427 break;
428
429 value->len--;
430 }
431 }
432
433 return NGX_OK;
434 }
435
436 static ngx_int_t
437 ngx_http_eval_set_variable_value(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx,
438 ngx_str_t *name, ngx_str_t *value)
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
439 {
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
440 ngx_uint_t i;
441 ngx_http_eval_variable_t *variable;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
442
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
443 variable = ctx->base_conf->variables->elts;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
444
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
445 for(i = 0;i<ctx->base_conf->variables->nelts;i++) {
0a1fef7 Valery Kholodkov Stop on line break while parsing urlencoded
vkholodkov authored
446 if(!ngx_strncasecmp(variable[i].variable->name.data, name->data, variable[i].variable->name.len)) {
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
447 ctx->values[i]->len = value->len;
448 ctx->values[i]->data = value->data;
0a1fef7 Valery Kholodkov Stop on line break while parsing urlencoded
vkholodkov authored
449 ctx->values[i]->valid = 1;
450 ctx->values[i]->not_found = 0;
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
451
452 return NGX_OK;
453 }
454 }
455
456 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
457 "eval: ignored undefined variable \"%V\"", value);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
458
459 return NGX_OK;
460 }
461
462 static ngx_int_t
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
463 ngx_http_eval_parse_param(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx, ngx_str_t *param) {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
464 u_char *p, *src, *dst;
465
466 ngx_str_t name;
467 ngx_str_t value;
468
469 p = (u_char *) ngx_strchr(param->data, '=');
470
471 if(p == NULL) {
472 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
473 "eval: invalid param \"%V\"", param);
474 return NGX_ERROR;
475 }
476
477 name.data = param->data;
478 name.len = p - param->data;
479
480 value.data = p + 1;
481 value.len = param->len - (p - param->data) - 1;
482
483 src = dst = value.data;
484
172d8ba Yichun Zhang now we can properly unescape "+" to whitespace.
agentzh authored
485 ngx_unescape_uri_patched(&dst, &src, value.len, NGX_UNESCAPE_URI);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
486
674b49c Valery Kholodkov Update length after unescaping the value
vkholodkov authored
487 value.len = dst - value.data;
488
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
489 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
490 "eval param: \"%V\"=\"%V\"", &name, &value);
491
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
492 return ngx_http_eval_set_variable_value(r, ctx, &name, &value);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
493 }
494
495 static ngx_int_t
496 ngx_http_eval_urlencoded(ngx_http_request_t *r, ngx_http_eval_ctx_t *ctx)
497 {
498 u_char *pos, *last;
499 ngx_str_t param;
500 ngx_int_t rc;
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
501 ngx_http_eval_ctx_t *sr_ctx;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
502
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
503 sr_ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module);
504
505 if (sr_ctx && sr_ctx->buffer.start) {
506 pos = sr_ctx->buffer.pos;
507 last = sr_ctx->buffer.last;
508
509 } else {
510 if (!r->upstream || r->upstream->buffer.last == r->upstream->buffer.pos) {
511 return NGX_OK;
512 }
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
513
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
514 pos = r->upstream->buffer.pos;
515 last = r->upstream->buffer.last;
516 }
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
517
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
518 do {
519 param.data = pos;
520 param.len = 0;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
521
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
522 while (pos != last) {
523 if (*pos == '&') {
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
524 pos++;
525 break;
526 }
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
527
0a1fef7 Valery Kholodkov Stop on line break while parsing urlencoded
vkholodkov authored
528 if (*pos == CR || *pos == LF) {
529 pos = last;
530 break;
531 }
532
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
533 param.len++;
534 pos++;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
535 }
536
c0110a2 Evaluating response according to it's content type
Valery Kholodkov authored
537 if(param.len != 0) {
538 rc = ngx_http_eval_parse_param(r, ctx, &param);
539
540 if(rc != NGX_OK) {
541 return rc;
542 }
543 }
544 }while(pos != last);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
545
546 return NGX_OK;
547 }
548
3a3b15e Added sources of eval module
Valery Kholodkov authored
549 static void *
550 ngx_http_eval_create_loc_conf(ngx_conf_t *cf)
551 {
552 ngx_http_eval_loc_conf_t *conf;
553
554 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_eval_loc_conf_t));
555
556 if (conf == NULL) {
557 return NGX_CONF_ERROR;
558 }
559
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
560 conf->escalate = NGX_CONF_UNSET;
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
561 conf->buffer_size = NGX_CONF_UNSET_SIZE;
562 conf->subrequest_in_memory = NGX_CONF_UNSET;
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
563
3a3b15e Added sources of eval module
Valery Kholodkov authored
564 return conf;
565 }
566
567 static char *
568 ngx_http_eval_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
569 {
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
570 ngx_http_eval_loc_conf_t *prev = parent;
571 ngx_http_eval_loc_conf_t *conf = child;
572
573 ngx_conf_merge_value(conf->escalate, prev->escalate, 0);
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
574 ngx_conf_merge_str_value(conf->override_content_type, prev->override_content_type, "");
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
575 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, (size_t) ngx_pagesize);
576 ngx_conf_merge_value(conf->subrequest_in_memory,
501c9e4 Yichun Zhang now we disable subrequest in memory by default.
agentzh authored
577 prev->subrequest_in_memory, 0);
3673975 Added eval_escalate directive which enables escalation of errors
Valery Kholodkov authored
578
3a3b15e Added sources of eval module
Valery Kholodkov authored
579 return NGX_CONF_OK;
580 }
581
582 static ngx_int_t
583 ngx_http_eval_variable(ngx_http_request_t *r,
584 ngx_http_variable_value_t *v, uintptr_t data)
585 {
541f54a Yichun Zhang updated README.
agentzh authored
586 dd("XXX eval variable get_handle");
587
3a3b15e Added sources of eval module
Valery Kholodkov authored
588 v->valid = 1;
589 v->no_cacheable = 0;
590 v->not_found = 0;
591
592 v->len = 0;
593 v->data = (u_char*)"";
594
595 return NGX_OK;
596 }
597
598 static char *
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
599 ngx_http_eval_add_variables(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
3a3b15e Added sources of eval module
Valery Kholodkov authored
600 {
601 ngx_http_eval_loc_conf_t *ecf = conf;
602
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
603 ngx_uint_t i;
3a3b15e Added sources of eval module
Valery Kholodkov authored
604 ngx_int_t index;
605 ngx_str_t *value;
606 ngx_http_variable_t *v;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
607 ngx_http_eval_variable_t *variable;
3a3b15e Added sources of eval module
Valery Kholodkov authored
608
609 value = cf->args->elts;
610
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
611 ecf->variables = ngx_array_create(cf->pool,
612 cf->args->nelts, sizeof(ngx_http_eval_variable_t));
613
614 if(ecf->variables == NULL) {
3a3b15e Added sources of eval module
Valery Kholodkov authored
615 return NGX_CONF_ERROR;
616 }
617
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
618 for(i = 1;i<cf->args->nelts;i++) {
619 if (value[i].data[0] != '$') {
620 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
621 "invalid variable name \"%V\"", &value[1]);
622 return NGX_CONF_ERROR;
623 }
3a3b15e Added sources of eval module
Valery Kholodkov authored
624
5d4e50a Fixed issue with populating the variables array
Valery Kholodkov authored
625 variable = ngx_array_push(ecf->variables);
e660bcd Valery Kholodkov Verify result of ngx_array_push
vkholodkov authored
626 if(variable == NULL) {
627 return NGX_CONF_ERROR;
628 }
5d4e50a Fixed issue with populating the variables array
Valery Kholodkov authored
629
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
630 value[i].len--;
631 value[i].data++;
3a3b15e Added sources of eval module
Valery Kholodkov authored
632
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
633 v = ngx_http_add_variable(cf, &value[i], NGX_HTTP_VAR_CHANGEABLE);
634 if (v == NULL) {
635 return NGX_CONF_ERROR;
636 }
637
638 index = ngx_http_get_variable_index(cf, &value[i]);
639 if (index == NGX_ERROR) {
640 return NGX_CONF_ERROR;
641 }
3a3b15e Added sources of eval module
Valery Kholodkov authored
642
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
643 if (v->get_handler == NULL)
644 {
645 v->get_handler = ngx_http_eval_variable;
646 v->data = index;
647 }
648
5d4e50a Fixed issue with populating the variables array
Valery Kholodkov authored
649 variable->variable = v;
650 variable->index = index;
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
651 }
3a3b15e Added sources of eval module
Valery Kholodkov authored
652
653 return NGX_CONF_OK;
654 }
655
656 static char *
657 ngx_http_eval_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
658 {
d9809d0 Yichun Zhang fixed compilation warnings with gcc 4.6.
agentzh authored
659 ngx_http_eval_loc_conf_t *pecf = conf;
3a3b15e Added sources of eval module
Valery Kholodkov authored
660
661 char *rv;
662 void *mconf;
663 ngx_str_t name;
664 ngx_uint_t i;
665 ngx_conf_t save;
666 ngx_http_module_t *module;
667 ngx_http_conf_ctx_t *ctx, *pctx;
d9809d0 Yichun Zhang fixed compilation warnings with gcc 4.6.
agentzh authored
668 ngx_http_core_loc_conf_t *clcf, *rclcf;
3a3b15e Added sources of eval module
Valery Kholodkov authored
669 ngx_http_core_srv_conf_t *cscf;
670
2fc79cb Yichun Zhang now we report an error at config time if used with nginx 0.8.42 ~ 0.8.53...
agentzh authored
671 #if defined(nginx_version) && nginx_version >= 8042 && nginx_version <= 8053
672 return "does not work with " NGINX_VER;
673 #endif
674
ff0d8cc Evaluation of multiple variables
Valery Kholodkov authored
675 if(ngx_http_eval_add_variables(cf, cmd, conf) != NGX_CONF_OK) {
3a3b15e Added sources of eval module
Valery Kholodkov authored
676 return NGX_CONF_ERROR;
677 }
678
679 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
680 if (ctx == NULL) {
681 return NGX_CONF_ERROR;
682 }
683
684 pctx = cf->ctx;
685 ctx->main_conf = pctx->main_conf;
686 ctx->srv_conf = pctx->srv_conf;
687
688 ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
689 if (ctx->loc_conf == NULL) {
690 return NGX_CONF_ERROR;
691 }
692
693 for (i = 0; ngx_modules[i]; i++) {
694 if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
695 continue;
696 }
697
698 module = ngx_modules[i]->ctx;
699
700 if (module->create_loc_conf) {
701
702 mconf = module->create_loc_conf(cf);
703 if (mconf == NULL) {
704 return NGX_CONF_ERROR;
705 }
706
707 ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
708 }
709 }
710
711 clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
712
713 name.len = sizeof("/eval_") - 1 + NGX_OFF_T_LEN;
714
715 name.data = ngx_palloc(cf->pool, name.len);
716
717 if(name.data == NULL) {
718 return NGX_CONF_ERROR;
719 }
720
721 name.len = ngx_sprintf(name.data, "/eval_%O", (off_t)(uintptr_t)clcf) - name.data;
722
723 clcf->loc_conf = ctx->loc_conf;
724 clcf->name = name;
11f7161 Restore $uri variable in subrequests
Valery Kholodkov authored
725 clcf->exact_match = 0;
3a3b15e Added sources of eval module
Valery Kholodkov authored
726 clcf->noname = 0;
727 clcf->internal = 1;
728 clcf->noregex = 1;
729
730 cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
731
732 rclcf = cscf->ctx->loc_conf[ngx_http_core_module.ctx_index];
733
734 if (ngx_http_add_location(cf, &rclcf->locations, clcf) != NGX_OK) {
735 return NGX_CONF_ERROR;
736 }
737
738 pecf->eval_location = clcf->name;
739
740 save = *cf;
741 cf->ctx = ctx;
742 cf->cmd_type = NGX_HTTP_LOC_CONF;
743
744 rv = ngx_conf_parse(cf, NULL);
745
746 *cf = save;
747
748 return rv;
749 }
750
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
751 static char *
752 ngx_http_eval_subrequest_in_memory(ngx_conf_t *cf,
753 ngx_command_t *cmd, void *conf)
754 {
755 char *res;
756
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
757 dd("eval subrequest in memory");
758
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
759 res = ngx_conf_set_flag_slot(cf, cmd, conf);
760 if (res != NGX_CONF_OK) {
761 return res;
762 }
763
764 return NGX_CONF_OK;
765 }
766
3a3b15e Added sources of eval module
Valery Kholodkov authored
767 static ngx_int_t
768 ngx_http_eval_init(ngx_conf_t *cf)
769 {
770 ngx_http_handler_pt *h;
771 ngx_http_core_main_conf_t *cmcf;
772
773 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
774
775 h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers);
776 if (h == NULL) {
777 return NGX_ERROR;
778 }
779
780 *h = ngx_http_eval_handler;
781
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
782 if (ngx_http_eval_requires_filter) {
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
783 dd("requires filter");
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
784 ngx_http_next_header_filter = ngx_http_top_header_filter;
785 ngx_http_top_header_filter = ngx_http_eval_header_filter;
786
787 ngx_http_next_body_filter = ngx_http_top_body_filter;
788 ngx_http_top_body_filter = ngx_http_eval_body_filter;
789 }
790
3a3b15e Added sources of eval module
Valery Kholodkov authored
791 return NGX_OK;
792 }
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
793
794 static ngx_int_t
795 ngx_http_eval_header_filter(ngx_http_request_t *r)
796 {
797 ngx_http_eval_ctx_t *ctx;
798
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
799 dd("header filter");
800
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
801 if (r == r->main) {
802 return ngx_http_next_header_filter(r);
803 }
804
805 ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module);
806 if (ctx == NULL) {
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
807 dd("WARNING: ctx is null, forwarding header filter");
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
808 return ngx_http_next_header_filter(r);
809 }
810
811 r->filter_need_in_memory = 1;
812
813 /* suppress header output */
814
f8e1daf Yichun Zhang fixed a nasty bug in discarded_bufs.
agentzh authored
815 dd("header filter called: type: %.*s", (int)r->headers_out.content_type.len, r->headers_out.content_type.data);
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
816
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
817 return NGX_OK;
818 }
819
820 static ngx_int_t
821 ngx_http_eval_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
822 {
823 ngx_http_eval_ctx_t *ctx;
824 ngx_chain_t *cl;
825 ngx_buf_t *b;
826 ngx_http_eval_loc_conf_t *conf;
827 size_t len;
828 ssize_t rest;
829
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
830 dd("in body filter");
831
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
832 if (r == r->main) {
833 return ngx_http_next_body_filter(r, in);
834 }
835
836 ctx = ngx_http_get_module_ctx(r, ngx_http_eval_module);
837 if (ctx == NULL) {
838 return ngx_http_next_body_filter(r, in);
839 }
840
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
841 dd("in body filter");
842
e38ddad Yichun Zhang now we no longer bundle Test::Nginx with us; and also fixed several impo...
agentzh authored
843 conf = ngx_http_get_module_loc_conf(r->parent, ngx_http_eval_module);
844
845 if (conf->subrequest_in_memory) {
846 return ngx_http_next_body_filter(r, in);
847 }
848
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
849 b = &ctx->buffer;
850
851 if (b->start == NULL) {
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
852 dd("allocate buffer");
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
853
854 b->start = ngx_palloc(r->pool, conf->buffer_size);
855 if (b->start == NULL) {
856 return NGX_ERROR;
857 }
858
859 b->end = b->start + conf->buffer_size;
860 b->pos = b->last = b->start;
861 }
862
863 for (cl = in; cl; cl = cl->next) {
864 rest = b->end - b->last;
865 if (rest == 0) {
866 break;
867 }
868
869 if ( ! ngx_buf_in_memory(cl->buf)) {
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
870 dd("buf not in memory!");
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
871 continue;
872 }
873
874 len = cl->buf->last - cl->buf->pos;
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
875
876 if (len == 0) {
877 continue;
878 }
879
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
880 if (len > (size_t) rest) {
881 /* we truncate the exceeding part of the response body */
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
882 dd("truncate and ignore exceeding bufs");
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
883 len = rest;
884 }
885
f4a75e5 Yichun Zhang added ddebug.h since Valery won't merge this branch to his mainstream an...
agentzh authored
886
f8e1daf Yichun Zhang fixed a nasty bug in discarded_bufs.
agentzh authored
887 dd("copied data '%.*s' (len %d, c0: %d)", (int) len, cl->buf->pos, (int) len, (int) *(cl->buf->pos));
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
888 b->last = ngx_copy(b->last, cl->buf->pos, len);
889 }
890
891 ngx_http_eval_discard_bufs(r->pool, in);
892
893 return NGX_OK;
894 }
895
896 static void
897 ngx_http_eval_discard_bufs(ngx_pool_t *pool, ngx_chain_t *in)
898 {
899 ngx_chain_t *cl;
900
f8e1daf Yichun Zhang fixed a nasty bug in discarded_bufs.
agentzh authored
901 for (cl = in; cl; cl = cl->next) {
2b10da5 Yichun Zhang no longer pfree the upstream chain bufs.
agentzh authored
902 #if 0
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
903 if (cl->buf->temporary && cl->buf->memory
904 && ngx_buf_size(cl->buf) > 0) {
905 ngx_pfree(pool, cl->buf->start);
906 }
2b10da5 Yichun Zhang no longer pfree the upstream chain bufs.
agentzh authored
907 #endif
3020e9d Yichun Zhang implemented the eval_subrequest_in_memory and the corresponding eval_buf...
agentzh authored
908
909 cl->buf->pos = cl->buf->last;
910 }
911 }
912
172d8ba Yichun Zhang now we can properly unescape "+" to whitespace.
agentzh authored
913
914 /* XXX we also decode '+' to ' ' */
915 static void
916 ngx_unescape_uri_patched(u_char **dst, u_char **src, size_t size,
917 ngx_uint_t type)
918 {
919 u_char *d, *s, ch, c, decoded;
920 enum {
921 sw_usual = 0,
922 sw_quoted,
923 sw_quoted_second
924 } state;
925
926 d = *dst;
927 s = *src;
928
929 state = 0;
930 decoded = 0;
931
932 while (size--) {
933
934 ch = *s++;
935
936 switch (state) {
937 case sw_usual:
938 if (ch == '?'
939 && (type & (NGX_UNESCAPE_URI|NGX_UNESCAPE_REDIRECT)))
940 {
941 *d++ = ch;
942 goto done;
943 }
944
945 if (ch == '%') {
946 state = sw_quoted;
947 break;
948 }
949
950 if (ch == '+') {
951 *d++ = ' ';
952 break;
953 }
954
955 *d++ = ch;
956 break;
957
958 case sw_quoted:
959
960 if (ch >= '0' && ch <= '9') {
961 decoded = (u_char) (ch - '0');
962 state = sw_quoted_second;
963 break;
964 }
965
966 c = (u_char) (ch | 0x20);
967 if (c >= 'a' && c <= 'f') {
968 decoded = (u_char) (c - 'a' + 10);
969 state = sw_quoted_second;
970 break;
971 }
972
973 /* the invalid quoted character */
974
975 state = sw_usual;
976
977 *d++ = ch;
978
979 break;
980
981 case sw_quoted_second:
982
983 state = sw_usual;
984
985 if (ch >= '0' && ch <= '9') {
986 ch = (u_char) ((decoded << 4) + ch - '0');
987
988 if (type & NGX_UNESCAPE_REDIRECT) {
989 if (ch > '%' && ch < 0x7f) {
990 *d++ = ch;
991 break;
992 }
993
994 *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
995
996 break;
997 }
998
999 *d++ = ch;
1000
1001 break;
1002 }
1003
1004 c = (u_char) (ch | 0x20);
1005 if (c >= 'a' && c <= 'f') {
1006 ch = (u_char) ((decoded << 4) + c - 'a' + 10);
1007
1008 if (type & NGX_UNESCAPE_URI) {
1009 if (ch == '?') {
1010 *d++ = ch;
1011 goto done;
1012 }
1013
1014 *d++ = ch;
1015 break;
1016 }
1017
1018 if (type & NGX_UNESCAPE_REDIRECT) {
1019 if (ch == '?') {
1020 *d++ = ch;
1021 goto done;
1022 }
1023
1024 if (ch > '%' && ch < 0x7f) {
1025 *d++ = ch;
1026 break;
1027 }
1028
1029 *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
1030 break;
1031 }
1032
1033 *d++ = ch;
1034
1035 break;
1036 }
1037
1038 /* the invalid quoted character */
1039
1040 break;
1041 }
1042 }
1043
1044 done:
1045
1046 *dst = d;
1047 *src = s;
1048 }
1049
Something went wrong with that request. Please try again.