comparison src/http/modules/proxy/ngx_http_proxy_upstream.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
9 9
10 10
11 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p); 11 static ngx_chain_t *ngx_http_proxy_create_request(ngx_http_proxy_ctx_t *p);
12 static void ngx_http_proxy_init_upstream(void *data); 12 static void ngx_http_proxy_init_upstream(void *data);
13 static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p); 13 static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p);
14 static void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p);
15 static void ngx_http_proxy_upstream_busy_lock_handler(ngx_event_t *rev);
16 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p); 14 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p);
17 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); 15 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p);
18 static void ngx_http_proxy_send_request_handler(ngx_event_t *wev); 16 static void ngx_http_proxy_send_request_handler(ngx_event_t *wev);
19 static void ngx_http_proxy_dummy_handler(ngx_event_t *wev); 17 static void ngx_http_proxy_dummy_handler(ngx_event_t *wev);
20 static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev); 18 static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev);
264 262
265 octx->output_ctx = wctx; 263 octx->output_ctx = wctx;
266 264
267 wctx->pool = r->pool; 265 wctx->pool = r->pool;
268 266
269 if (p->lcf->busy_lock) { 267 if (p->lcf->busy_lock && !p->busy_locked) {
270 ngx_http_proxy_upstream_busy_lock(p); 268 ngx_http_proxy_upstream_busy_lock(p);
271 } else { 269 } else {
272 ngx_http_proxy_connect(p); 270 ngx_http_proxy_connect(p);
273 } 271 }
274 } 272 }
310 p->status = 0; 308 p->status = 0;
311 p->status_count = 0; 309 p->status_count = 0;
312 } 310 }
313 311
314 312
315 static void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p) 313 void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p)
316 { 314 {
317 int ft_type; 315 int rc, ft_type;
318 316
319 if (p->lcf->busy_lock->conn_n < p->lcf->busy_lock->max_conn) { 317 if (p->busy_lock.time == 0) {
320 p->lcf->busy_lock->conn_n++; 318 p->busy_lock.event = p->request->connection->read;
321 319 p->busy_lock.event_handler = ngx_http_proxy_busy_lock_handler;
322 if (p->busy_lock_time) { 320 }
323 p->busy_lock_time = 0; 321
324 p->lcf->busy_lock->waiting_n--; 322 rc = ngx_http_busy_lock(p->lcf->busy_lock, &p->busy_lock);
325 } 323
326 324 if (rc == NGX_AGAIN) {
325 return;
326 }
327
328 if (rc == NGX_OK) {
327 ngx_http_proxy_connect(p); 329 ngx_http_proxy_connect(p);
328 return; 330 return;
329 } 331 }
330 332
331 if (p->busy_lock_time) { 333 if (rc == NGX_DONE) {
332 if (p->busy_lock_time < p->lcf->busy_lock->timeout) {
333 ngx_add_timer(p->request->connection->read, 1000);
334 return;
335 }
336
337 p->lcf->busy_lock->waiting_n--;
338 ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK; 334 ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK;
339 335
340 } else { 336 } else {
341 if (p->lcf->busy_lock->waiting_n < p->lcf->busy_lock->max_waiting) { 337 /* rc == NGX_ERROR */
342 p->lcf->busy_lock->waiting_n++;
343 ngx_add_timer(p->request->connection->read, 1000);
344 p->request->connection->read->event_handler =
345 ngx_http_proxy_upstream_busy_lock_handler;
346 /* TODO: ngx_handle_level_read_event() */
347 return;
348 }
349
350 ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING; 338 ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING;
351 } 339 }
352 340
353 if (p->stale && (p->lcf->use_stale & ft_type)) { 341 if (p->stale && (p->lcf->use_stale & ft_type)) {
354 ngx_http_proxy_finalize_request(p, 342 ngx_http_proxy_finalize_request(p,
355 ngx_http_proxy_send_cached_response(p)); 343 ngx_http_proxy_send_cached_response(p));
356 return; 344 return;
357 } 345 }
358 346
359 ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE); 347 ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE);
360 return;
361 }
362
363
364 static void ngx_http_proxy_upstream_busy_lock_handler(ngx_event_t *rev)
365 {
366 ngx_connection_t *c;
367 ngx_http_request_t *r;
368 ngx_http_proxy_ctx_t *p;
369
370 ngx_log_debug(rev->log, "busy lock");
371
372 c = rev->data;
373 r = c->data;
374 p = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
375 p->action = "waiting upstream in busy lock";
376
377 if (rev->timedout) {
378 rev->timedout = 0;
379 p->busy_lock_time++;
380 ngx_http_proxy_upstream_busy_lock(p);
381 return;
382 }
383
384 ngx_log_debug(rev->log, "client sent while busy lock");
385
386 /*
387 * TODO: kevent() notify about error, otherwise we need to
388 * call ngx_peek(): recv(MGS_PEEK) to get errno. THINK about aio
389 * if there's no error we need to disable event.
390 */
391
392 #if (HAVE_KQUEUE)
393
394 if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && rev->kq_eof) {
395 p->lcf->busy_lock->waiting_n--;
396
397 ngx_del_timer(rev);
398
399 ngx_log_error(NGX_LOG_ERR, c->log, rev->kq_errno,
400 "client() closed connection");
401
402 if (ngx_del_event(rev, NGX_READ_EVENT, NGX_CLOSE_EVENT) == NGX_ERROR) {
403 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
404 return;
405 }
406
407 /* we have not HTTP code for the case when a client cancels a request */
408
409 ngx_http_proxy_finalize_request(p, 0);
410 return;
411 }
412
413 #endif
414
415 } 348 }
416 349
417 350
418 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) 351 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
419 { 352 {
722 655
723 return; 656 return;
724 } 657 }
725 } 658 }
726 659
660 if (p->status == NGX_HTTP_NOT_FOUND
661 && p->upstream->peer.tries > 1
662 && p->lcf->next_upstream & NGX_HTTP_PROXY_FT_HTTP_404)
663 {
664 ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_HTTP_404);
665 return;
666 }
667
668 /* TODO: "proxy_error_page" */
669
727 p->upstream->status_line.len = p->status_end - p->status_start; 670 p->upstream->status_line.len = p->status_end - p->status_start;
728 p->upstream->status_line.data = ngx_palloc(p->request->pool, 671 p->upstream->status_line.data = ngx_palloc(p->request->pool,
729 p->upstream->status_line.len + 1); 672 p->upstream->status_line.len + 1);
730 if (p->upstream->status_line.data == NULL) { 673 if (p->upstream->status_line.data == NULL) {
731 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); 674 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
738 p->upstream->status _ p->upstream->status_line.data); 681 p->upstream->status _ p->upstream->status_line.data);
739 682
740 if (p->upstream->headers_in.headers) { 683 if (p->upstream->headers_in.headers) {
741 p->upstream->headers_in.headers->nelts = 0; 684 p->upstream->headers_in.headers->nelts = 0;
742 } else { 685 } else {
686 /* TODO: ngx_init_table */
743 p->upstream->headers_in.headers = ngx_create_table(p->request->pool, 687 p->upstream->headers_in.headers = ngx_create_table(p->request->pool,
744 20); 688 20);
745 } 689 }
746 690
747 c->read->event_handler = ngx_http_proxy_process_upstream_headers; 691 c->read->event_handler = ngx_http_proxy_process_upstream_headers;
954 header = (ngx_http_cache_header_t *) p->header_in->start; 898 header = (ngx_http_cache_header_t *) p->header_in->start;
955 899
956 header->expires = p->cache->ctx.expires; 900 header->expires = p->cache->ctx.expires;
957 header->last_modified = p->cache->ctx.last_modified; 901 header->last_modified = p->cache->ctx.last_modified;
958 header->date = p->cache->ctx.date; 902 header->date = p->cache->ctx.date;
959 /* TODO: r->headers_out.content_length_n == -1 */
960 header->length = r->headers_out.content_length_n; 903 header->length = r->headers_out.content_length_n;
904 p->cache->ctx.length = r->headers_out.content_length_n;
961 905
962 header->key_len = p->cache->ctx.key.len; 906 header->key_len = p->cache->ctx.key.len;
963 ngx_memcpy(&header->key, p->cache->ctx.key.data, header->key_len); 907 ngx_memcpy(&header->key, p->cache->ctx.key.data, header->key_len);
964 header->key[header->key_len] = LF; 908 header->key[header->key_len] = LF;
965 } 909 }
1103 } 1047 }
1104 1048
1105 if (p->upstream->peer.connection) { 1049 if (p->upstream->peer.connection) {
1106 if (ep->upstream_done && p->cachable) { 1050 if (ep->upstream_done && p->cachable) {
1107 if (ngx_http_proxy_update_cache(p) == NGX_ERROR) { 1051 if (ngx_http_proxy_update_cache(p) == NGX_ERROR) {
1052 ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock);
1108 ngx_http_proxy_finalize_request(p, 0); 1053 ngx_http_proxy_finalize_request(p, 0);
1109 return; 1054 return;
1110 } 1055 }
1111 1056
1057 ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock);
1058
1112 } else if (ep->upstream_eof && p->cachable) { 1059 } else if (ep->upstream_eof && p->cachable) {
1113 1060
1114 /* TODO: check length & update cache */ 1061 /* TODO: check length & update cache */
1115 1062
1116 if (ngx_http_proxy_update_cache(p) == NGX_ERROR) { 1063 if (ngx_http_proxy_update_cache(p) == NGX_ERROR) {
1064 ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock);
1117 ngx_http_proxy_finalize_request(p, 0); 1065 ngx_http_proxy_finalize_request(p, 0);
1118 return; 1066 return;
1119 } 1067 }
1068
1069 ngx_http_busy_unlock_cachable(p->lcf->busy_lock, &p->busy_lock);
1120 } 1070 }
1121 1071
1122 if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { 1072 if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) {
1123 ngx_http_proxy_close_connection(p); 1073 ngx_http_proxy_close_connection(p);
1124 } 1074 }
1204 ngx_http_proxy_finalize_request(p, status); 1154 ngx_http_proxy_finalize_request(p, status);
1205 return; 1155 return;
1206 } 1156 }
1207 } 1157 }
1208 1158
1209 if (p->lcf->busy_lock) { 1159 if (p->lcf->busy_lock && !p->busy_locked) {
1210 ngx_http_proxy_upstream_busy_lock(p); 1160 ngx_http_proxy_upstream_busy_lock(p);
1211 } else { 1161 } else {
1212 ngx_http_proxy_connect(p); 1162 ngx_http_proxy_connect(p);
1213 } 1163 }
1214 } 1164 }