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 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, |
297 hdr_transfer_encoding, 298 hdr_www_authenticate |
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" }, |
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)); |
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; |
713 do { 714 new = NULL; 715 chunked = 0; |
716 offset = 0; 717 clength = -1; 718 length = -1; 719 size = -1; 720 mtime = 0; |
721 |
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 |
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 */ |
766 if (need_auth || *url->user || *url->pwd) { |
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); |
771 else if (fetchAuthMethod && fetchAuthMethod(url) == 0) { 772 _http_basic_auth(fd, "Authorization", url->user, url->pwd); 773 } else { |
774 _http_seterr(HTTP_NEED_AUTH); 775 goto ouch; 776 } 777 } 778 779 /* other headers */ |
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"); |
811 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; |
881 case hdr_end: 882 /* fall through */ 883 case hdr_unknown: 884 /* ignore */ 885 break; 886 } 887 } while (h > hdr_end); 888 |
889 /* we have a hit */ 890 if (code == HTTP_OK || code == HTTP_PARTIAL) |
891 break; 892 |
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; |
903 close(fd); 904 fd = -1; |
905 if (!new) { 906 DEBUG(fprintf(stderr, "redirect with no new location\n")); 907 break; 908 } |
909 if (url != URL) 910 fetchFreeURL(url); 911 url = new; 912 } while (++i < n); 913 |
914 /* we failed, or ran out of retries */ |
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 --- |