1
/* Copyright (C) agentzh */
6
#include "ngx_http_echo_sleep.h"
7
#include "ngx_http_echo_handler.h"
12
/* event handler for echo_sleep */
14
static void ngx_http_echo_post_sleep(ngx_http_request_t *r);
16
static void ngx_http_echo_sleep_cleanup(void *data);
20
ngx_http_echo_exec_echo_sleep(
21
ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx,
22
ngx_array_t *computed_args)
24
ngx_str_t *computed_arg;
25
ngx_str_t *computed_arg_elts;
26
float delay; /* in sec */
27
ngx_http_cleanup_t *cln;
29
computed_arg_elts = computed_args->elts;
30
computed_arg = &computed_arg_elts[0];
32
delay = atof( (char*) computed_arg->data );
34
if (delay < 0.001) { /* should be bigger than 1 msec */
35
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
36
"invalid sleep duration \"%V\"", &computed_arg_elts[0]);
38
return NGX_HTTP_BAD_REQUEST;
41
dd("DELAY = %.02lf sec", delay);
43
ngx_add_timer(&ctx->sleep, (ngx_msec_t) (1000 * delay));
45
/* we don't check broken downstream connections
46
* ourselves so even if the client shuts down
47
* the connection prematurely, nginx will still
48
* go on waiting for our timers to get properly
49
* expired. However, we'd still register a
50
* cleanup handler for completeness. */
52
cln = ngx_http_cleanup_add(r, 0);
57
cln->handler = ngx_http_echo_sleep_cleanup;
65
ngx_http_echo_post_sleep(ngx_http_request_t *r)
67
ngx_http_echo_ctx_t *ctx;
70
dd("entered echo post sleep...(r->done: %d)", r->done);
72
dd("sleep: before get module ctx");
74
ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
83
dd("sleep: after get module ctx");
85
dd("timed out? %d", ctx->sleep.timedout);
86
dd("timer set? %d", ctx->sleep.timer_set);
88
if ( ! ctx->sleep.timedout ) {
93
ctx->sleep.timedout = 0;
95
if (ctx->sleep.timer_set) {
96
dd("deleting timer for echo_sleep");
98
ngx_del_timer(&ctx->sleep);
101
/* r->write_event_handler = ngx_http_request_empty_handler; */
103
ngx_http_echo_wev_handler(r);
108
ngx_http_echo_sleep_event_handler(ngx_event_t *ev)
111
ngx_http_request_t *r;
112
ngx_http_log_ctx_t *ctx;
122
ctx->current_request = r;
124
/* XXX when r->done == 1 we should do cleaning immediately
125
* and delete our timer and then quit. */
127
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
128
"echo sleep handler: \"%V?%V\"", &r->uri, &r->args);
136
ngx_http_echo_post_sleep(r);
138
#if defined(nginx_version)
140
dd("before run posted requests");
142
ngx_http_run_posted_requests(c);
144
dd("after run posted requests");
152
ngx_http_echo_exec_echo_blocking_sleep(ngx_http_request_t *r,
153
ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
155
ngx_str_t *computed_arg;
156
ngx_str_t *computed_arg_elts;
157
float delay; /* in sec */
159
computed_arg_elts = computed_args->elts;
160
computed_arg = &computed_arg_elts[0];
162
delay = atof( (char*) computed_arg->data );
164
if (delay < 0.001) { /* should be bigger than 1 msec */
165
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
166
"invalid sleep duration \"%V\"", &computed_arg_elts[0]);
167
return NGX_HTTP_BAD_REQUEST;
170
dd("blocking DELAY = %.02lf sec", delay);
172
ngx_msleep((ngx_msec_t) (1000 * delay));
179
ngx_http_echo_sleep_cleanup(void *data)
181
ngx_http_request_t *r = data;
182
ngx_http_echo_ctx_t *ctx;
184
dd("echo sleep cleanup");
186
ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
191
if (ctx->sleep.timer_set) {
192
dd("cleanup: deleting timer for echo_sleep");
194
ngx_del_timer(&ctx->sleep);
198
dd("cleanup: timer not set");