Branch data Line data Source code
1 : : /* Copyright (C) agentzh */
2 : :
3 : : #define DDEBUG 0
4 : : #include "ddebug.h"
5 : :
6 : : #include "ngx_http_echo_sleep.h"
7 : : #include "ngx_http_echo_handler.h"
8 : :
9 : : #include <nginx.h>
10 : : #include <ngx_log.h>
11 : :
12 : : /* event handler for echo_sleep */
13 : :
14 : : static void ngx_http_echo_post_sleep(ngx_http_request_t *r);
15 : :
16 : : static void ngx_http_echo_sleep_cleanup(void *data);
17 : :
18 : :
19 : : ngx_int_t
20 : 0 : ngx_http_echo_exec_echo_sleep(
21 : : ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx,
22 : : ngx_array_t *computed_args)
23 : : {
24 : : ngx_str_t *computed_arg;
25 : : ngx_str_t *computed_arg_elts;
26 : : float delay; /* in sec */
27 : : ngx_http_cleanup_t *cln;
28 : :
29 : 0 : computed_arg_elts = computed_args->elts;
30 : 0 : computed_arg = &computed_arg_elts[0];
31 : :
32 : 0 : delay = atof( (char*) computed_arg->data );
33 : :
34 [ # # ]: 0 : if (delay < 0.001) { /* should be bigger than 1 msec */
35 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
36 : : "invalid sleep duration \"%V\"", &computed_arg_elts[0]);
37 : :
38 : 0 : return NGX_HTTP_BAD_REQUEST;
39 : : }
40 : :
41 : : dd("adding timer with delay %.02lf sec, r:%.*s", delay,
42 : : (int) r->uri.len,
43 : : r->uri.data);
44 : :
45 : 0 : ngx_add_timer(&ctx->sleep, (ngx_msec_t) (1000 * delay));
46 : :
47 : : /* we don't check broken downstream connections
48 : : * ourselves so even if the client shuts down
49 : : * the connection prematurely, nginx will still
50 : : * go on waiting for our timers to get properly
51 : : * expired. However, we'd still register a
52 : : * cleanup handler for completeness. */
53 : :
54 : 0 : cln = ngx_http_cleanup_add(r, 0);
55 [ # # ]: 0 : if (cln == NULL) {
56 : 0 : return NGX_ERROR;
57 : : }
58 : :
59 : 0 : cln->handler = ngx_http_echo_sleep_cleanup;
60 : 0 : cln->data = r;
61 : :
62 : 0 : return NGX_AGAIN;
63 : : }
64 : :
65 : :
66 : : static void
67 : 0 : ngx_http_echo_post_sleep(ngx_http_request_t *r)
68 : : {
69 : : ngx_http_echo_ctx_t *ctx;
70 : : /* ngx_int_t rc; */
71 : :
72 : : dd("post sleep, r:%.*s", (int) r->uri.len, r->uri.data);
73 : :
74 : 0 : ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
75 : :
76 [ # # ]: 0 : if (ctx == NULL) {
77 : 0 : return;
78 : : }
79 : :
80 : 0 : ctx->waiting = 0;
81 : 0 : ctx->done = 1;
82 : :
83 : : dd("sleep: after get module ctx");
84 : :
85 : : dd("timed out? %d", ctx->sleep.timedout);
86 : : dd("timer set? %d", ctx->sleep.timer_set);
87 : :
88 [ # # ]: 0 : if ( ! ctx->sleep.timedout ) {
89 : : dd("HERE reached!");
90 : 0 : return;
91 : : }
92 : :
93 : 0 : ctx->sleep.timedout = 0;
94 : :
95 [ # # ]: 0 : if (ctx->sleep.timer_set) {
96 : : dd("deleting timer for echo_sleep");
97 : :
98 : 0 : ngx_del_timer(&ctx->sleep);
99 : : }
100 : :
101 : : /* r->write_event_handler = ngx_http_request_empty_handler; */
102 : :
103 : 0 : ngx_http_echo_wev_handler(r);
104 : : }
105 : :
106 : :
107 : : void
108 : 0 : ngx_http_echo_sleep_event_handler(ngx_event_t *ev)
109 : : {
110 : : ngx_connection_t *c;
111 : : ngx_http_request_t *r;
112 : : ngx_http_log_ctx_t *ctx;
113 : :
114 : 0 : r = ev->data;
115 : 0 : c = r->connection;
116 : :
117 [ # # ]: 0 : if (c->destroyed) {
118 : 0 : return;
119 : : }
120 : :
121 [ # # ]: 0 : if (c->error) {
122 : 0 : ngx_http_finalize_request(r, NGX_ERROR);
123 : 0 : return;
124 : : }
125 : :
126 : 0 : ctx = c->log->data;
127 : 0 : ctx->current_request = r;
128 : :
129 : : /* XXX when r->done == 1 we should do cleaning immediately
130 : : * and delete our timer and then quit. */
131 : :
132 [ # # ]: 0 : ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
133 : : "echo sleep handler: \"%V?%V\"", &r->uri, &r->args);
134 : :
135 : : /*
136 : : if (r->done) {
137 : : return;
138 : : }
139 : : */
140 : :
141 : 0 : ngx_http_echo_post_sleep(r);
142 : :
143 : : #if defined(nginx_version)
144 : :
145 : : dd("before run posted requests");
146 : :
147 : 0 : ngx_http_run_posted_requests(c);
148 : :
149 : : dd("after run posted requests");
150 : :
151 : : #endif
152 : : }
153 : :
154 : :
155 : : ngx_int_t
156 : 0 : ngx_http_echo_exec_echo_blocking_sleep(ngx_http_request_t *r,
157 : : ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
158 : : {
159 : : ngx_str_t *computed_arg;
160 : : ngx_str_t *computed_arg_elts;
161 : : float delay; /* in sec */
162 : :
163 : 0 : computed_arg_elts = computed_args->elts;
164 : 0 : computed_arg = &computed_arg_elts[0];
165 : :
166 : 0 : delay = atof( (char*) computed_arg->data );
167 : :
168 [ # # ]: 0 : if (delay < 0.001) { /* should be bigger than 1 msec */
169 [ # # ]: 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
170 : : "invalid sleep duration \"%V\"", &computed_arg_elts[0]);
171 : 0 : return NGX_HTTP_BAD_REQUEST;
172 : : }
173 : :
174 : : dd("blocking DELAY = %.02lf sec", delay);
175 : :
176 : 0 : ngx_msleep((ngx_msec_t) (1000 * delay));
177 : :
178 : 0 : return NGX_OK;
179 : : }
180 : :
181 : :
182 : : static void
183 : 0 : ngx_http_echo_sleep_cleanup(void *data)
184 : : {
185 : 0 : ngx_http_request_t *r = data;
186 : : ngx_http_echo_ctx_t *ctx;
187 : :
188 : : dd("echo sleep cleanup");
189 : :
190 : 0 : ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);
191 [ # # ]: 0 : if (ctx == NULL) {
192 : 0 : return;
193 : : }
194 : :
195 [ # # ]: 0 : if (ctx->sleep.timer_set) {
196 : : dd("cleanup: deleting timer for echo_sleep");
197 : :
198 : 0 : ngx_del_timer(&ctx->sleep);
199 : 0 : return;
200 : : }
201 : :
202 : : dd("cleanup: timer not set");
203 : : }
204 : :
|