5
#include "ngx_http_echo_handler.h"
6
#include "ngx_http_echo_echo.h"
7
#include "ngx_http_echo_util.h"
8
#include "ngx_http_echo_sleep.h"
9
#include "ngx_http_echo_var.h"
10
#include "ngx_http_echo_timer.h"
11
#include "ngx_http_echo_location.h"
12
#include "ngx_http_echo_subrequest.h"
13
#include "ngx_http_echo_request_info.h"
14
#include "ngx_http_echo_foreach.h"
20
ngx_http_echo_handler_init(ngx_conf_t *cf)
24
rc = ngx_http_echo_echo_init(cf);
29
return ngx_http_echo_add_variables(cf);
34
ngx_http_echo_wev_handler(ngx_http_request_t *r)
37
ngx_http_echo_ctx_t *ctx;
41
ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
44
ngx_http_finalize_request(r, NGX_ERROR);
48
if (ctx->waiting && ! ctx->done) {
49
if (r->main->posted_requests
50
&& r->main->posted_requests->request != r)
54
#if defined(nginx_version) && nginx_version >= 8012
55
ngx_http_post_request(r, NULL);
57
ngx_http_post_request(r);
66
ctx->next_handler_cmd++;
68
rc = ngx_http_echo_run_cmds(r);
70
dd("rc: %d", (int) rc);
76
if (rc == NGX_AGAIN) {
77
dd("mark busy %d", (int) ctx->next_handler_cmd);
82
dd("mark ready %d", (int) ctx->next_handler_cmd);
86
dd("finalizing with rc %d", (int) rc);
88
dd("finalize request %.*s with %d", (int) r->uri.len, r->uri.data, (int) rc);
90
ngx_http_finalize_request(r, rc);
96
ngx_http_echo_handler(ngx_http_request_t *r)
99
ngx_http_echo_ctx_t *ctx;
101
rc = ngx_http_echo_run_cmds(r);
103
if (rc == NGX_ERROR) {
104
return NGX_HTTP_INTERNAL_SERVER_ERROR;
107
if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
111
if (rc == NGX_DONE) {
115
if (rc == NGX_AGAIN) {
116
#if defined(nginx_version) && nginx_version >= 8011
120
/* XXX we need this for 0.7.x and 0.8.x < 0.8.11 */
121
dd("%d", r->connection->destroyed);
124
ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
126
dd("mark busy %d", (int) ctx->next_handler_cmd);
139
ngx_http_echo_run_cmds(ngx_http_request_t *r)
141
ngx_http_echo_loc_conf_t *elcf;
142
ngx_http_echo_ctx_t *ctx;
145
ngx_array_t *computed_args = NULL;
146
ngx_http_echo_cmd_t *cmd;
147
ngx_http_echo_cmd_t *cmd_elts;
148
ngx_array_t *opts = NULL;
151
elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
152
cmds = elcf->handler_cmds;
157
ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
159
rc = ngx_http_echo_init_ctx(r, &ctx);
164
ngx_http_set_ctx(r, ctx, ngx_http_echo_module);
167
dd("exec handler: %.*s: %i", (int) r->uri.len, r->uri.data,
168
(int) ctx->next_handler_cmd);
170
cmd_elts = cmds->elts;
172
for (; ctx->next_handler_cmd < cmds->nelts; ctx->next_handler_cmd++) {
174
cmd = &cmd_elts[ctx->next_handler_cmd];
176
/* evaluate arguments for the current cmd (if any) */
178
computed_args = ngx_array_create(r->pool, cmd->args->nelts,
181
if (computed_args == NULL) {
182
return NGX_HTTP_INTERNAL_SERVER_ERROR;
185
opts = ngx_array_create(r->pool, 1, sizeof(ngx_str_t));
188
return NGX_HTTP_INTERNAL_SERVER_ERROR;
191
rc = ngx_http_echo_eval_cmd_args(r, cmd, computed_args, opts);
193
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
194
"Failed to evaluate arguments for "
200
/* do command dispatch based on the opcode */
201
switch (cmd->opcode) {
202
case echo_opcode_echo:
203
/* XXX moved the following code to a separate
205
dd("found echo opcode");
206
rc = ngx_http_echo_exec_echo(r, ctx, computed_args,
207
0 /* in filter */, opts);
210
case echo_opcode_echo_request_body:
211
rc = ngx_http_echo_exec_echo_request_body(r, ctx);
214
case echo_opcode_echo_location_async:
215
dd("found opcode echo location async...");
216
rc = ngx_http_echo_exec_echo_location_async(r, ctx,
220
case echo_opcode_echo_location:
221
return ngx_http_echo_exec_echo_location(r, ctx, computed_args);
224
case echo_opcode_echo_subrequest_async:
225
dd("found opcode echo subrequest async...");
226
rc = ngx_http_echo_exec_echo_subrequest_async(r, ctx,
230
case echo_opcode_echo_subrequest:
231
return ngx_http_echo_exec_echo_subrequest(r, ctx, computed_args);
234
case echo_opcode_echo_sleep:
235
return ngx_http_echo_exec_echo_sleep(r, ctx, computed_args);
238
case echo_opcode_echo_flush:
239
rc = ngx_http_echo_exec_echo_flush(r, ctx);
242
case echo_opcode_echo_blocking_sleep:
243
rc = ngx_http_echo_exec_echo_blocking_sleep(r, ctx,
247
case echo_opcode_echo_reset_timer:
248
rc = ngx_http_echo_exec_echo_reset_timer(r, ctx);
251
case echo_opcode_echo_duplicate:
252
rc = ngx_http_echo_exec_echo_duplicate(r, ctx, computed_args);
255
case echo_opcode_echo_read_request_body:
256
ctx->wait_read_request_body = 0;
258
rc = ngx_http_echo_exec_echo_read_request_body(r, ctx);
260
#if defined(nginx_version) && nginx_version >= 8011
261
/* XXX read_client_request_body always increments the counter */
265
dd("read request body: %d", (int) rc);
271
ctx->wait_read_request_body = 1;
273
/* r->write_event_handler = ngx_http_request_empty_handler; */
278
case echo_opcode_echo_foreach_split:
279
rc = ngx_http_echo_exec_echo_foreach_split(r, ctx, computed_args);
282
case echo_opcode_echo_end:
283
rc = ngx_http_echo_exec_echo_end(r, ctx);
286
case echo_opcode_echo_exec:
288
return ngx_http_echo_exec_exec(r, ctx, computed_args);
292
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
293
"Unknown opcode: %d", cmd->opcode);
294
return NGX_HTTP_INTERNAL_SERVER_ERROR;
298
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
303
rc = ngx_http_echo_send_chain_link(r, ctx, NULL /* indicate LAST */);
305
if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
314
ngx_http_echo_post_subrequest(ngx_http_request_t *r,
315
void *data, ngx_int_t rc)
317
ngx_http_request_t *pr;
318
ngx_http_echo_ctx_t *pr_ctx;
325
pr_ctx = ngx_http_get_module_ctx(pr, ngx_http_echo_module);
326
if (pr_ctx == NULL) {
330
dd("mark ready %d", (int) pr_ctx->next_handler_cmd);
335
pr->write_event_handler = ngx_http_echo_wev_handler;
337
/* ensure that the parent request is (or will be)
338
* posted out the head of the r->posted_requests chain */
340
if (r->main->posted_requests
341
&& r->main->posted_requests->request != pr)
343
rc = ngx_http_echo_post_request_at_head(pr, NULL);