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);