Mercurial > hg > nginx
comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 176:c0552e5ab567
nginx-0.0.1-2003-11-09-23:03:38 import; separate building
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 09 Nov 2003 20:03:38 +0000 |
parents | e92c2c647c57 |
children | 4db54fdbcbe7 |
comparison
equal
deleted
inserted
replaced
175:e92c2c647c57 | 176:c0552e5ab567 |
---|---|
130 offsetof(ngx_http_proxy_loc_conf_t, cache), | 130 offsetof(ngx_http_proxy_loc_conf_t, cache), |
131 NULL }, | 131 NULL }, |
132 | 132 |
133 | 133 |
134 { ngx_string("proxy_busy_lock"), | 134 { ngx_string("proxy_busy_lock"), |
135 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE3, | 135 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE13, |
136 ngx_http_set_busy_lock_slot, | 136 ngx_http_set_busy_lock_slot, |
137 NGX_HTTP_LOC_CONF_OFFSET, | 137 NGX_HTTP_LOC_CONF_OFFSET, |
138 offsetof(ngx_http_proxy_loc_conf_t, busy_lock), | 138 offsetof(ngx_http_proxy_loc_conf_t, busy_lock), |
139 NULL }, | 139 NULL }, |
140 | 140 |
238 | 238 |
239 { ngx_null_string, 0 } | 239 { ngx_null_string, 0 } |
240 }; | 240 }; |
241 | 241 |
242 | 242 |
243 static ngx_str_t cache_states[] = { | |
244 ngx_string("PASS"), | |
245 ngx_string("BYPASS"), | |
246 ngx_string("AUTH"), | |
247 ngx_string("PGNC"), | |
248 ngx_string("MISS"), | |
249 ngx_string("EXPR"), | |
250 ngx_string("AGED"), | |
251 ngx_string("HIT") | |
252 }; | |
253 | |
254 | |
255 static ngx_str_t cache_reason[] = { | |
256 ngx_string("BPS"), | |
257 ngx_string("XAE"), | |
258 ngx_string("CTL"), | |
259 ngx_string("EXP"), | |
260 ngx_string("MVD"), | |
261 ngx_string("LMF"), | |
262 ngx_string("PDE") | |
263 }; | |
264 | |
265 | |
243 static int ngx_http_proxy_handler(ngx_http_request_t *r) | 266 static int ngx_http_proxy_handler(ngx_http_request_t *r) |
244 { | 267 { |
245 int rc; | |
246 ngx_http_proxy_ctx_t *p; | 268 ngx_http_proxy_ctx_t *p; |
247 | 269 |
248 ngx_http_create_ctx(r, p, ngx_http_proxy_module, | 270 ngx_http_create_ctx(r, p, ngx_http_proxy_module, |
249 sizeof(ngx_http_proxy_ctx_t), | 271 sizeof(ngx_http_proxy_ctx_t), |
250 NGX_HTTP_INTERNAL_SERVER_ERROR); | 272 NGX_HTTP_INTERNAL_SERVER_ERROR); |
267 | 289 |
268 | 290 |
269 if (!p->lcf->cache | 291 if (!p->lcf->cache |
270 || (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD)) | 292 || (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD)) |
271 { | 293 { |
272 p->state->cache = NGX_HTTP_PROXY_CACHE_PASS; | 294 p->state->cache_state = NGX_HTTP_PROXY_CACHE_PASS; |
273 | 295 |
274 } else if (r->bypass_cache) { | 296 } else if (r->bypass_cache) { |
275 p->state->cache = NGX_HTTP_PROXY_CACHE_BYPASS; | 297 p->state->cache_state = NGX_HTTP_PROXY_CACHE_BYPASS; |
276 | 298 |
277 } else if (r->headers_in.authorization) { | 299 } else if (r->headers_in.authorization) { |
278 p->state->cache = NGX_HTTP_PROXY_CACHE_AUTH; | 300 p->state->cache_state = NGX_HTTP_PROXY_CACHE_AUTH; |
279 | 301 |
280 } else if (r->no_cache) { | 302 } else if (r->no_cache) { |
281 p->state->cache = NGX_HTTP_PROXY_CACHE_PGNC; | 303 p->state->cache_state = NGX_HTTP_PROXY_CACHE_PGNC; |
282 p->cachable = 1; | 304 p->cachable = 1; |
283 | 305 |
284 } else { | 306 } else { |
285 p->cachable = 1; | 307 p->cachable = 1; |
286 } | 308 } |
287 | 309 |
288 | 310 |
289 if (p->state->cache) { | 311 if (p->state->cache_state != 0) { |
290 return ngx_http_proxy_request_upstream(p); | 312 return ngx_http_proxy_request_upstream(p); |
291 } | 313 } |
292 | 314 |
293 rc = ngx_http_proxy_get_cached_response(p); | 315 return ngx_http_proxy_get_cached_response(p); |
294 | 316 } |
295 if (rc == NGX_DONE || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { | 317 |
296 return rc; | 318 |
297 } | 319 void ngx_http_proxy_busy_lock_handler(ngx_event_t *rev) |
298 | 320 { |
299 p->valid_header_in = 1; | 321 ngx_connection_t *c; |
300 | 322 ngx_http_request_t *r; |
301 if (rc == NGX_OK) { | 323 ngx_http_proxy_ctx_t *p; |
302 return ngx_http_proxy_send_cached_response(p); | 324 |
303 } | 325 ngx_log_debug(rev->log, "busy lock"); |
304 | 326 |
305 /* rc == NGX_DECLINED || NGX_HTTP_CACHE_STALE || NGX_HTTP_CACHE_AGED */ | 327 c = rev->data; |
306 | 328 r = c->data; |
307 return ngx_http_proxy_request_upstream(p); | 329 p = ngx_http_get_module_ctx(r, ngx_http_proxy_module); |
330 p->action = "waiting upstream in busy lock"; | |
331 | |
332 if (rev->timedout) { | |
333 rev->timedout = 0; | |
334 p->busy_lock.time++; | |
335 p->state->bl_time = p->busy_lock.time; | |
336 if (p->state->cache_state < NGX_HTTP_PROXY_CACHE_MISS) { | |
337 ngx_http_proxy_upstream_busy_lock(p); | |
338 | |
339 } else { | |
340 ngx_http_proxy_cache_busy_lock(p); | |
341 } | |
342 | |
343 return; | |
344 } | |
345 | |
346 ngx_log_debug(rev->log, "client sent while busy lock"); | |
347 | |
348 /* | |
349 * TODO: kevent() notify about error, otherwise we need to | |
350 * call ngx_peek(): recv(MGS_PEEK) to get errno. THINK about aio | |
351 * if there's no error we need to disable event. | |
352 */ | |
353 | |
354 #if (HAVE_KQUEUE) | |
355 | |
356 if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && rev->kq_eof) { | |
357 p->lcf->busy_lock->waiting--; | |
358 | |
359 ngx_del_timer(rev); | |
360 | |
361 ngx_log_error(NGX_LOG_ERR, c->log, rev->kq_errno, | |
362 "client() closed connection"); | |
363 | |
364 if (ngx_del_event(rev, NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) { | |
365 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
366 return; | |
367 } | |
368 | |
369 /* we have not HTTP code for the case when a client cancels a request */ | |
370 | |
371 ngx_http_proxy_finalize_request(p, 0); | |
372 return; | |
373 } | |
374 | |
375 #endif | |
376 | |
308 } | 377 } |
309 | 378 |
310 | 379 |
311 void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc) | 380 void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc) |
312 { | 381 { |
313 ngx_log_debug(p->request->connection->log, | 382 ngx_log_debug(p->request->connection->log, |
314 "finalize http proxy request"); | 383 "finalize http proxy request"); |
315 | 384 |
316 if (p->upstream->peer.connection) { | 385 if (p->upstream && p->upstream->peer.connection) { |
317 ngx_http_proxy_close_connection(p); | 386 ngx_http_proxy_close_connection(p); |
318 } | 387 } |
319 | 388 |
320 if (p->header_sent | 389 if (p->header_sent |
321 && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) | 390 && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE)) |
322 { | 391 { |
323 rc = 0; | 392 rc = 0; |
324 } | 393 } |
325 | 394 |
326 p->request->connection->log->data = p->saved_ctx; | 395 if (p->saved_ctx) { |
327 p->request->connection->log->handler = p->saved_handler; | 396 p->request->connection->log->data = p->saved_ctx; |
397 p->request->connection->log->handler = p->saved_handler; | |
398 } | |
328 | 399 |
329 ngx_http_finalize_request(p->request, rc); | 400 ngx_http_finalize_request(p->request, rc); |
330 } | 401 } |
331 | 402 |
332 | 403 |
336 | 407 |
337 c = p->upstream->peer.connection; | 408 c = p->upstream->peer.connection; |
338 p->upstream->peer.connection = NULL; | 409 p->upstream->peer.connection = NULL; |
339 | 410 |
340 if (p->lcf->busy_lock) { | 411 if (p->lcf->busy_lock) { |
341 p->lcf->busy_lock->conn_n--; | 412 p->lcf->busy_lock->busy--; |
342 } | 413 } |
343 | 414 |
344 ngx_log_debug(c->log, "proxy close connection: %d" _ c->fd); | 415 ngx_log_debug(c->log, "proxy close connection: %d" _ c->fd); |
345 | 416 |
346 if (c->fd == -1) { | 417 if (c->fd == -1) { |
377 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, | 448 ngx_log_error(NGX_LOG_ALERT, c->log, ngx_socket_errno, |
378 ngx_close_socket_n " failed"); | 449 ngx_close_socket_n " failed"); |
379 } | 450 } |
380 | 451 |
381 c->fd = -1; | 452 c->fd = -1; |
453 } | |
454 | |
455 | |
456 size_t ngx_http_proxy_log_state(void *data, char *buf, size_t len) | |
457 { | |
458 return 0; | |
382 } | 459 } |
383 | 460 |
384 | 461 |
385 size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len) | 462 size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len) |
386 { | 463 { |
511 | 588 |
512 if (conf->busy_lock == NULL) { | 589 if (conf->busy_lock == NULL) { |
513 conf->busy_lock = prev->busy_lock; | 590 conf->busy_lock = prev->busy_lock; |
514 } | 591 } |
515 | 592 |
516 if (conf->busy_lock && conf->cache && conf->busy_lock->busy == NULL) { | 593 if (conf->busy_lock && conf->cache && conf->busy_lock->md5 == NULL) { |
594 | |
595 /* ngx_calloc_shared() */ | |
596 conf->busy_lock->md5_mask = | |
597 ngx_pcalloc(cf->pool, (conf->busy_lock->max_busy + 7) / 8); | |
598 if (conf->busy_lock->md5_mask == NULL) { | |
599 return NGX_CONF_ERROR; | |
600 } | |
601 | |
602 /* 16 bytes are 128 bits of the md5 */ | |
517 | 603 |
518 /* ngx_alloc_shared() */ | 604 /* ngx_alloc_shared() */ |
519 conf->busy_lock->busy_mask = | 605 conf->busy_lock->md5 = ngx_palloc(cf->pool, |
520 ngx_palloc(cf->pool, (conf->busy_lock->max_conn + 7) / 8); | 606 16 * conf->busy_lock->max_busy); |
521 if (conf->busy_lock->busy_mask == NULL) { | 607 if (conf->busy_lock->md5 == NULL) { |
522 return NGX_CONF_ERROR; | |
523 } | |
524 | |
525 /* 16 bytes are 128 bits of the md5 */ | |
526 | |
527 /* ngx_alloc_shared() */ | |
528 conf->busy_lock->busy = ngx_palloc(cf->pool, | |
529 16 * conf->busy_lock->max_conn); | |
530 if (conf->busy_lock->busy == NULL) { | |
531 return NGX_CONF_ERROR; | 608 return NGX_CONF_ERROR; |
532 } | 609 } |
533 } | 610 } |
534 | 611 |
535 | 612 |