448
+ − 1 /*
+ − 2 * Copyright (c) 2000, Red Hat, Inc.
+ − 3 *
+ − 4 * This program is free software; you can redistribute it and/or modify
+ − 5 * it under the terms of the GNU General Public License as published by
+ − 6 * the Free Software Foundation; either version 2 of the License, or
+ − 7 * (at your option) any later version.
+ − 8 *
+ − 9 * A copy of the GNU General Public License can be found at
+ − 10 * http://www.gnu.org/
+ − 11 *
+ − 12 * Written by DJ Delorie <dj@cygnus.com>
+ − 13 *
+ − 14 */
+ − 15
+ − 16 /* This file is responsible for implementing all direct HTTP protocol
+ − 17 channels. It is intentionally simplistic. */
+ − 18
+ − 19 #include "win32.h"
+ − 20 #include "winsock.h"
+ − 21 #include <stdio.h>
+ − 22 #include <stdlib.h>
+ − 23
+ − 24 #include "resource.h"
+ − 25 #include "state.h"
+ − 26 #include "simpsock.h"
+ − 27 #include "msg.h"
+ − 28
+ − 29 #include "netio.h"
+ − 30 #include "nio-http.h"
+ − 31
+ − 32 static char six2pr[64] = {
+ − 33 'A','B','C','D','E','F','G','H','I','J','K','L','M',
+ − 34 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
+ − 35 'a','b','c','d','e','f','g','h','i','j','k','l','m',
+ − 36 'n','o','p','q','r','s','t','u','v','w','x','y','z',
+ − 37 '0','1','2','3','4','5','6','7','8','9','+','/'
+ − 38 };
+ − 39
+ − 40 static char *
+ − 41 base64_encode (char *username, char *password)
+ − 42 {
+ − 43 unsigned char *ep;
+ − 44 char *rp;
+ − 45 static char *rv = 0;
+ − 46 if (rv)
+ − 47 free (rv);
+ − 48 rv = (char *) malloc (2 * (strlen (username) + strlen (password)) + 5);
+ − 49
+ − 50 char *up = (char *) malloc (strlen (username) + strlen (password) + 6);
+ − 51 strcpy (up, username);
+ − 52 strcat (up, ":");
+ − 53 strcat (up, password);
+ − 54 ep = (unsigned char *)up + strlen (up);
+ − 55 *ep++ = 0;
+ − 56 *ep++ = 0;
+ − 57 *ep++ = 0;
+ − 58
+ − 59 char block[4];
+ − 60
+ − 61 rp = rv;
+ − 62
+ − 63 for (ep = (unsigned char *)up; *ep; ep += 3)
+ − 64 {
+ − 65 block[0] = six2pr[ep[0] >> 2];
+ − 66 block[1] = six2pr[((ep[0] << 4) & 0x30) | ((ep[1] >> 4) & 0x0f)];
+ − 67 block[2] = six2pr[((ep[1] << 2) & 0x3c) | ((ep[2] >> 6) & 0x03)];
+ − 68 block[3] = six2pr[ep[2] & 0x3f];
+ − 69
+ − 70 if (ep[1] == 0)
+ − 71 block[2] = block[3] = '=';
+ − 72 if (ep[2] == 0)
+ − 73 block[3] = '=';
+ − 74 memcpy (rp, block, 4);
+ − 75 rp += 4;
+ − 76 }
+ − 77 *rp = 0;
+ − 78
+ − 79 free (up);
+ − 80
+ − 81 return rv;
+ − 82 }
+ − 83
+ − 84 NetIO_HTTP::NetIO_HTTP (char *Purl)
+ − 85 : NetIO (Purl)
+ − 86 {
+ − 87 retry_get:
+ − 88 if (port == 0)
+ − 89 port = 80;
+ − 90
+ − 91 if (net_method == IDC_NET_PROXY)
+ − 92 s = new SimpleSocket (net_proxy_host, net_proxy_port);
+ − 93 else
+ − 94 s = new SimpleSocket (host, port);
+ − 95
+ − 96 if (!s->ok())
+ − 97 {
+ − 98 s = 0;
+ − 99 return;
+ − 100 }
+ − 101
+ − 102 if (net_method == IDC_NET_PROXY)
+ − 103 s->printf ("GET %s HTTP/1.0\r\n", url);
+ − 104 else
+ − 105 s->printf ("GET %s HTTP/1.0\r\n", path);
+ − 106 s->printf ("Host: %s:%d\r\n", host, port);
+ − 107
+ − 108 if (net_user && net_passwd)
+ − 109 s->printf ("Authorization: Basic %s\r\n",
+ − 110 base64_encode (net_user, net_passwd));
+ − 111
+ − 112 if (net_proxy_user && net_proxy_passwd)
+ − 113 s->printf ("Proxy-Authorization: Basic %s\r\n",
+ − 114 base64_encode (net_proxy_user, net_proxy_passwd));
+ − 115
+ − 116 s->printf ("\r\n");
+ − 117
+ − 118 char *l = s->gets ();
+ − 119 int code;
+ − 120 sscanf (l, "%*s %d", &code);
+ − 121 if (code >= 300 && code < 400)
+ − 122 {
+ − 123 do {
+ − 124 l = s->gets ();
+ − 125 if (_strnicmp (l, "Location:", 9) == 0)
+ − 126 {
+ − 127 char *u = l + 9;
+ − 128 while (*u == ' ' || *u == '\t')
+ − 129 u++;
+ − 130 set_url (u);
+ − 131 delete s;
+ − 132 goto retry_get;
+ − 133 }
+ − 134 } while (*l);
+ − 135 }
+ − 136 if (code == 401) /* authorization required */
+ − 137 {
+ − 138 get_auth ();
+ − 139 delete s;
+ − 140 goto retry_get;
+ − 141 }
+ − 142 if (code == 407) /* proxy authorization required */
+ − 143 {
+ − 144 get_proxy_auth ();
+ − 145 delete s;
+ − 146 goto retry_get;
+ − 147 }
+ − 148 if (code >= 300)
+ − 149 {
+ − 150 delete s;
+ − 151 s = 0;
+ − 152 return;
+ − 153 }
+ − 154 do {
+ − 155 l = s->gets ();
+ − 156 if (_strnicmp (l, "Content-Length:", 15) == 0)
+ − 157 sscanf (l, "%*s %d", &file_size);
+ − 158 } while (*l);
+ − 159 }
+ − 160
+ − 161 NetIO_HTTP::~NetIO_HTTP ()
+ − 162 {
+ − 163 if (s)
+ − 164 delete s;
+ − 165 }
+ − 166
+ − 167 int
+ − 168 NetIO_HTTP::ok ()
+ − 169 {
+ − 170 if (s)
+ − 171 return 1;
+ − 172 return 0;
+ − 173 }
+ − 174
+ − 175 int
+ − 176 NetIO_HTTP::read (char *buf, int nbytes)
+ − 177 {
+ − 178 return s->read (buf, nbytes);
+ − 179 }