comparison src/http/modules/ngx_http_limit_req_module.c @ 3780:d94d7104f598

change order of limit_req lookup result processing
author Igor Sysoev <igor@sysoev.ru>
date Thu, 14 Oct 2010 09:20:01 +0000
parents 57aecfdcac3d
children 7697412a0921 97995d63aa36
comparison
equal deleted inserted replaced
3779:57aecfdcac3d 3780:d94d7104f598
189 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &excess); 189 rc = ngx_http_limit_req_lookup(lrcf, hash, vv->data, len, &excess);
190 190
191 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 191 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
192 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000); 192 "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000);
193 193
194 if (rc == NGX_DECLINED) {
195
196 n = offsetof(ngx_rbtree_node_t, color)
197 + offsetof(ngx_http_limit_req_node_t, data)
198 + len;
199
200 node = ngx_slab_alloc_locked(ctx->shpool, n);
201 if (node == NULL) {
202
203 ngx_http_limit_req_expire(ctx, 0);
204
205 node = ngx_slab_alloc_locked(ctx->shpool, n);
206 if (node == NULL) {
207 ngx_shmtx_unlock(&ctx->shpool->mutex);
208 return NGX_HTTP_SERVICE_UNAVAILABLE;
209 }
210 }
211
212 lr = (ngx_http_limit_req_node_t *) &node->color;
213
214 node->key = hash;
215 lr->len = (u_char) len;
216
217 tp = ngx_timeofday();
218 lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
219
220 lr->excess = 0;
221 ngx_memcpy(lr->data, vv->data, len);
222
223 ngx_rbtree_insert(&ctx->sh->rbtree, node);
224
225 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
226
227 ngx_shmtx_unlock(&ctx->shpool->mutex);
228
229 return NGX_DECLINED;
230 }
231
232 ngx_shmtx_unlock(&ctx->shpool->mutex);
233
234 if (rc == NGX_OK) {
235 return NGX_DECLINED;
236 }
237
194 if (rc == NGX_BUSY) { 238 if (rc == NGX_BUSY) {
195 ngx_shmtx_unlock(&ctx->shpool->mutex);
196
197 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0, 239 ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
198 "limiting requests, excess: %ui.%03ui by zone \"%V\"", 240 "limiting requests, excess: %ui.%03ui by zone \"%V\"",
199 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); 241 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
200 242
201 return NGX_HTTP_SERVICE_UNAVAILABLE; 243 return NGX_HTTP_SERVICE_UNAVAILABLE;
202 } 244 }
203 245
204 if (rc == NGX_AGAIN) { 246 /* rc == NGX_AGAIN */
205 ngx_shmtx_unlock(&ctx->shpool->mutex); 247
206 248 if (lrcf->nodelay) {
207 if (lrcf->nodelay) { 249 return NGX_DECLINED;
208 return NGX_DECLINED; 250 }
209 } 251
210 252 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
211 ngx_log_error(lrcf->delay_log_level, r->connection->log, 0, 253 "delaying request, excess: %ui.%03ui, by zone \"%V\"",
212 "delaying request, excess: %ui.%03ui, by zone \"%V\"", 254 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
213 excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); 255
214 256 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
215 if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { 257 return NGX_HTTP_INTERNAL_SERVER_ERROR;
216 return NGX_HTTP_INTERNAL_SERVER_ERROR; 258 }
217 } 259
218 260 r->read_event_handler = ngx_http_test_reading;
219 r->read_event_handler = ngx_http_test_reading; 261 r->write_event_handler = ngx_http_limit_req_delay;
220 r->write_event_handler = ngx_http_limit_req_delay; 262 ngx_add_timer(r->connection->write,
221 ngx_add_timer(r->connection->write, 263 (ngx_msec_t) excess * 1000 / ctx->rate);
222 (ngx_msec_t) excess * 1000 / ctx->rate); 264
223 265 return NGX_AGAIN;
224 return NGX_AGAIN;
225 }
226
227 if (rc == NGX_OK) {
228 goto done;
229 }
230
231 /* rc == NGX_DECLINED */
232
233 n = offsetof(ngx_rbtree_node_t, color)
234 + offsetof(ngx_http_limit_req_node_t, data)
235 + len;
236
237 node = ngx_slab_alloc_locked(ctx->shpool, n);
238 if (node == NULL) {
239
240 ngx_http_limit_req_expire(ctx, 0);
241
242 node = ngx_slab_alloc_locked(ctx->shpool, n);
243 if (node == NULL) {
244 ngx_shmtx_unlock(&ctx->shpool->mutex);
245 return NGX_HTTP_SERVICE_UNAVAILABLE;
246 }
247 }
248
249 lr = (ngx_http_limit_req_node_t *) &node->color;
250
251 node->key = hash;
252 lr->len = (u_char) len;
253
254 tp = ngx_timeofday();
255 lr->last = (ngx_msec_t) (tp->sec * 1000 + tp->msec);
256
257 lr->excess = 0;
258 ngx_memcpy(lr->data, vv->data, len);
259
260 ngx_rbtree_insert(&ctx->sh->rbtree, node);
261
262 ngx_queue_insert_head(&ctx->sh->queue, &lr->queue);
263
264 done:
265
266 ngx_shmtx_unlock(&ctx->shpool->mutex);
267
268 return NGX_DECLINED;
269 } 266 }
270 267
271 268
272 static void 269 static void
273 ngx_http_limit_req_delay(ngx_http_request_t *r) 270 ngx_http_limit_req_delay(ngx_http_request_t *r)