Mercurial > hg > nginx-vendor-0-8
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 } |