comparison src/core/ngx_inet.c @ 252:644510700914 NGINX_0_4_11

nginx 0.4.11 *) Feature: the POP3 proxy supports the AUTH LOGIN PLAIN and CRAM-MD5. *) Feature: the ngx_http_perl_module supports the $r->allow_ranges method. *) Bugfix: if the APOP was enabled in the POP3 proxy, then the USER/PASS commands might not work; bug appeared in 0.4.10.
author Igor Sysoev <http://sysoev.ru>
date Wed, 25 Oct 2006 00:00:00 +0400
parents c982febb7588
children 0effe91f6083
comparison
equal deleted inserted replaced
251:16ffa8ae5759 252:644510700914
221 221
222 222
223 ngx_int_t 223 ngx_int_t
224 ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u) 224 ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
225 { 225 {
226 u_char *p; 226 u_char *p, *host;
227 size_t len; 227 size_t len;
228 ngx_int_t port; 228 ngx_int_t port;
229 ngx_uint_t i; 229 ngx_uint_t i;
230 struct hostent *h;
230 #if (NGX_HAVE_UNIX_DOMAIN) 231 #if (NGX_HAVE_UNIX_DOMAIN)
231 struct sockaddr_un *saun; 232 struct sockaddr_un *saun;
232 #endif 233 #endif
233 234
234 len = u->url.len; 235 len = u->url.len;
388 u->portn = (in_port_t) port; 389 u->portn = (in_port_t) port;
389 390
390 port: 391 port:
391 392
392 if (u->listen) { 393 if (u->listen) {
394 if (u->portn == 0) {
395 if (u->default_portn == 0) {
396 u->err = "no port";
397 return NGX_ERROR;
398 }
399
400 u->portn = u->default_portn;
401 }
402
403 if (u->host.len == 1 && u->host.data[0] == '*') {
404 u->host.len = 0;
405 }
406
407 /* AF_INET only */
408
409 if (u->host.len) {
410
411 host = ngx_palloc(cf->temp_pool, u->host.len + 1);
412 if (host == NULL) {
413 return NGX_ERROR;
414 }
415
416 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
417
418 u->addr.in_addr = inet_addr((const char *) host);
419
420 if (u->addr.in_addr == INADDR_NONE) {
421 h = gethostbyname((const char *) host);
422
423 if (h == NULL || h->h_addr_list[0] == NULL) {
424 u->err = "host not found";
425 return NGX_ERROR;
426 }
427
428 u->addr.in_addr = *(in_addr_t *)(h->h_addr_list[0]);
429 }
430
431 } else {
432 u->addr.in_addr = INADDR_ANY;
433 }
434
393 return NGX_OK; 435 return NGX_OK;
394 } 436 }
395 437
396 if (u->default_port) { 438 if (u->default_port) {
397 439
556 peers->peer[0].uri_separator = ""; 598 peers->peer[0].uri_separator = "";
557 } 599 }
558 600
559 return peers; 601 return peers;
560 } 602 }
561
562
563 ngx_peers_t *
564 ngx_inet_upstream_parse(ngx_conf_t *cf, ngx_inet_upstream_t *u)
565 {
566 char *err;
567 u_char *host;
568 size_t len;
569 in_addr_t in_addr;
570 ngx_uint_t i;
571 ngx_peers_t *peers;
572 struct hostent *h;
573 struct sockaddr_in *sin;
574
575 err = ngx_inet_parse_host_port(u);
576
577 if (err) {
578 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
579 "%s in upstream \"%V\"", err, &u->name);
580 return NULL;
581 }
582
583 if (u->default_port) {
584
585 if (u->default_port_value == 0) {
586 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
587 "no port in upstream \"%V\"", &u->name);
588 return NULL;
589 }
590
591 u->port = u->default_port_value;
592
593 u->port_text.data = ngx_palloc(cf->pool, sizeof("65536") - 1);
594 if (u->port_text.data == NULL) {
595 return NULL;
596 }
597
598 u->port_text.len = ngx_sprintf(u->port_text.data, "%d",
599 u->default_port_value)
600 - u->port_text.data;
601
602 } else if (u->port) {
603 if (u->port == u->default_port_value) {
604 u->default_port = 1;
605 }
606
607 } else {
608 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
609 "no port in upstream \"%V\"", &u->name);
610 return NULL;
611 }
612
613 if (u->host.len == 0) {
614 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
615 "no host in upstream \"%V\"", &u->name);
616 return NULL;
617 }
618
619 u->port = htons(u->port);
620
621 host = ngx_palloc(cf->temp_pool, u->host.len + 1);
622 if (host == NULL) {
623 return NULL;
624 }
625
626 (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
627
628 /* AF_INET only */
629
630 in_addr = inet_addr((char *) host);
631
632 if (in_addr == INADDR_NONE) {
633 h = gethostbyname((char *) host);
634
635 if (h == NULL || h->h_addr_list[0] == NULL) {
636 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
637 "host %s is not found in upstream \"%V\"",
638 host, &u->name);
639 return NULL;
640 }
641
642 for (i = 0; h->h_addr_list[i] != NULL; i++) { /* void */ }
643
644 /* MP: ngx_shared_palloc() */
645
646 peers = ngx_pcalloc(cf->pool,
647 sizeof(ngx_peers_t) + sizeof(ngx_peer_t) * (i - 1));
648 if (peers == NULL) {
649 return NULL;
650 }
651
652 peers->number = i;
653
654 for (i = 0; h->h_addr_list[i] != NULL; i++) {
655
656 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
657 if (sin == NULL) {
658 return NULL;
659 }
660
661 sin->sin_family = AF_INET;
662 sin->sin_port = u->port;
663 sin->sin_addr.s_addr = *(in_addr_t *) (h->h_addr_list[i]);
664
665 peers->peer[i].sockaddr = (struct sockaddr *) sin;
666 peers->peer[i].socklen = sizeof(struct sockaddr_in);
667
668 len = INET_ADDRSTRLEN - 1 + 1 + u->port_text.len;
669
670 peers->peer[i].name.data = ngx_palloc(cf->pool, len);
671 if (peers->peer[i].name.data == NULL) {
672 return NULL;
673 }
674
675 len = ngx_sock_ntop(AF_INET, (struct sockaddr *) sin,
676 peers->peer[i].name.data, len);
677
678 peers->peer[i].name.data[len++] = ':';
679
680 ngx_memcpy(peers->peer[i].name.data + len,
681 u->port_text.data, u->port_text.len);
682
683 peers->peer[i].name.len = len + u->port_text.len;
684
685 peers->peer[i].uri_separator = "";
686
687 peers->peer[i].weight = NGX_CONF_UNSET_UINT;
688 peers->peer[i].max_fails = NGX_CONF_UNSET_UINT;
689 peers->peer[i].fail_timeout = NGX_CONF_UNSET;
690 }
691
692 } else {
693
694 /* MP: ngx_shared_palloc() */
695
696 peers = ngx_pcalloc(cf->pool, sizeof(ngx_peers_t));
697 if (peers == NULL) {
698 return NULL;
699 }
700
701 sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
702 if (sin == NULL) {
703 return NULL;
704 }
705
706 peers->number = 1;
707
708 sin->sin_family = AF_INET;
709 sin->sin_port = u->port;
710 sin->sin_addr.s_addr = in_addr;
711
712 peers->peer[0].sockaddr = (struct sockaddr *) sin;
713 peers->peer[0].socklen = sizeof(struct sockaddr_in);
714
715 len = u->host.len + 1 + u->port_text.len;
716
717 peers->peer[0].name.len = len;
718
719 peers->peer[0].name.data = ngx_palloc(cf->pool, len);
720 if (peers->peer[0].name.data == NULL) {
721 return NULL;
722 }
723
724 len = u->host.len;
725
726 ngx_memcpy(peers->peer[0].name.data, u->host.data, len);
727
728 peers->peer[0].name.data[len++] = ':';
729
730 ngx_memcpy(peers->peer[0].name.data + len,
731 u->port_text.data, u->port_text.len);
732
733 peers->peer[0].uri_separator = "";
734 }
735
736 return peers;
737 }
738
739
740 char *
741 ngx_inet_parse_host_port(ngx_inet_upstream_t *u)
742 {
743 size_t i;
744 ngx_int_t port;
745 ngx_str_t *url;
746
747 url = &u->url;
748
749 if (u->port_only) {
750 i = 0;
751
752 } else {
753 if (url->data[0] == ':' || url->data[0] == '/') {
754 return "invalid host";
755 }
756
757 i = 1;
758 }
759
760 u->host.data = url->data;
761 u->host_header = *url;
762
763 for ( /* void */ ; i < url->len; i++) {
764
765 if (url->data[i] == ':') {
766 u->port_text.data = &url->data[i] + 1;
767 u->host.len = i;
768
769 if (!u->uri_part) {
770 u->port_text.len = &url->data[url->len] - u->port_text.data;
771 break;
772 }
773 }
774
775 if (url->data[i] == '/') {
776 u->uri.data = &url->data[i];
777 u->uri.len = url->len - i;
778 u->host_header.len = i;
779
780 if (u->host.len == 0) {
781 u->host.len = i;
782 }
783
784 if (u->port_text.data == NULL) {
785 u->default_port = 1;
786 return NULL;
787 }
788
789 u->port_text.len = &url->data[i] - u->port_text.data;
790
791 if (u->port_text.len == 0) {
792 return "invalid port";
793 }
794
795 break;
796 }
797 }
798
799 if (u->port_text.data) {
800
801 if (u->port_text.len == 0) {
802 u->port_text.len = &url->data[i] - u->port_text.data;
803
804 if (u->port_text.len == 0) {
805 return "invalid port";
806 }
807 }
808
809 port = ngx_atoi(u->port_text.data, u->port_text.len);
810
811 if (port == NGX_ERROR || port < 1 || port > 65536) {
812 return "invalid port";
813 }
814
815 } else {
816 port = ngx_atoi(url->data, url->len);
817
818 if (port == NGX_ERROR) {
819 u->default_port = 1;
820 u->host.len = url->len;
821
822 return NULL;
823 }
824
825 u->port_text = *url;
826 u->wildcard = 1;
827 }
828
829 u->port = (in_port_t) port;
830
831 return NULL;
832 }