comparison src/http/modules/proxy/ngx_http_proxy_upstream.c @ 175:e92c2c647c57

nginx-0.0.1-2003-11-05-20:03:41 import
author Igor Sysoev <igor@sysoev.ru>
date Wed, 05 Nov 2003 17:03:41 +0000
parents ea464a6c0581
children c0552e5ab567
comparison
equal deleted inserted replaced
174:ea464a6c0581 175:e92c2c647c57
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);
14 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p); 16 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p);
15 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p); 17 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p);
16 static void ngx_http_proxy_send_request_handler(ngx_event_t *wev); 18 static void ngx_http_proxy_send_request_handler(ngx_event_t *wev);
17 static void ngx_http_proxy_dummy_handler(ngx_event_t *wev); 19 static void ngx_http_proxy_dummy_handler(ngx_event_t *wev);
18 static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev); 20 static void ngx_http_proxy_process_upstream_status_line(ngx_event_t *rev);
262 264
263 octx->output_ctx = wctx; 265 octx->output_ctx = wctx;
264 266
265 wctx->pool = r->pool; 267 wctx->pool = r->pool;
266 268
267 ngx_http_proxy_connect(p); 269 if (p->lcf->busy_lock) {
270 ngx_http_proxy_upstream_busy_lock(p);
271 } else {
272 ngx_http_proxy_connect(p);
273 }
268 } 274 }
269 275
270 276
271 static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p) 277 static void ngx_http_proxy_reinit_upstream(ngx_http_proxy_ctx_t *p)
272 { 278 {
301 } 307 }
302 } 308 }
303 309
304 p->status = 0; 310 p->status = 0;
305 p->status_count = 0; 311 p->status_count = 0;
312 }
313
314
315 static void ngx_http_proxy_upstream_busy_lock(ngx_http_proxy_ctx_t *p)
316 {
317 int ft_type;
318
319 if (p->lcf->busy_lock->conn_n < p->lcf->busy_lock->max_conn) {
320 p->lcf->busy_lock->conn_n++;
321
322 if (p->busy_lock_time) {
323 p->busy_lock_time = 0;
324 p->lcf->busy_lock->waiting_n--;
325 }
326
327 ngx_http_proxy_connect(p);
328 return;
329 }
330
331 if (p->busy_lock_time) {
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;
339
340 } else {
341 if (p->lcf->busy_lock->waiting_n < p->lcf->busy_lock->max_waiting) {
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;
351 }
352
353 if (p->stale && (p->lcf->use_stale & ft_type)) {
354 ngx_http_proxy_finalize_request(p,
355 ngx_http_proxy_send_cached_response(p));
356 return;
357 }
358
359 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
306 } 415 }
307 416
308 417
309 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p) 418 static void ngx_http_proxy_connect(ngx_http_proxy_ctx_t *p)
310 { 419 {
1009 return; 1118 return;
1010 } 1119 }
1011 } 1120 }
1012 1121
1013 if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) { 1122 if (ep->upstream_done || ep->upstream_eof || ep->upstream_error) {
1014 ngx_http_proxy_close_connection(p->upstream->peer.connection); 1123 ngx_http_proxy_close_connection(p);
1015 p->upstream->peer.connection = NULL;
1016 } 1124 }
1017 } 1125 }
1018 1126
1019 if (ep->downstream_done) { 1127 if (ep->downstream_done) {
1020 ngx_log_debug(ev->log, "http proxy downstream done"); 1128 ngx_log_debug(ev->log, "http proxy downstream done");
1022 return; 1130 return;
1023 } 1131 }
1024 1132
1025 if (ep->downstream_error) { 1133 if (ep->downstream_error) {
1026 if (!p->cachable && p->upstream->peer.connection) { 1134 if (!p->cachable && p->upstream->peer.connection) {
1027 ngx_http_proxy_close_connection(p->upstream->peer.connection); 1135 ngx_http_proxy_close_connection(p);
1028 p->upstream->peer.connection = NULL;
1029 } 1136 }
1030 1137
1031 if (p->upstream->peer.connection == NULL) { 1138 if (p->upstream->peer.connection == NULL) {
1032 ngx_http_close_connection(c); 1139 ngx_http_close_connection(c);
1033 } 1140 }
1078 status = NGX_HTTP_BAD_GATEWAY; 1185 status = NGX_HTTP_BAD_GATEWAY;
1079 } 1186 }
1080 } 1187 }
1081 1188
1082 if (p->upstream->peer.connection) { 1189 if (p->upstream->peer.connection) {
1083 ngx_http_proxy_close_connection(p->upstream->peer.connection); 1190 ngx_http_proxy_close_connection(p);
1084 p->upstream->peer.connection = NULL;
1085 } 1191 }
1086 1192
1087 if (status) { 1193 if (status) {
1088 p->state->status = status; 1194 p->state->status = status;
1089 1195
1098 ngx_http_proxy_finalize_request(p, status); 1204 ngx_http_proxy_finalize_request(p, status);
1099 return; 1205 return;
1100 } 1206 }
1101 } 1207 }
1102 1208
1103 ngx_http_proxy_connect(p); 1209 if (p->lcf->busy_lock) {
1104 } 1210 ngx_http_proxy_upstream_busy_lock(p);
1211 } else {
1212 ngx_http_proxy_connect(p);
1213 }
1214 }