http.c (75891) | http.c (77238) |
---|---|
1/*- 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * | 1/*- 2 * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * |
28 * $FreeBSD: head/lib/libfetch/http.c 75891 2001-04-24 00:06:21Z archie $ | 28 * $FreeBSD: head/lib/libfetch/http.c 77238 2001-05-26 19:37:15Z des $ |
29 */ 30 31/* 32 * The following copyright applies to the base64 code: 33 * 34 *- 35 * Copyright 1997 Massachusetts Institute of Technology 36 * --- 252 unchanged lines hidden (view full) --- 289 hdr_syserror = -2, 290 hdr_error = -1, 291 hdr_end = 0, 292 hdr_unknown = 1, 293 hdr_content_length, 294 hdr_content_range, 295 hdr_last_modified, 296 hdr_location, | 29 */ 30 31/* 32 * The following copyright applies to the base64 code: 33 * 34 *- 35 * Copyright 1997 Massachusetts Institute of Technology 36 * --- 252 unchanged lines hidden (view full) --- 289 hdr_syserror = -2, 290 hdr_error = -1, 291 hdr_end = 0, 292 hdr_unknown = 1, 293 hdr_content_length, 294 hdr_content_range, 295 hdr_last_modified, 296 hdr_location, |
297 hdr_transfer_encoding | 297 hdr_transfer_encoding, 298 hdr_www_authenticate |
298} hdr; 299 300/* Names of interesting headers */ 301static struct { 302 hdr num; 303 const char *name; 304} hdr_names[] = { 305 { hdr_content_length, "Content-Length" }, 306 { hdr_content_range, "Content-Range" }, 307 { hdr_last_modified, "Last-Modified" }, 308 { hdr_location, "Location" }, 309 { hdr_transfer_encoding, "Transfer-Encoding" }, | 299} hdr; 300 301/* Names of interesting headers */ 302static struct { 303 hdr num; 304 const char *name; 305} hdr_names[] = { 306 { hdr_content_length, "Content-Length" }, 307 { hdr_content_range, "Content-Range" }, 308 { hdr_last_modified, "Last-Modified" }, 309 { hdr_location, "Location" }, 310 { hdr_transfer_encoding, "Transfer-Encoding" }, |
311 { hdr_www_authenticate, "WWW-Authenticate" }, |
|
310 { hdr_unknown, NULL }, 311}; 312 313static char *reply_buf; 314static size_t reply_size; 315static size_t reply_length; 316 317/* --- 241 unchanged lines hidden (view full) --- 559 * Encode username and password 560 */ 561static int 562_http_basic_auth(int fd, const char *hdr, const char *usr, const char *pwd) 563{ 564 char *upw, *auth; 565 int r; 566 | 312 { hdr_unknown, NULL }, 313}; 314 315static char *reply_buf; 316static size_t reply_size; 317static size_t reply_length; 318 319/* --- 241 unchanged lines hidden (view full) --- 561 * Encode username and password 562 */ 563static int 564_http_basic_auth(int fd, const char *hdr, const char *usr, const char *pwd) 565{ 566 char *upw, *auth; 567 int r; 568 |
569 DEBUG(fprintf(stderr, "usr: [\033[1m%s\033[m]\n", usr)); 570 DEBUG(fprintf(stderr, "pwd: [\033[1m%s\033[m]\n", pwd)); |
|
567 if (asprintf(&upw, "%s:%s", usr, pwd) == -1) 568 return -1; 569 auth = _http_base64(upw); 570 free(upw); 571 if (auth == NULL) 572 return -1; 573 r = _http_cmd(fd, "%s: Basic %s", hdr, auth); 574 free(auth); --- 125 unchanged lines hidden (view full) --- 700 701 /* try the provided URL first */ 702 url = URL; 703 704 /* if the A flag is set, we only get one try */ 705 n = noredirect ? 1 : MAX_REDIRECT; 706 i = 0; 707 | 571 if (asprintf(&upw, "%s:%s", usr, pwd) == -1) 572 return -1; 573 auth = _http_base64(upw); 574 free(upw); 575 if (auth == NULL) 576 return -1; 577 r = _http_cmd(fd, "%s: Basic %s", hdr, auth); 578 free(auth); --- 125 unchanged lines hidden (view full) --- 704 705 /* try the provided URL first */ 706 url = URL; 707 708 /* if the A flag is set, we only get one try */ 709 n = noredirect ? 1 : MAX_REDIRECT; 710 i = 0; 711 |
712 need_auth = 0; |
|
708 do { 709 new = NULL; 710 chunked = 0; | 713 do { 714 new = NULL; 715 chunked = 0; |
711 need_auth = 0; | |
712 offset = 0; 713 clength = -1; 714 length = -1; 715 size = -1; 716 mtime = 0; | 716 offset = 0; 717 clength = -1; 718 length = -1; 719 size = -1; 720 mtime = 0; |
717 retry: | 721 |
718 /* check port */ 719 if (!url->port) 720 url->port = _fetch_default_port(url->scheme); 721 722 /* connect to server or proxy */ 723 if ((fd = _http_connect(url, purl, flags)) == -1) 724 goto ouch; 725 --- 12 unchanged lines hidden (view full) --- 738 if (purl) { 739 _http_cmd(fd, "%s %s://%s:%d%s HTTP/1.1", 740 op, url->scheme, host, url->port, url->doc); 741 } else { 742 _http_cmd(fd, "%s %s HTTP/1.1", 743 op, url->doc); 744 } 745 | 722 /* check port */ 723 if (!url->port) 724 url->port = _fetch_default_port(url->scheme); 725 726 /* connect to server or proxy */ 727 if ((fd = _http_connect(url, purl, flags)) == -1) 728 goto ouch; 729 --- 12 unchanged lines hidden (view full) --- 742 if (purl) { 743 _http_cmd(fd, "%s %s://%s:%d%s HTTP/1.1", 744 op, url->scheme, host, url->port, url->doc); 745 } else { 746 _http_cmd(fd, "%s %s HTTP/1.1", 747 op, url->doc); 748 } 749 |
750 /* virtual host */ 751 if (url->port == _fetch_default_port(url->scheme)) 752 _http_cmd(fd, "Host: %s", host); 753 else 754 _http_cmd(fd, "Host: %s:%d", host, url->port); 755 |
|
746 /* proxy authorization */ 747 if (purl) { 748 if (*purl->user || *purl->pwd) 749 _http_basic_auth(fd, "Proxy-Authorization", 750 purl->user, purl->pwd); 751 else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0') 752 _http_authorize(fd, "Proxy-Authorization", p); 753 } 754 755 /* server authorization */ | 756 /* proxy authorization */ 757 if (purl) { 758 if (*purl->user || *purl->pwd) 759 _http_basic_auth(fd, "Proxy-Authorization", 760 purl->user, purl->pwd); 761 else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0') 762 _http_authorize(fd, "Proxy-Authorization", p); 763 } 764 765 /* server authorization */ |
756 if (need_auth) { | 766 if (need_auth || *url->user || *url->pwd) { |
757 if (*url->user || *url->pwd) 758 _http_basic_auth(fd, "Authorization", url->user, url->pwd); 759 else if ((p = getenv("HTTP_AUTH")) != NULL && *p != '\0') 760 _http_authorize(fd, "Authorization", p); | 767 if (*url->user || *url->pwd) 768 _http_basic_auth(fd, "Authorization", url->user, url->pwd); 769 else if ((p = getenv("HTTP_AUTH")) != NULL && *p != '\0') 770 _http_authorize(fd, "Authorization", p); |
761 else { | 771 else if (fetchAuthMethod && fetchAuthMethod(url) == 0) { 772 _http_basic_auth(fd, "Authorization", url->user, url->pwd); 773 } else { |
762 _http_seterr(HTTP_NEED_AUTH); 763 goto ouch; 764 } 765 } 766 767 /* other headers */ | 774 _http_seterr(HTTP_NEED_AUTH); 775 goto ouch; 776 } 777 } 778 779 /* other headers */ |
768 if (url->port == _fetch_default_port(url->scheme)) 769 _http_cmd(fd, "Host: %s", host); 770 else 771 _http_cmd(fd, "Host: %s:%d", host, url->port); | |
772 _http_cmd(fd, "User-Agent: %s " _LIBFETCH_VER, __progname); 773 if (url->offset) 774 _http_cmd(fd, "Range: bytes=%lld-", url->offset); 775 _http_cmd(fd, "Connection: close"); 776 _http_cmd(fd, ""); 777 778 /* get reply */ 779 switch ((code = _http_get_reply(fd))) { --- 15 unchanged lines hidden (view full) --- 795 * nothing more we can do. 796 */ 797 _http_seterr(code); 798 goto ouch; 799 } 800 /* try again, but send the password this time */ 801 if (verbose) 802 _fetch_info("server requires authorization"); | 780 _http_cmd(fd, "User-Agent: %s " _LIBFETCH_VER, __progname); 781 if (url->offset) 782 _http_cmd(fd, "Range: bytes=%lld-", url->offset); 783 _http_cmd(fd, "Connection: close"); 784 _http_cmd(fd, ""); 785 786 /* get reply */ 787 switch ((code = _http_get_reply(fd))) { --- 15 unchanged lines hidden (view full) --- 803 * nothing more we can do. 804 */ 805 _http_seterr(code); 806 goto ouch; 807 } 808 /* try again, but send the password this time */ 809 if (verbose) 810 _fetch_info("server requires authorization"); |
803 need_auth = 1; 804 close(fd); 805 goto retry; | 811 break; |
806 case HTTP_NEED_PROXY_AUTH: 807 /* 808 * If we're talking to a proxy, we already sent our proxy 809 * authorization code, so there's nothing more we can do. 810 */ 811 _http_seterr(code); 812 goto ouch; 813 case HTTP_PROTOCOL_ERROR: --- 48 unchanged lines hidden (view full) --- 862 } 863 new->offset = url->offset; 864 new->length = url->length; 865 break; 866 case hdr_transfer_encoding: 867 /* XXX weak test*/ 868 chunked = (strcasecmp(p, "chunked") == 0); 869 break; | 812 case HTTP_NEED_PROXY_AUTH: 813 /* 814 * If we're talking to a proxy, we already sent our proxy 815 * authorization code, so there's nothing more we can do. 816 */ 817 _http_seterr(code); 818 goto ouch; 819 case HTTP_PROTOCOL_ERROR: --- 48 unchanged lines hidden (view full) --- 868 } 869 new->offset = url->offset; 870 new->length = url->length; 871 break; 872 case hdr_transfer_encoding: 873 /* XXX weak test*/ 874 chunked = (strcasecmp(p, "chunked") == 0); 875 break; |
876 case hdr_www_authenticate: 877 if (code != HTTP_NEED_AUTH) 878 break; 879 /* if we were smarter, we'd check the method and realm */ 880 break; |
|
870 case hdr_end: 871 /* fall through */ 872 case hdr_unknown: 873 /* ignore */ 874 break; 875 } 876 } while (h > hdr_end); 877 | 881 case hdr_end: 882 /* fall through */ 883 case hdr_unknown: 884 /* ignore */ 885 break; 886 } 887 } while (h > hdr_end); 888 |
878 /* we either have a hit, or a redirect with no Location: header */ 879 if (code == HTTP_OK || code == HTTP_PARTIAL || !new) | 889 /* we have a hit */ 890 if (code == HTTP_OK || code == HTTP_PARTIAL) |
880 break; 881 | 891 break; 892 |
882 /* we have a redirect */ | 893 /* we need to provide authentication */ 894 if (code == HTTP_NEED_AUTH) { 895 need_auth = 1; 896 close(fd); 897 fd = -1; 898 continue; 899 } 900 901 /* all other cases: we got a redirect */ 902 need_auth = 0; |
883 close(fd); 884 fd = -1; | 903 close(fd); 904 fd = -1; |
905 if (!new) { 906 DEBUG(fprintf(stderr, "redirect with no new location\n")); 907 break; 908 } |
|
885 if (url != URL) 886 fetchFreeURL(url); 887 url = new; 888 } while (++i < n); 889 | 909 if (url != URL) 910 fetchFreeURL(url); 911 url = new; 912 } while (++i < n); 913 |
890 /* no success */ | 914 /* we failed, or ran out of retries */ |
891 if (fd == -1) { 892 _http_seterr(code); 893 goto ouch; 894 } 895 896 DEBUG(fprintf(stderr, "offset %lld, length %lld, size %lld, clength %lld\n", 897 offset, length, size, clength)); 898 --- 111 unchanged lines hidden --- | 915 if (fd == -1) { 916 _http_seterr(code); 917 goto ouch; 918 } 919 920 DEBUG(fprintf(stderr, "offset %lld, length %lld, size %lld, clength %lld\n", 921 offset, length, size, clength)); 922 --- 111 unchanged lines hidden --- |