Mercurial > hg > nginx
comparison src/http/modules/ngx_http_limit_req_module.c @ 2312:6e6f7db88be9
change rate to an excess
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 14 Nov 2008 11:32:03 +0000 |
parents | 159136c9808d |
children | b56a9ba4824d |
comparison
equal
deleted
inserted
replaced
2311:6bad42a41dd8 | 2312:6e6f7db88be9 |
---|---|
13 u_char color; | 13 u_char color; |
14 u_char dummy; | 14 u_char dummy; |
15 u_short len; | 15 u_short len; |
16 ngx_queue_t queue; | 16 ngx_queue_t queue; |
17 ngx_msec_t last; | 17 ngx_msec_t last; |
18 float rate; | 18 float excess; |
19 u_char data[1]; | 19 u_char data[1]; |
20 } ngx_http_limit_req_node_t; | 20 } ngx_http_limit_req_node_t; |
21 | 21 |
22 | 22 |
23 typedef struct { | 23 typedef struct { |
105 | 105 |
106 | 106 |
107 static ngx_int_t | 107 static ngx_int_t |
108 ngx_http_limit_req_handler(ngx_http_request_t *r) | 108 ngx_http_limit_req_handler(ngx_http_request_t *r) |
109 { | 109 { |
110 float rate; | 110 float excess; |
111 size_t len, n; | 111 size_t len, n; |
112 uint32_t hash; | 112 uint32_t hash; |
113 ngx_int_t rc; | 113 ngx_int_t rc; |
114 ngx_time_t *tp; | 114 ngx_time_t *tp; |
115 ngx_rbtree_node_t *node; | 115 ngx_rbtree_node_t *node; |
163 if (lz) { | 163 if (lz) { |
164 ngx_queue_remove(&lz->queue); | 164 ngx_queue_remove(&lz->queue); |
165 | 165 |
166 ngx_queue_insert_head(ctx->queue, &lz->queue); | 166 ngx_queue_insert_head(ctx->queue, &lz->queue); |
167 | 167 |
168 rate = lz->rate; | 168 excess = lz->excess; |
169 | 169 |
170 } else { | 170 } else { |
171 rate = 0.0; | 171 excess = 0.0; |
172 } | 172 } |
173 | 173 |
174 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 174 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
175 "limit_req: %i %.3f", rc, rate); | 175 "limit_req: %i %.3f", rc, excess); |
176 | 176 |
177 if (rc == NGX_BUSY) { | 177 if (rc == NGX_BUSY) { |
178 ngx_shmtx_unlock(&ctx->shpool->mutex); | 178 ngx_shmtx_unlock(&ctx->shpool->mutex); |
179 | 179 |
180 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 180 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
181 "limiting requests, excess: %.3f", rate); | 181 "limiting requests, excess: %.3f", excess); |
182 | 182 |
183 return NGX_HTTP_SERVICE_UNAVAILABLE; | 183 return NGX_HTTP_SERVICE_UNAVAILABLE; |
184 } | 184 } |
185 | 185 |
186 if (rc == NGX_AGAIN) { | 186 if (rc == NGX_AGAIN) { |
189 if (lzcf->nodelay) { | 189 if (lzcf->nodelay) { |
190 return NGX_DECLINED; | 190 return NGX_DECLINED; |
191 } | 191 } |
192 | 192 |
193 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, | 193 ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, |
194 "delaying request, excess: %.3f", rate); | 194 "delaying request, excess: %.3f", excess); |
195 | 195 |
196 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { | 196 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { |
197 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 197 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
198 } | 198 } |
199 | 199 |
200 r->read_event_handler = ngx_http_test_reading; | 200 r->read_event_handler = ngx_http_test_reading; |
201 r->write_event_handler = ngx_http_limit_req_delay; | 201 r->write_event_handler = ngx_http_limit_req_delay; |
202 ngx_add_timer(r->connection->write, (ngx_msec_t) (rate * 1000)); | 202 ngx_add_timer(r->connection->write, (ngx_msec_t) (excess * 1000)); |
203 | 203 |
204 return NGX_AGAIN; | 204 return NGX_AGAIN; |
205 } | 205 } |
206 | 206 |
207 if (rc == NGX_OK) { | 207 if (rc == NGX_OK) { |
232 lz->len = (u_char) len; | 232 lz->len = (u_char) len; |
233 | 233 |
234 tp = ngx_timeofday(); | 234 tp = ngx_timeofday(); |
235 lz->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec); | 235 lz->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec); |
236 | 236 |
237 lz->rate = 0.0; | 237 lz->excess = 0.0; |
238 ngx_memcpy(lz->data, vv->data, len); | 238 ngx_memcpy(lz->data, vv->data, len); |
239 | 239 |
240 ngx_rbtree_insert(ctx->rbtree, node); | 240 ngx_rbtree_insert(ctx->rbtree, node); |
241 | 241 |
242 ngx_queue_insert_head(ctx->queue, &lz->queue); | 242 ngx_queue_insert_head(ctx->queue, &lz->queue); |
349 tp = ngx_timeofday(); | 349 tp = ngx_timeofday(); |
350 | 350 |
351 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); | 351 now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); |
352 ms = (ngx_msec_int_t) (now - lz->last); | 352 ms = (ngx_msec_int_t) (now - lz->last); |
353 | 353 |
354 lz->rate = lz->rate - ctx->rate * ngx_abs(ms) / 1000 + 1; | 354 lz->excess = lz->excess - ctx->rate * ngx_abs(ms) / 1000 + 1; |
355 | 355 |
356 if (lz->rate < 0.0) { | 356 if (lz->excess < 0.0) { |
357 lz->rate = 0.0; | 357 lz->excess = 0.0; |
358 } | 358 } |
359 | 359 |
360 lz->last = now; | 360 lz->last = now; |
361 | 361 |
362 *lzp = lz; | 362 *lzp = lz; |
363 | 363 |
364 if (lz->rate > lzcf->burst) { | 364 if (lz->excess > lzcf->burst) { |
365 return NGX_BUSY; | 365 return NGX_BUSY; |
366 } | 366 } |
367 | 367 |
368 if (lz->rate > 0.0) { | 368 if (lz->excess > 0.0) { |
369 return NGX_AGAIN; | 369 return NGX_AGAIN; |
370 } | 370 } |
371 | 371 |
372 return NGX_OK; | 372 return NGX_OK; |
373 } | 373 } |
386 | 386 |
387 | 387 |
388 static void | 388 static void |
389 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n) | 389 ngx_http_limit_req_expire(ngx_http_limit_req_ctx_t *ctx, ngx_uint_t n) |
390 { | 390 { |
391 float rate; | 391 float excess; |
392 ngx_time_t *tp; | 392 ngx_time_t *tp; |
393 ngx_msec_t now; | 393 ngx_msec_t now; |
394 ngx_queue_t *q; | 394 ngx_queue_t *q; |
395 ngx_msec_int_t ms; | 395 ngx_msec_int_t ms; |
396 ngx_rbtree_node_t *node; | 396 ngx_rbtree_node_t *node; |
423 | 423 |
424 if (ms < 60000) { | 424 if (ms < 60000) { |
425 return; | 425 return; |
426 } | 426 } |
427 | 427 |
428 rate = lz->rate - ctx->rate * ms / 1000; | 428 excess = lz->excess - ctx->rate * ms / 1000; |
429 | 429 |
430 if (rate > 0.0) { | 430 if (excess > 0.0) { |
431 return; | 431 return; |
432 } | 432 } |
433 } | 433 } |
434 | 434 |
435 ngx_queue_remove(q); | 435 ngx_queue_remove(q); |