Mercurial > hg > nginx
comparison src/http/modules/proxy/ngx_http_proxy_handler.c @ 169:edf29bb717da
nginx-0.0.1-2003-10-31-19:05:33 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 31 Oct 2003 16:05:33 +0000 |
parents | ba5dbb949603 |
children | c42be4185301 |
comparison
equal
deleted
inserted
replaced
168:ba5dbb949603 | 169:edf29bb717da |
---|---|
20 static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p); | 20 static void ngx_http_proxy_send_response(ngx_http_proxy_ctx_t *p); |
21 static void ngx_http_proxy_process_body(ngx_event_t *ev); | 21 static void ngx_http_proxy_process_body(ngx_event_t *ev); |
22 | 22 |
23 static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p); | 23 static int ngx_http_proxy_parse_status_line(ngx_http_proxy_ctx_t *p); |
24 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type); | 24 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type); |
25 static int ngx_http_proxy_log_state(ngx_http_proxy_ctx_t *p, int status); | |
25 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); | 26 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc); |
26 static void ngx_http_proxy_close_connection(ngx_connection_t *c); | 27 static void ngx_http_proxy_close_connection(ngx_connection_t *c); |
27 | 28 |
28 static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len); | 29 static size_t ngx_http_proxy_log_error(void *data, char *buf, size_t len); |
29 | 30 |
187 | 188 |
188 { ngx_null_string, 0 } | 189 { ngx_null_string, 0 } |
189 }; | 190 }; |
190 | 191 |
191 | 192 |
192 static char http_version[] = " HTTP/1.0" CRLF; | 193 static char http_version[] = " HTTP/1.0" CRLF; |
193 static char host_header[] = "Host: "; | 194 static char host_header[] = "Host: "; |
194 static char connection_close_header[] = "Connection: close" CRLF; | 195 static char connection_close_header[] = "Connection: close" CRLF; |
195 | 196 |
196 | 197 |
197 | 198 |
198 static int ngx_http_proxy_handler(ngx_http_request_t *r) | 199 static int ngx_http_proxy_handler(ngx_http_request_t *r) |
199 { | 200 { |
204 NGX_HTTP_INTERNAL_SERVER_ERROR); | 205 NGX_HTTP_INTERNAL_SERVER_ERROR); |
205 | 206 |
206 p->lcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); | 207 p->lcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module); |
207 p->upstream.peers = p->lcf->peers; | 208 p->upstream.peers = p->lcf->peers; |
208 p->upstream.tries = p->lcf->peers->number; | 209 p->upstream.tries = p->lcf->peers->number; |
210 | |
211 ngx_init_array(p->states, r->pool, p->upstream.tries, | |
212 sizeof(ngx_http_proxy_state_t), | |
213 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
209 | 214 |
210 p->request = r; | 215 p->request = r; |
211 p->method = r->method; | 216 p->method = r->method; |
212 | 217 |
213 /* TODO: we currently support reverse proxy only */ | 218 /* TODO: we currently support reverse proxy only */ |
469 } | 474 } |
470 | 475 |
471 if (rc == NGX_CONNECT_ERROR) { | 476 if (rc == NGX_CONNECT_ERROR) { |
472 ngx_event_connect_peer_failed(&p->upstream); | 477 ngx_event_connect_peer_failed(&p->upstream); |
473 | 478 |
474 #if 0 | 479 if (ngx_http_proxy_log_state(p, NGX_HTTP_BAD_GATEWAY) == NGX_ERROR) |
475 /* TODO: make separate func and call it from next_upstream */ | 480 { |
476 | |
477 if (!(state = ngx_push_array(p->states))) { | |
478 ngx_http_proxy_finalize_request(p, | 481 ngx_http_proxy_finalize_request(p, |
479 NGX_HTTP_INTERNAL_SERVER_ERROR); | 482 NGX_HTTP_INTERNAL_SERVER_ERROR); |
480 return NGX_DONE; | 483 return NGX_DONE; |
481 } | 484 } |
482 | |
483 state->status = NGX_HTTP_BAD_GATEWAY; | |
484 state->peer = | |
485 p->upstream.peers->peers[p->upstream.cur_peer].addr_port_text; | |
486 | |
487 #endif | |
488 | 485 |
489 if (p->upstream.tries == 0) { | 486 if (p->upstream.tries == 0) { |
490 ngx_http_proxy_finalize_request(p, NGX_HTTP_BAD_GATEWAY); | 487 ngx_http_proxy_finalize_request(p, NGX_HTTP_BAD_GATEWAY); |
491 return NGX_DONE; | 488 return NGX_DONE; |
492 } | 489 } |
515 | 512 |
516 p->request_sent = 0; | 513 p->request_sent = 0; |
517 p->timedout = 0; | 514 p->timedout = 0; |
518 | 515 |
519 if (rc == NGX_OK) { | 516 if (rc == NGX_OK) { |
520 return ngx_http_proxy_send_request(p); | 517 return ngx_http_proxy_send_request0(p); |
521 } | 518 } |
522 | 519 |
523 /* rc == NGX_AGAIN */ | 520 /* rc == NGX_AGAIN */ |
524 | 521 |
525 ngx_add_timer(c->write, p->lcf->connect_timeout); | 522 ngx_add_timer(c->write, p->lcf->connect_timeout); |
526 | 523 |
527 return NGX_AGAIN; | 524 return NGX_AGAIN; |
528 } | 525 } |
529 } | 526 } |
527 | |
528 | |
529 static int ngx_http_proxy_send_request0(ngx_http_proxy_ctx_t *p) | |
530 { | |
531 ngx_connection_t *c; | |
532 ngx_chain_writer_ctx_t *wctx; | |
533 | |
534 c = p->upstream.connection; | |
535 | |
536 p->action = "sending request to upstream"; | |
537 wctx = p->output_chain_ctx->output_ctx; | |
538 wctx->connection = c; | |
539 rc = ngx_output_chain(p->output_chain_ctx, | |
540 !p->request_sent ? p->request->request_hunks: | |
541 NULL); | |
542 if (rc == NGX_ERROR) { | |
543 return ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR); | |
544 } | |
545 | |
546 p->request_sent = 1; | |
547 | |
548 if (c->write->timer_set) { | |
549 ngx_del_timer(c->write); | |
550 } | |
551 | |
552 if (rc == NGX_AGAIN) { | |
553 ngx_add_timer(c->write, p->lcf->send_timeout); | |
554 | |
555 if (ngx_handle_write_event(c->write, /* STUB: lowat */ 0) == NGX_ERROR) | |
556 { | |
557 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
558 return; | |
559 } | |
560 | |
561 return NGX_AGAIN; | |
562 } | |
563 | |
564 /* rc == NGX_OK */ | |
565 | |
566 if (c->read->ready) { | |
567 /* post aio operation */ | |
568 ngx_http_proxy_process_upstream_status_line(c->read); | |
569 } | |
570 | |
571 if (ngx_handle_level_write_event(c->write) == NGX_ERROR) { | |
572 ngx_http_proxy_finalize_request(p, | |
573 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
574 return; | |
575 } | |
576 | |
577 if (c->tcp_nopush) { | |
578 if (ngx_tcp_push(c->fd) == NGX_ERROR) { | |
579 ngx_log_error(NGX_LOG_CRIT, c->log, | |
580 ngx_socket_errno, | |
581 ngx_tcp_push_n " failed"); | |
582 ngx_http_proxy_finalize_request(p, | |
583 NGX_HTTP_INTERNAL_SERVER_ERROR); | |
584 return; | |
585 } | |
586 | |
587 c->tcp_nopush = 0; | |
588 } | |
589 } | |
590 | |
591 return; | |
592 } | |
593 | |
594 ngx_http_proxy_next_upstream(p, NGX_HTTP_PROXY_FT_ERROR); | |
595 | |
596 return NGX_OK; | |
597 } | |
598 | |
530 | 599 |
531 #endif | 600 #endif |
532 | 601 |
533 | 602 |
534 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) | 603 static void ngx_http_proxy_send_request(ngx_http_proxy_ctx_t *p) |
1389 } | 1458 } |
1390 | 1459 |
1391 | 1460 |
1392 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type) | 1461 static void ngx_http_proxy_next_upstream(ngx_http_proxy_ctx_t *p, int ft_type) |
1393 { | 1462 { |
1463 int status; | |
1464 | |
1394 ngx_event_connect_peer_failed(&p->upstream); | 1465 ngx_event_connect_peer_failed(&p->upstream); |
1395 | 1466 |
1396 if (p->timedout) { | 1467 if (p->timedout) { |
1397 ngx_log_error(NGX_LOG_ERR, p->request->connection->log, NGX_ETIMEDOUT, | 1468 ngx_log_error(NGX_LOG_ERR, p->request->connection->log, NGX_ETIMEDOUT, |
1398 "upstream timed out"); | 1469 "upstream timed out"); |
1401 if (p->upstream.connection) { | 1472 if (p->upstream.connection) { |
1402 ngx_http_proxy_close_connection(p->upstream.connection); | 1473 ngx_http_proxy_close_connection(p->upstream.connection); |
1403 p->upstream.connection = NULL; | 1474 p->upstream.connection = NULL; |
1404 } | 1475 } |
1405 | 1476 |
1477 if (ft_type == NGX_HTTP_PROXY_FT_TIMEOUT) { | |
1478 status = NGX_HTTP_GATEWAY_TIME_OUT; | |
1479 | |
1480 } else { | |
1481 status = NGX_HTTP_BAD_GATEWAY; | |
1482 } | |
1483 | |
1484 if (ngx_http_proxy_log_state(p, status) == NGX_ERROR) { | |
1485 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1486 return; | |
1487 } | |
1488 | |
1406 if (p->upstream.tries == 0 || !(p->lcf->next_upstream & ft_type)) { | 1489 if (p->upstream.tries == 0 || !(p->lcf->next_upstream & ft_type)) { |
1407 ngx_http_proxy_finalize_request(p, | 1490 ngx_http_proxy_finalize_request(p, status); |
1408 p->timedout ? NGX_HTTP_GATEWAY_TIME_OUT: | |
1409 NGX_HTTP_BAD_GATEWAY); | |
1410 return; | 1491 return; |
1411 } | 1492 } |
1412 | 1493 |
1413 if (!p->fatal_error) { | 1494 if (!p->fatal_error) { |
1414 ngx_http_proxy_send_request(p); | 1495 ngx_http_proxy_send_request(p); |
1417 | 1498 |
1418 ngx_log_debug(p->request->connection->log, "FATAL ERROR IN NEXT UPSTREAM"); | 1499 ngx_log_debug(p->request->connection->log, "FATAL ERROR IN NEXT UPSTREAM"); |
1419 | 1500 |
1420 return; | 1501 return; |
1421 } | 1502 } |
1503 | |
1504 | |
1505 static int ngx_http_proxy_log_state(ngx_http_proxy_ctx_t *p, int status) | |
1506 { | |
1507 ngx_http_proxy_state_t *state; | |
1508 | |
1509 if (!(state = ngx_push_array(&p->states))) { | |
1510 return NGX_ERROR; | |
1511 } | |
1512 | |
1513 state->status = status; | |
1514 state->peer = | |
1515 &p->upstream.peers->peers[p->upstream.cur_peer].addr_port_text; | |
1516 | |
1517 return NGX_OK; | |
1518 } | |
1519 | |
1422 | 1520 |
1423 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc) | 1521 static void ngx_http_proxy_finalize_request(ngx_http_proxy_ctx_t *p, int rc) |
1424 { | 1522 { |
1425 ngx_log_debug(p->request->connection->log, | 1523 ngx_log_debug(p->request->connection->log, |
1426 "finalize http proxy request"); | 1524 "finalize http proxy request"); |
1443 | 1541 |
1444 p->fatal_error = 1; | 1542 p->fatal_error = 1; |
1445 | 1543 |
1446 return; | 1544 return; |
1447 } | 1545 } |
1448 | |
1449 | 1546 |
1450 | 1547 |
1451 static void ngx_http_proxy_close_connection(ngx_connection_t *c) | 1548 static void ngx_http_proxy_close_connection(ngx_connection_t *c) |
1452 { | 1549 { |
1453 ngx_log_debug(c->log, "close connection: %d" _ c->fd); | 1550 ngx_log_debug(c->log, "close connection: %d" _ c->fd); |