]>
Commit | Line | Data |
---|---|---|
4a83b7b0 | 1 | /* |
85553593 | 2 | * Copyright (c) 2000, 2001, Red Hat, Inc. |
4a83b7b0 DD |
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 | ||
5898e300 | 19 | #if 0 |
b24c88b3 RC |
20 | static const char *cvsid = |
21 | "\n%%% $Id$\n"; | |
5898e300 | 22 | #endif |
946fc045 | 23 | |
4a83b7b0 DD |
24 | #include "win32.h" |
25 | #include "winsock.h" | |
26 | #include <stdio.h> | |
27 | #include <stdlib.h> | |
28 | ||
29 | #include "resource.h" | |
30 | #include "state.h" | |
31 | #include "simpsock.h" | |
32 | #include "msg.h" | |
33 | ||
34 | #include "netio.h" | |
35 | #include "nio-http.h" | |
36 | ||
37 | static char six2pr[64] = { | |
b24c88b3 RC |
38 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', |
39 | 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', | |
40 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', | |
41 | 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', | |
42 | '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' | |
4a83b7b0 DD |
43 | }; |
44 | ||
45 | static char * | |
46 | base64_encode (char *username, char *password) | |
47 | { | |
48 | unsigned char *ep; | |
49 | char *rp; | |
50 | static char *rv = 0; | |
51 | if (rv) | |
5e0464a1 RC |
52 | delete[] rv; |
53 | rv = new char[2 * (strlen (username) + strlen (password)) + 5]; | |
4a83b7b0 | 54 | |
5e0464a1 | 55 | char *up = new char[strlen (username) + strlen (password) + 6]; |
4a83b7b0 DD |
56 | strcpy (up, username); |
57 | strcat (up, ":"); | |
58 | strcat (up, password); | |
b24c88b3 | 59 | ep = (unsigned char *) up + strlen (up); |
4a83b7b0 DD |
60 | *ep++ = 0; |
61 | *ep++ = 0; | |
62 | *ep++ = 0; | |
63 | ||
64 | char block[4]; | |
65 | ||
66 | rp = rv; | |
67 | ||
b24c88b3 | 68 | for (ep = (unsigned char *) up; *ep; ep += 3) |
4a83b7b0 DD |
69 | { |
70 | block[0] = six2pr[ep[0] >> 2]; | |
71 | block[1] = six2pr[((ep[0] << 4) & 0x30) | ((ep[1] >> 4) & 0x0f)]; | |
72 | block[2] = six2pr[((ep[1] << 2) & 0x3c) | ((ep[2] >> 6) & 0x03)]; | |
73 | block[3] = six2pr[ep[2] & 0x3f]; | |
74 | ||
75 | if (ep[1] == 0) | |
76 | block[2] = block[3] = '='; | |
77 | if (ep[2] == 0) | |
78 | block[3] = '='; | |
79 | memcpy (rp, block, 4); | |
80 | rp += 4; | |
81 | } | |
82 | *rp = 0; | |
83 | ||
5e0464a1 | 84 | delete[] up; |
4a83b7b0 DD |
85 | |
86 | return rv; | |
87 | } | |
88 | ||
341988b9 | 89 | NetIO_HTTP::NetIO_HTTP (char const *Purl, BOOL allow_ftp_auth):NetIO (Purl, allow_ftp_auth) |
4a83b7b0 | 90 | { |
b24c88b3 | 91 | retry_get: |
4a83b7b0 DD |
92 | if (port == 0) |
93 | port = 80; | |
94 | ||
95 | if (net_method == IDC_NET_PROXY) | |
96 | s = new SimpleSocket (net_proxy_host, net_proxy_port); | |
97 | else | |
98 | s = new SimpleSocket (host, port); | |
99 | ||
b24c88b3 | 100 | if (!s->ok ()) |
4a83b7b0 | 101 | { |
b24c88b3 RC |
102 | delete |
103 | s; | |
c168185f | 104 | s = NULL; |
4a83b7b0 DD |
105 | return; |
106 | } | |
107 | ||
108 | if (net_method == IDC_NET_PROXY) | |
1ac649ed | 109 | s->printf ("GET %s HTTP/1.0\r\n", Purl); |
4a83b7b0 DD |
110 | else |
111 | s->printf ("GET %s HTTP/1.0\r\n", path); | |
112 | s->printf ("Host: %s:%d\r\n", host, port); | |
113 | ||
114 | if (net_user && net_passwd) | |
115 | s->printf ("Authorization: Basic %s\r\n", | |
116 | base64_encode (net_user, net_passwd)); | |
117 | ||
118 | if (net_proxy_user && net_proxy_passwd) | |
119 | s->printf ("Proxy-Authorization: Basic %s\r\n", | |
120 | base64_encode (net_proxy_user, net_proxy_passwd)); | |
121 | ||
122 | s->printf ("\r\n"); | |
123 | ||
b24c88b3 RC |
124 | char * |
125 | l = s->gets (); | |
126 | int | |
127 | code; | |
67a55ad9 RC |
128 | if (!l) |
129 | return; | |
4a83b7b0 DD |
130 | sscanf (l, "%*s %d", &code); |
131 | if (code >= 300 && code < 400) | |
132 | { | |
b24c88b3 RC |
133 | while ((l = s->gets ()) != 0) |
134 | { | |
135 | if (_strnicmp (l, "Location:", 9) == 0) | |
136 | { | |
137 | char * | |
138 | u = l + 9; | |
139 | while (*u == ' ' || *u == '\t') | |
140 | u++; | |
141 | set_url (u); | |
142 | delete | |
143 | s; | |
144 | goto retry_get; | |
145 | } | |
146 | } | |
4a83b7b0 | 147 | } |
b24c88b3 | 148 | if (code == 401) /* authorization required */ |
4a83b7b0 | 149 | { |
ab57ceaa | 150 | get_auth (NULL); |
b24c88b3 RC |
151 | delete |
152 | s; | |
4a83b7b0 DD |
153 | goto retry_get; |
154 | } | |
b24c88b3 | 155 | if (code == 407) /* proxy authorization required */ |
4a83b7b0 | 156 | { |
ab57ceaa | 157 | get_proxy_auth (NULL); |
b24c88b3 RC |
158 | delete |
159 | s; | |
4a83b7b0 DD |
160 | goto retry_get; |
161 | } | |
b24c88b3 | 162 | if (code == 500 /* ftp authentication through proxy required */ |
1ac649ed | 163 | && net_method == IDC_NET_PROXY && !strncmp (Purl, "ftp://", 6)) |
85553593 | 164 | { |
ab57ceaa | 165 | get_ftp_auth (NULL); |
85553593 | 166 | if (net_ftp_user && net_ftp_passwd) |
b24c88b3 RC |
167 | { |
168 | delete | |
169 | s; | |
1ac649ed RC |
170 | Purl = (String ("ftp://") + net_ftp_user + |
171 | ":" + net_ftp_passwd + "@" + (Purl + 6)).cstr_oneuse(); | |
b24c88b3 | 172 | goto retry_get; |
85553593 CV |
173 | } |
174 | } | |
4a83b7b0 DD |
175 | if (code >= 300) |
176 | { | |
b24c88b3 RC |
177 | delete |
178 | s; | |
4a83b7b0 DD |
179 | s = 0; |
180 | return; | |
181 | } | |
90d14922 RC |
182 | |
183 | // Eat the header, picking out the Content-Length in the process | |
184 | while (((l = s->gets ()) != NULL) && (*l != '\0')) | |
b24c88b3 RC |
185 | { |
186 | if (_strnicmp (l, "Content-Length:", 15) == 0) | |
187 | sscanf (l, "%*s %d", &file_size); | |
188 | } | |
4a83b7b0 DD |
189 | } |
190 | ||
191 | NetIO_HTTP::~NetIO_HTTP () | |
192 | { | |
193 | if (s) | |
194 | delete s; | |
195 | } | |
196 | ||
197 | int | |
198 | NetIO_HTTP::ok () | |
199 | { | |
67a55ad9 | 200 | if (s && s->ok ()) |
4a83b7b0 DD |
201 | return 1; |
202 | return 0; | |
203 | } | |
204 | ||
205 | int | |
206 | NetIO_HTTP::read (char *buf, int nbytes) | |
207 | { | |
208 | return s->read (buf, nbytes); | |
209 | } |