Branch data Line data Source code
1 : : #define DDEBUG 0
2 : : #include "ddebug.h"
3 : :
4 : : #include "ngx_http_echo_util.h"
5 : : #include "ngx_http_echo_subrequest.h"
6 : : #include "ngx_http_echo_handler.h"
7 : :
8 : : #define ngx_http_echo_method_name(m) { sizeof(m) - 1, (u_char *) m " " }
9 : :
10 : : ngx_str_t ngx_http_echo_content_length_header_key =
11 : : ngx_string("Content-Length");
12 : :
13 : : ngx_str_t ngx_http_echo_get_method = ngx_http_echo_method_name("GET");
14 : : ngx_str_t ngx_http_echo_put_method = ngx_http_echo_method_name("PUT");
15 : : ngx_str_t ngx_http_echo_post_method = ngx_http_echo_method_name("POST");
16 : : ngx_str_t ngx_http_echo_head_method = ngx_http_echo_method_name("HEAD");
17 : : ngx_str_t ngx_http_echo_copy_method = ngx_http_echo_method_name("COPY");
18 : : ngx_str_t ngx_http_echo_move_method = ngx_http_echo_method_name("MOVE");
19 : : ngx_str_t ngx_http_echo_lock_method = ngx_http_echo_method_name("LOCK");
20 : : ngx_str_t ngx_http_echo_mkcol_method = ngx_http_echo_method_name("MKCOL");
21 : : ngx_str_t ngx_http_echo_trace_method = ngx_http_echo_method_name("TRACE");
22 : : ngx_str_t ngx_http_echo_delete_method = ngx_http_echo_method_name("DELETE");
23 : : ngx_str_t ngx_http_echo_unlock_method = ngx_http_echo_method_name("UNLOCK");
24 : : ngx_str_t ngx_http_echo_options_method = ngx_http_echo_method_name("OPTIONS");
25 : : ngx_str_t ngx_http_echo_propfind_method =
26 : : ngx_http_echo_method_name("PROPFIND");
27 : : ngx_str_t ngx_http_echo_proppatch_method =
28 : : ngx_http_echo_method_name("PROPPATCH");
29 : :
30 : :
31 : : typedef struct ngx_http_echo_subrequest_s {
32 : : ngx_uint_t method;
33 : : ngx_str_t *method_name;
34 : : ngx_str_t *location;
35 : : ngx_str_t *query_string;
36 : : ssize_t content_length_n;
37 : : ngx_http_request_body_t *request_body;
38 : : } ngx_http_echo_subrequest_t;
39 : :
40 : :
41 : : static ngx_int_t ngx_http_echo_parse_method_name(ngx_str_t **method_name_ptr);
42 : :
43 : : static ngx_int_t ngx_http_echo_adjust_subrequest(ngx_http_request_t *sr,
44 : : ngx_http_echo_subrequest_t *parsed_sr);
45 : :
46 : : static ngx_int_t ngx_http_echo_parse_subrequest_spec(ngx_http_request_t *r,
47 : : ngx_array_t *computed_args, ngx_http_echo_subrequest_t **parsed_sr_ptr);
48 : :
49 : :
50 : : ngx_int_t
51 : 0 : ngx_http_echo_exec_echo_subrequest_async(ngx_http_request_t *r,
52 : : ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
53 : : {
54 : : ngx_int_t rc;
55 : : ngx_http_echo_subrequest_t *parsed_sr;
56 : : ngx_http_request_t *sr; /* subrequest object */
57 : : ngx_str_t args;
58 : 0 : ngx_uint_t flags = 0;
59 : :
60 : :
61 : : dd_enter();
62 : :
63 : 0 : rc = ngx_http_echo_parse_subrequest_spec(r, computed_args, &parsed_sr);
64 [ # # ]: 0 : if (rc != NGX_OK) {
65 : 0 : return rc;
66 : : }
67 : :
68 : : dd("location: %.*s",
69 : : (int) parsed_sr->location->len,
70 : : parsed_sr->location->data);
71 : :
72 : 0 : args.data = NULL;
73 : 0 : args.len = 0;
74 : :
75 [ # # ]: 0 : if (ngx_http_parse_unsafe_uri(r, parsed_sr->location, &args, &flags)
76 : : != NGX_OK)
77 : : {
78 : 0 : ctx->headers_sent = 1;
79 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
80 : : }
81 : :
82 [ # # ][ # # ]: 0 : if (args.len > 0 && parsed_sr->query_string == NULL) {
83 : 0 : parsed_sr->query_string = &args;
84 : : }
85 : :
86 : 0 : rc = ngx_http_echo_send_header_if_needed(r, ctx);
87 [ # # ][ # # ]: 0 : if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
88 : 0 : return rc;
89 : : }
90 : :
91 : 0 : rc = ngx_http_subrequest(r, parsed_sr->location, parsed_sr->query_string,
92 : : &sr, NULL, 0);
93 : :
94 [ # # ]: 0 : if (rc != NGX_OK) {
95 : 0 : return NGX_ERROR;
96 : : }
97 : :
98 : 0 : rc = ngx_http_echo_adjust_subrequest(sr, parsed_sr);
99 : :
100 [ # # ]: 0 : if (rc != NGX_OK) {
101 : 0 : return rc;
102 : : }
103 : :
104 : 0 : return NGX_OK;
105 : : }
106 : :
107 : :
108 : : ngx_int_t
109 : 0 : ngx_http_echo_exec_echo_subrequest(ngx_http_request_t *r,
110 : : ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
111 : : {
112 : : ngx_int_t rc;
113 : : ngx_http_request_t *sr; /* subrequest object */
114 : : ngx_http_post_subrequest_t *psr;
115 : : ngx_http_echo_subrequest_t *parsed_sr;
116 : : ngx_str_t args;
117 : 0 : ngx_uint_t flags = 0;
118 : : ngx_http_echo_ctx_t *sr_ctx;
119 : :
120 : : dd_enter();
121 : :
122 : 0 : rc = ngx_http_echo_parse_subrequest_spec(r, computed_args, &parsed_sr);
123 : :
124 [ # # ]: 0 : if (rc != NGX_OK) {
125 : 0 : return rc;
126 : : }
127 : :
128 : 0 : args.data = NULL;
129 : 0 : args.len = 0;
130 : :
131 [ # # ]: 0 : if (ngx_http_parse_unsafe_uri(r, parsed_sr->location, &args, &flags)
132 : : != NGX_OK)
133 : : {
134 : 0 : ctx->headers_sent = 1;
135 : :
136 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
137 : : }
138 : :
139 [ # # ][ # # ]: 0 : if (args.len > 0 && parsed_sr->query_string == NULL) {
140 : 0 : parsed_sr->query_string = &args;
141 : : }
142 : :
143 : 0 : rc = ngx_http_echo_send_header_if_needed(r, ctx);
144 : :
145 [ # # ][ # # ]: 0 : if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
146 : 0 : return rc;
147 : : }
148 : :
149 : 0 : sr_ctx = ngx_http_echo_create_ctx(r);
150 : :
151 : : /* set by ngx_http_echo_create_ctx
152 : : * sr_ctx->run_post_subrequest = 0
153 : : */
154 : :
155 : 0 : psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
156 : :
157 [ # # ]: 0 : if (psr == NULL) {
158 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
159 : : }
160 : :
161 : 0 : psr->handler = ngx_http_echo_post_subrequest;
162 : 0 : psr->data = sr_ctx;
163 : :
164 : 0 : rc = ngx_http_subrequest(r, parsed_sr->location, parsed_sr->query_string,
165 : : &sr, psr, 0);
166 : :
167 [ # # ]: 0 : if (rc != NGX_OK) {
168 : 0 : return NGX_ERROR;
169 : : }
170 : :
171 : 0 : sr_ctx->sleep.data = sr;
172 : :
173 : 0 : ngx_http_set_ctx(sr, sr_ctx, ngx_http_echo_module);
174 : :
175 : 0 : rc = ngx_http_echo_adjust_subrequest(sr, parsed_sr);
176 : :
177 [ # # ]: 0 : if (rc != NGX_OK) {
178 : 0 : return NGX_ERROR;
179 : : }
180 : :
181 : 0 : return NGX_AGAIN;
182 : : }
183 : :
184 : :
185 : : static ngx_int_t
186 : 0 : ngx_http_echo_parse_subrequest_spec(ngx_http_request_t *r,
187 : : ngx_array_t *computed_args, ngx_http_echo_subrequest_t **parsed_sr_ptr)
188 : : {
189 : : ngx_str_t *computed_arg_elts, *arg;
190 : 0 : ngx_str_t **to_write = NULL;
191 : : ngx_str_t *method_name;
192 : 0 : ngx_str_t *body_str = NULL;
193 : 0 : ngx_str_t *body_file = NULL;
194 : : ngx_uint_t i;
195 : : ngx_flag_t expecting_opt;
196 : 0 : ngx_http_request_body_t *rb = NULL;
197 : : ngx_buf_t *b;
198 : : ngx_http_echo_subrequest_t *parsed_sr;
199 : : ngx_open_file_info_t of;
200 : : ngx_http_core_loc_conf_t *clcf;
201 : : size_t len;
202 : :
203 : 0 : *parsed_sr_ptr = ngx_pcalloc(r->pool, sizeof(ngx_http_echo_subrequest_t));
204 [ # # ]: 0 : if (*parsed_sr_ptr == NULL) {
205 : 0 : return NGX_ERROR;
206 : : }
207 : :
208 : 0 : parsed_sr = *parsed_sr_ptr;
209 : :
210 : 0 : computed_arg_elts = computed_args->elts;
211 : :
212 : 0 : method_name = &computed_arg_elts[0];
213 : :
214 : 0 : parsed_sr->location = &computed_arg_elts[1];
215 : :
216 [ # # ]: 0 : if (parsed_sr->location->len == 0) {
217 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
218 : : }
219 : :
220 : 0 : expecting_opt = 1;
221 : :
222 [ # # ]: 0 : for (i = 2; i < computed_args->nelts; i++) {
223 : 0 : arg = &computed_arg_elts[i];
224 : :
225 [ # # ]: 0 : if (!expecting_opt) {
226 [ # # ]: 0 : if (to_write == NULL) {
227 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
228 : : "echo_subrequest_async: to_write should NOT be NULL");
229 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
230 : : }
231 : :
232 : 0 : *to_write = arg;
233 : 0 : to_write = NULL;
234 : :
235 : 0 : expecting_opt = 1;
236 : :
237 : 0 : continue;
238 : : }
239 : :
240 [ # # ]: 0 : if (arg->len == 2) {
241 [ # # ]: 0 : if (ngx_strncmp("-q", arg->data, arg->len) == 0) {
242 : 0 : to_write = &parsed_sr->query_string;
243 : 0 : expecting_opt = 0;
244 : 0 : continue;
245 : : }
246 : :
247 [ # # ]: 0 : if (ngx_strncmp("-b", arg->data, arg->len) == 0) {
248 : 0 : to_write = &body_str;
249 : 0 : expecting_opt = 0;
250 : 0 : continue;
251 : : }
252 : :
253 [ # # ]: 0 : if (ngx_strncmp("-f", arg->data, arg->len) == 0) {
254 : : dd("found option -f");
255 : 0 : to_write = &body_file;
256 : 0 : expecting_opt = 0;
257 : 0 : continue;
258 : : }
259 : : }
260 : :
261 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
262 : : "Unknown option for echo_subrequest_async: %V", arg);
263 : :
264 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
265 : : }
266 : :
267 [ # # ][ # # ]: 0 : if (body_str != NULL && body_str->len) {
268 : 0 : rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
269 : :
270 [ # # ]: 0 : if (rb == NULL) {
271 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
272 : : }
273 : :
274 : 0 : parsed_sr->content_length_n = body_str->len;
275 : :
276 : 0 : b = ngx_calloc_buf(r->pool);
277 [ # # ]: 0 : if (b == NULL) {
278 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
279 : : }
280 : :
281 : 0 : b->temporary = 1;
282 : : /* b->memory = 1; */
283 : 0 : b->start = b->pos = body_str->data;
284 : 0 : b->end = b->last = body_str->data + body_str->len;
285 : :
286 : 0 : rb->bufs = ngx_alloc_chain_link(r->pool);
287 [ # # ]: 0 : if (rb->bufs == NULL) {
288 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
289 : : }
290 : :
291 : 0 : rb->bufs->buf = b;
292 : 0 : rb->bufs->next = NULL;
293 : :
294 : 0 : rb->buf = b;
295 : :
296 [ # # ][ # # ]: 0 : } else if (body_file != NULL && body_file->len) {
297 : :
298 : : dd("body_file defined %.*s", (int) body_file->len, body_file->data);
299 : :
300 : 0 : body_file->data = ngx_http_echo_rebase_path(r->pool, body_file->data,
301 : 0 : body_file->len, &len);
302 : :
303 [ # # ]: 0 : if (body_file->data == NULL) {
304 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
305 : : }
306 : :
307 : 0 : body_file->len = len;
308 : :
309 : : dd("after rebase, the path becomes %.*s", (int) body_file->len,
310 : : body_file->data);
311 : :
312 : 0 : rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
313 [ # # ]: 0 : if (rb == NULL) {
314 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
315 : : }
316 : :
317 : 0 : clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
318 : 0 : ngx_memzero(&of, sizeof(ngx_open_file_info_t));
319 : :
320 : : #if defined(nginx_version) && nginx_version >= 8018
321 : 0 : of.read_ahead = clcf->read_ahead;
322 : : #endif
323 : :
324 : 0 : of.directio = clcf->directio;
325 : 0 : of.valid = clcf->open_file_cache_valid;
326 : 0 : of.min_uses = clcf->open_file_cache_min_uses;
327 : 0 : of.errors = clcf->open_file_cache_errors;
328 : 0 : of.events = clcf->open_file_cache_events;
329 : :
330 [ # # ]: 0 : if (ngx_open_cached_file(clcf->open_file_cache, body_file, &of, r->pool)
331 : : != NGX_OK)
332 : : {
333 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, of.err,
334 : : "%s \"%V\" failed",
335 : : of.failed, body_file);
336 : :
337 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
338 : : }
339 : :
340 : : dd("file content size: %d", (int) of.size);
341 : :
342 : 0 : parsed_sr->content_length_n = of.size;
343 : :
344 : 0 : b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
345 [ # # ]: 0 : if (b == NULL) {
346 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
347 : : }
348 : :
349 : 0 : b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
350 [ # # ]: 0 : if (b->file == NULL) {
351 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
352 : : }
353 : :
354 : 0 : b->file_pos = 0;
355 : 0 : b->file_last = of.size;
356 : :
357 : 0 : b->in_file = b->file_last ? 1: 0;
358 : :
359 : : #if 0
360 : : b->last_buf = (r == r->main) ? 1: 0;
361 : : b->last_in_chain = 1;
362 : : #endif
363 : :
364 : 0 : b->file->fd = of.fd;
365 : 0 : b->file->name = *body_file;
366 : 0 : b->file->log = r->connection->log;
367 : 0 : b->file->directio = of.is_directio;
368 : :
369 : 0 : rb->bufs = ngx_alloc_chain_link(r->pool);
370 [ # # ]: 0 : if (rb->bufs == NULL) {
371 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
372 : : }
373 : :
374 : 0 : rb->bufs->buf = b;
375 : 0 : rb->bufs->next = NULL;
376 : 0 : rb->buf = b;
377 : : }
378 : :
379 : 0 : parsed_sr->request_body = rb;
380 : :
381 : 0 : parsed_sr->method = ngx_http_echo_parse_method_name(&method_name);
382 : 0 : parsed_sr->method_name = method_name;
383 : :
384 : 0 : return NGX_OK;
385 : : }
386 : :
387 : :
388 : : static ngx_int_t
389 : 0 : ngx_http_echo_adjust_subrequest(ngx_http_request_t *sr,
390 : : ngx_http_echo_subrequest_t *parsed_sr)
391 : : {
392 : : ngx_table_elt_t *h;
393 : : ngx_http_core_main_conf_t *cmcf;
394 : : ngx_http_request_t *r;
395 : :
396 : 0 : sr->method = parsed_sr->method;
397 : 0 : sr->method_name = *(parsed_sr->method_name);
398 : :
399 : 0 : r = sr->parent;
400 : :
401 : 0 : sr->header_in = r->header_in;
402 : :
403 : : /* XXX work-around a bug in ngx_http_subrequest */
404 [ # # ]: 0 : if (r->headers_in.headers.last == &r->headers_in.headers.part) {
405 : 0 : sr->headers_in.headers.last = &sr->headers_in.headers.part;
406 : : }
407 : :
408 : : /* we do not inherit the parent request's variables */
409 : 0 : cmcf = ngx_http_get_module_main_conf(sr, ngx_http_core_module);
410 : 0 : sr->variables = ngx_pcalloc(sr->pool, cmcf->variables.nelts
411 : : * sizeof(ngx_http_variable_value_t));
412 : :
413 [ # # ]: 0 : if (sr->variables == NULL) {
414 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
415 : : }
416 : :
417 [ # # ]: 0 : if (parsed_sr->content_length_n > 0) {
418 : 0 : sr->headers_in.content_length_n = parsed_sr->content_length_n;
419 : 0 : sr->request_body = parsed_sr->request_body;
420 : :
421 : 0 : sr->headers_in.content_length = ngx_pcalloc(sr->pool,
422 : : sizeof(ngx_table_elt_t));
423 : 0 : sr->headers_in.content_length->value.data =
424 : 0 : ngx_palloc(sr->pool, NGX_OFF_T_LEN);
425 [ # # ]: 0 : if (sr->headers_in.content_length->value.data == NULL) {
426 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
427 : : }
428 : 0 : sr->headers_in.content_length->value.len = ngx_sprintf(
429 : 0 : sr->headers_in.content_length->value.data, "%O",
430 : : sr->headers_in.content_length_n) -
431 : 0 : sr->headers_in.content_length->value.data;
432 : :
433 [ # # ]: 0 : if (ngx_list_init(&sr->headers_in.headers, sr->pool, 20,
434 : : sizeof(ngx_table_elt_t)) != NGX_OK) {
435 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
436 : : }
437 : :
438 : 0 : h = ngx_list_push(&sr->headers_in.headers);
439 [ # # ]: 0 : if (h == NULL) {
440 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
441 : : }
442 : :
443 : 0 : h->hash = sr->header_hash;
444 : :
445 : 0 : h->key = ngx_http_echo_content_length_header_key;
446 : 0 : h->value = sr->headers_in.content_length->value;
447 : :
448 : 0 : h->lowcase_key = ngx_pnalloc(sr->pool, h->key.len);
449 [ # # ]: 0 : if (h->lowcase_key == NULL) {
450 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
451 : : }
452 : :
453 : 0 : ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
454 : :
455 : : dd("sr content length: %.*s",
456 : : (int) sr->headers_in.content_length->value.len,
457 : : sr->headers_in.content_length->value.data);
458 : : }
459 : :
460 : : dd("subrequest body: %p", sr->request_body);
461 : :
462 : 0 : return NGX_OK;
463 : : }
464 : :
465 : :
466 : : static ngx_int_t
467 : 0 : ngx_http_echo_parse_method_name(ngx_str_t **method_name_ptr)
468 : : {
469 : 0 : const ngx_str_t* method_name = *method_name_ptr;
470 : :
471 [ # # # # : 0 : switch (method_name->len) {
# # # # ]
472 : : case 3:
473 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "GET") == 0) {
474 : 0 : *method_name_ptr = &ngx_http_echo_get_method;
475 : 0 : return NGX_HTTP_GET;
476 : : break;
477 : : }
478 : :
479 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "PUT") == 0) {
480 : 0 : *method_name_ptr = &ngx_http_echo_put_method;
481 : 0 : return NGX_HTTP_PUT;
482 : : break;
483 : : }
484 : :
485 : 0 : return NGX_HTTP_UNKNOWN;
486 : : break;
487 : :
488 : : case 4:
489 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "POST") == 0) {
490 : 0 : *method_name_ptr = &ngx_http_echo_post_method;
491 : 0 : return NGX_HTTP_POST;
492 : : break;
493 : : }
494 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "HEAD") == 0) {
495 : 0 : *method_name_ptr = &ngx_http_echo_head_method;
496 : 0 : return NGX_HTTP_HEAD;
497 : : break;
498 : : }
499 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "COPY") == 0) {
500 : 0 : *method_name_ptr = &ngx_http_echo_copy_method;
501 : 0 : return NGX_HTTP_COPY;
502 : : break;
503 : : }
504 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "MOVE") == 0) {
505 : 0 : *method_name_ptr = &ngx_http_echo_move_method;
506 : 0 : return NGX_HTTP_MOVE;
507 : : break;
508 : : }
509 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "LOCK") == 0) {
510 : 0 : *method_name_ptr = &ngx_http_echo_lock_method;
511 : 0 : return NGX_HTTP_LOCK;
512 : : break;
513 : : }
514 : 0 : return NGX_HTTP_UNKNOWN;
515 : : break;
516 : :
517 : : case 5:
518 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "MKCOL") == 0) {
519 : 0 : *method_name_ptr = &ngx_http_echo_mkcol_method;
520 : 0 : return NGX_HTTP_MKCOL;
521 : : break;
522 : : }
523 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "TRACE") == 0) {
524 : 0 : *method_name_ptr = &ngx_http_echo_trace_method;
525 : 0 : return NGX_HTTP_TRACE;
526 : : break;
527 : : }
528 : 0 : return NGX_HTTP_UNKNOWN;
529 : : break;
530 : :
531 : : case 6:
532 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "DELETE") == 0) {
533 : 0 : *method_name_ptr = &ngx_http_echo_delete_method;
534 : 0 : return NGX_HTTP_DELETE;
535 : : break;
536 : : }
537 : :
538 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "UNLOCK") == 0) {
539 : 0 : *method_name_ptr = &ngx_http_echo_unlock_method;
540 : 0 : return NGX_HTTP_UNLOCK;
541 : : break;
542 : : }
543 : 0 : return NGX_HTTP_UNKNOWN;
544 : : break;
545 : :
546 : : case 7:
547 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "OPTIONS") == 0) {
548 : 0 : *method_name_ptr = &ngx_http_echo_options_method;
549 : 0 : return NGX_HTTP_OPTIONS;
550 : : break;
551 : : }
552 : 0 : return NGX_HTTP_UNKNOWN;
553 : : break;
554 : :
555 : : case 8:
556 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "PROPFIND") == 0) {
557 : 0 : *method_name_ptr = &ngx_http_echo_propfind_method;
558 : 0 : return NGX_HTTP_PROPFIND;
559 : : break;
560 : : }
561 : 0 : return NGX_HTTP_UNKNOWN;
562 : : break;
563 : :
564 : : case 9:
565 [ # # ]: 0 : if (ngx_http_echo_strcmp_const(method_name->data, "PROPPATCH") == 0) {
566 : 0 : *method_name_ptr = &ngx_http_echo_proppatch_method;
567 : 0 : return NGX_HTTP_PROPPATCH;
568 : : break;
569 : : }
570 : 0 : return NGX_HTTP_UNKNOWN;
571 : : break;
572 : :
573 : : default:
574 : 0 : return NGX_HTTP_UNKNOWN;
575 : : break;
576 : : }
577 : :
578 : : return NGX_HTTP_UNKNOWN;
579 : : }
580 : :
581 : :
582 : : /* XXX extermely evil and not working yet */
583 : : ngx_int_t
584 : 0 : ngx_http_echo_exec_abort_parent(ngx_http_request_t *r,
585 : : ngx_http_echo_ctx_t *ctx)
586 : : {
587 : : #if 0
588 : : ngx_http_postponed_request_t *pr, *ppr;
589 : : ngx_http_request_t *saved_data = NULL;
590 : : ngx_chain_t *out = NULL;
591 : : /* ngx_int_t rc; */
592 : :
593 : : dd("aborting parent...");
594 : :
595 : : if (r == r->main || r->parent == NULL) {
596 : : return NGX_OK;
597 : : }
598 : :
599 : : if (r->parent->postponed) {
600 : : dd("Found parent->postponed...");
601 : :
602 : : saved_data = r->connection->data;
603 : : ppr = NULL;
604 : : for (pr = r->parent->postponed; pr->next; pr = pr->next) {
605 : : if (pr->request == NULL) {
606 : : continue;
607 : : }
608 : :
609 : : if (pr->request == r) {
610 : : /* r->parent->postponed->next = pr; */
611 : : dd("found the current subrequest");
612 : : out = pr->out;
613 : : continue;
614 : : }
615 : :
616 : : /* r->connection->data = pr->request; */
617 : : dd("finalizing the subrequest...");
618 : : ngx_http_upstream_create(pr->request);
619 : : pr->request->upstream = NULL;
620 : :
621 : : if (ppr == NULL) {
622 : : r->parent->postponed = pr->next;
623 : : ppr = pr->next;
624 : : } else {
625 : : ppr->next = pr->next;
626 : : ppr = pr->next;
627 : : }
628 : : }
629 : : }
630 : :
631 : : r->parent->postponed->next = NULL;
632 : :
633 : : /*
634 : : r->connection->data = r->parent;
635 : : r->connection->buffered = 0;
636 : :
637 : : if (out != NULL) {
638 : : dd("trying to send more stuffs for the parent");
639 : : ngx_http_output_filter(r->parent, out);
640 : : }
641 : : */
642 : :
643 : : /* ngx_http_send_special(r->parent, NGX_HTTP_LAST); */
644 : :
645 : : if (saved_data) {
646 : : r->connection->data = saved_data;
647 : : }
648 : :
649 : : dd("terminating the parent request");
650 : :
651 : : return ngx_http_echo_send_chain_link(r, ctx, NULL /* indicate LAST */);
652 : :
653 : : /* ngx_http_upstream_create(r); */
654 : :
655 : : /* ngx_http_finalize_request(r->parent, NGX_ERROR); */
656 : : #endif
657 : :
658 : 0 : return NGX_OK;
659 : : }
660 : :
661 : :
662 : : ngx_int_t
663 : 0 : ngx_http_echo_exec_exec(ngx_http_request_t *r,
664 : : ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
665 : : {
666 : : ngx_str_t *uri;
667 : : ngx_str_t *user_args;
668 : : ngx_str_t args;
669 : : ngx_uint_t flags;
670 : : ngx_str_t *computed_arg;
671 : :
672 : 0 : computed_arg = computed_args->elts;
673 : :
674 : 0 : uri = &computed_arg[0];
675 : :
676 [ # # ]: 0 : if (uri->len == 0) {
677 : 0 : return NGX_HTTP_BAD_REQUEST;
678 : : }
679 : :
680 [ # # ]: 0 : if (computed_args->nelts > 1) {
681 : 0 : user_args = &computed_arg[1];
682 : : } else {
683 : 0 : user_args = NULL;
684 : : }
685 : :
686 : 0 : args.data = NULL;
687 : 0 : args.len = 0;
688 : :
689 [ # # ]: 0 : if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags)
690 : : != NGX_OK) {
691 : 0 : ctx->headers_sent = 1;
692 : 0 : return NGX_HTTP_INTERNAL_SERVER_ERROR;
693 : : }
694 : :
695 [ # # ][ # # ]: 0 : if (args.len > 0 && user_args == NULL) {
696 : 0 : user_args = &args;
697 : : }
698 : :
699 : : /*
700 : : rc = ngx_http_echo_send_header_if_needed(r, ctx);
701 : : if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
702 : : return rc;
703 : : }
704 : : */
705 : :
706 [ # # ]: 0 : if (uri->data[0] == '@') {
707 [ # # ][ # # ]: 0 : if (user_args && user_args->len > 0) {
708 [ # # ]: 0 : ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
709 : : "query strings %V ignored when exec'ing named location %V",
710 : : user_args, uri);
711 : :
712 : : }
713 : :
714 : 0 : return ngx_http_named_location(r, uri);
715 : : }
716 : :
717 : 0 : return ngx_http_internal_redirect(r, uri, user_args);
718 : : }
719 : :
|