Mercurial > hg > nginx
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 } |