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