]>
Commit | Line | Data |
---|---|---|
52e1d7e2 | 1 | |
afe95a7e | 2 | |
56878878 | 3 | |
6a54c60e | 4 | |
da2b3a17 | 5 | |
5d86029a | 6 | |
30a4f2a8 | 7 | /* |
f5b8bbc4 | 8 | * $Id: client.cc,v 1.35 1997/10/25 17:22:35 wessels Exp $ |
30a4f2a8 | 9 | * |
10 | * DEBUG: section 0 WWW Client | |
11 | * AUTHOR: Harvest Derived | |
12 | * | |
42c04c16 | 13 | * SQUID Internet Object Cache http://squid.nlanr.net/Squid/ |
30a4f2a8 | 14 | * -------------------------------------------------------- |
15 | * | |
16 | * Squid is the result of efforts by numerous individuals from the | |
17 | * Internet community. Development is led by Duane Wessels of the | |
18 | * National Laboratory for Applied Network Research and funded by | |
19 | * the National Science Foundation. | |
20 | * | |
21 | * This program is free software; you can redistribute it and/or modify | |
22 | * it under the terms of the GNU General Public License as published by | |
23 | * the Free Software Foundation; either version 2 of the License, or | |
24 | * (at your option) any later version. | |
25 | * | |
26 | * This program is distributed in the hope that it will be useful, | |
27 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
29 | * GNU General Public License for more details. | |
30 | * | |
31 | * You should have received a copy of the GNU General Public License | |
32 | * along with this program; if not, write to the Free Software | |
33 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
34 | * | |
35 | */ | |
36 | ||
37 | /* | |
38 | * Copyright (c) 1994, 1995. All rights reserved. | |
39 | * | |
40 | * The Harvest software was developed by the Internet Research Task | |
41 | * Force Research Group on Resource Discovery (IRTF-RD): | |
42 | * | |
43 | * Mic Bowman of Transarc Corporation. | |
44 | * Peter Danzig of the University of Southern California. | |
45 | * Darren R. Hardy of the University of Colorado at Boulder. | |
46 | * Udi Manber of the University of Arizona. | |
47 | * Michael F. Schwartz of the University of Colorado at Boulder. | |
48 | * Duane Wessels of the University of Colorado at Boulder. | |
49 | * | |
50 | * This copyright notice applies to software in the Harvest | |
51 | * ``src/'' directory only. Users should consult the individual | |
52 | * copyright notices in the ``components/'' subdirectories for | |
53 | * copyright information about other software bundled with the | |
54 | * Harvest source code distribution. | |
55 | * | |
56 | * TERMS OF USE | |
57 | * | |
58 | * The Harvest software may be used and re-distributed without | |
59 | * charge, provided that the software origin and research team are | |
60 | * cited in any use of the system. Most commonly this is | |
61 | * accomplished by including a link to the Harvest Home Page | |
62 | * (http://harvest.cs.colorado.edu/) from the query page of any | |
63 | * Broker you deploy, as well as in the query result pages. These | |
64 | * links are generated automatically by the standard Broker | |
65 | * software distribution. | |
66 | * | |
67 | * The Harvest software is provided ``as is'', without express or | |
68 | * implied warranty, and with no support nor obligation to assist | |
69 | * in its use, correction, modification or enhancement. We assume | |
70 | * no liability with respect to the infringement of copyrights, | |
71 | * trade secrets, or any patents, and are not responsible for | |
72 | * consequential damages. Proper use of the Harvest software is | |
73 | * entirely the responsibility of the user. | |
74 | * | |
75 | * DERIVATIVE WORKS | |
76 | * | |
77 | * Users may make derivative works from the Harvest software, subject | |
78 | * to the following constraints: | |
79 | * | |
80 | * - You must include the above copyright notice and these | |
81 | * accompanying paragraphs in all forms of derivative works, | |
82 | * and any documentation and other materials related to such | |
83 | * distribution and use acknowledge that the software was | |
84 | * developed at the above institutions. | |
85 | * | |
86 | * - You must notify IRTF-RD regarding your distribution of | |
87 | * the derivative work. | |
88 | * | |
89 | * - You must clearly notify users that your are distributing | |
90 | * a modified version and not the original Harvest software. | |
91 | * | |
92 | * - Any derivative product is also subject to these copyright | |
93 | * and use restrictions. | |
94 | * | |
95 | * Note that the Harvest software is NOT in the public domain. We | |
96 | * retain copyright, as specified above. | |
97 | * | |
98 | * HISTORY OF FREE SOFTWARE STATUS | |
99 | * | |
100 | * Originally we required sites to license the software in cases | |
101 | * where they were going to build commercial products/services | |
102 | * around Harvest. In June 1995 we changed this policy. We now | |
103 | * allow people to use the core Harvest software (the code found in | |
104 | * the Harvest ``src/'' directory) for free. We made this change | |
105 | * in the interest of encouraging the widest possible deployment of | |
106 | * the technology. The Harvest software is really a reference | |
107 | * implementation of a set of protocols and formats, some of which | |
108 | * we intend to standardize. We encourage commercial | |
109 | * re-implementations of code complying to this set of standards. | |
110 | */ | |
090089c4 | 111 | |
44a47c6e | 112 | #include "squid.h" |
090089c4 | 113 | |
114 | #ifndef BUFSIZ | |
115 | #define BUFSIZ 8192 | |
116 | #endif | |
117 | ||
118 | /* Local functions */ | |
f5b8bbc4 | 119 | static int client_comm_connect(int sock, char *dest_host, u_short dest_port); |
120 | static void usage(const char *progname); | |
090089c4 | 121 | |
b8d8561b | 122 | static void |
0ee4272b | 123 | usage(const char *progname) |
090089c4 | 124 | { |
0ee4272b | 125 | fprintf(stderr, |
88738790 | 126 | "Usage: %s [-ars] [-i IMS] [-h host] [-p port] [-m method] [-t count] url\n" |
fe4e214f | 127 | "Options:\n" |
88738790 | 128 | " -a Do NOT include Accept: header.\n" |
fe4e214f | 129 | " -r Force cache to reload URL.\n" |
130 | " -s Silent. Do not print data to stdout.\n" | |
131 | " -i IMS If-Modified-Since time (in Epoch seconds).\n" | |
132 | " -h host Retrieve URL from cache on hostname. Default is localhost.\n" | |
133 | " -p port Port number of cache. Default is %d.\n" | |
88738790 | 134 | " -m method Request method, default is GET.\n" |
135 | " -t count Trace count cache-hops\n", | |
fe4e214f | 136 | progname, CACHE_HTTP_PORT); |
090089c4 | 137 | exit(1); |
138 | } | |
139 | ||
b8d8561b | 140 | int |
141 | main(int argc, char *argv[]) | |
090089c4 | 142 | { |
143 | int conn, c, len, bytesWritten; | |
144 | int port, to_stdout, reload; | |
599eadbe | 145 | int keep_alive = 0; |
88738790 | 146 | int opt_noaccept = 0; |
090089c4 | 147 | char url[BUFSIZ], msg[BUFSIZ], buf[BUFSIZ], hostname[BUFSIZ]; |
0ee4272b | 148 | const char *method = "GET"; |
090089c4 | 149 | extern char *optarg; |
234967c9 | 150 | time_t ims = 0; |
b3b64e58 | 151 | int max_forwards = -1; |
090089c4 | 152 | |
153 | /* set the defaults */ | |
154 | strcpy(hostname, "localhost"); | |
155 | port = CACHE_HTTP_PORT; | |
156 | to_stdout = 1; | |
157 | reload = 0; | |
158 | ||
159 | if (argc < 2) { | |
160 | usage(argv[0]); /* need URL */ | |
161 | } else if (argc >= 2) { | |
162 | strcpy(url, argv[argc - 1]); | |
163 | if (url[0] == '-') | |
164 | usage(argv[0]); | |
88738790 | 165 | while ((c = getopt(argc, argv, "ah:i:km:p:rst:?")) != -1) |
090089c4 | 166 | switch (c) { |
88738790 | 167 | case 'a': |
168 | opt_noaccept = 1; | |
169 | break; | |
090089c4 | 170 | case 'h': /* host:arg */ |
090089c4 | 171 | if (optarg != NULL) |
172 | strcpy(hostname, optarg); | |
173 | break; | |
174 | case 's': /* silent */ | |
090089c4 | 175 | to_stdout = 0; |
176 | break; | |
599eadbe | 177 | case 'k': /* backward compat */ |
178 | keep_alive = 1; | |
179 | break; | |
090089c4 | 180 | case 'r': /* reload */ |
181 | reload = 1; | |
182 | break; | |
183 | case 'p': /* port number */ | |
184 | sscanf(optarg, "%d", &port); | |
185 | if (port < 1) | |
186 | port = CACHE_HTTP_PORT; /* default */ | |
187 | break; | |
234967c9 | 188 | case 'i': /* IMS */ |
189 | ims = (time_t) atoi(optarg); | |
190 | break; | |
191 | case 'm': | |
192 | method = xstrdup(optarg); | |
193 | break; | |
b3b64e58 | 194 | case 't': |
195 | method = xstrdup("TRACE"); | |
196 | max_forwards = atoi(optarg); | |
197 | break; | |
090089c4 | 198 | case '?': /* usage */ |
199 | default: | |
200 | usage(argv[0]); | |
201 | break; | |
202 | } | |
203 | } | |
204 | /* Connect to the server */ | |
205 | if ((conn = socket(PF_INET, SOCK_STREAM, 0)) < 0) { | |
206 | perror("client: socket"); | |
207 | exit(1); | |
208 | } | |
209 | if (client_comm_connect(conn, hostname, port) < 0) { | |
210 | if (errno == 0) { | |
211 | fprintf(stderr, "client: ERROR: Cannot connect to %s:%d: Host unknown.\n", hostname, port); | |
212 | } else { | |
213 | char tbuf[BUFSIZ]; | |
042461c3 | 214 | snprintf(tbuf, BUFSIZ, "client: ERROR: Cannot connect to %s:%d", |
090089c4 | 215 | hostname, port); |
216 | perror(tbuf); | |
217 | } | |
218 | exit(1); | |
219 | } | |
220 | /* Build the HTTP request */ | |
042461c3 | 221 | snprintf(msg, BUFSIZ, "%s %s HTTP/1.0\r\n", method, url); |
090089c4 | 222 | if (reload) { |
042461c3 | 223 | snprintf(buf, BUFSIZ, "Pragma: no-cache\r\n"); |
234967c9 | 224 | strcat(msg, buf); |
225 | } | |
88738790 | 226 | if (opt_noaccept == 0) { |
042461c3 | 227 | snprintf(buf, BUFSIZ, "Accept: */*\r\n"); |
88738790 | 228 | strcat(msg, buf); |
229 | } | |
234967c9 | 230 | if (ims) { |
042461c3 | 231 | snprintf(buf, BUFSIZ, "If-Modified-Since: %s\r\n", mkrfc1123(ims)); |
234967c9 | 232 | strcat(msg, buf); |
090089c4 | 233 | } |
b3b64e58 | 234 | if (max_forwards > -1) { |
042461c3 | 235 | snprintf(buf, BUFSIZ, "Max-Forwards: %d\r\n", max_forwards); |
b3b64e58 | 236 | strcat(msg, buf); |
237 | } | |
599eadbe | 238 | if (keep_alive) { |
042461c3 | 239 | snprintf(buf, BUFSIZ, "Proxy-Connection: Keep-Alive\r\n"); |
599eadbe | 240 | strcat(msg, buf); |
241 | } | |
042461c3 | 242 | snprintf(buf, BUFSIZ, "\r\n"); |
234967c9 | 243 | strcat(msg, buf); |
090089c4 | 244 | |
245 | /* Send the HTTP request */ | |
246 | bytesWritten = write(conn, msg, strlen(msg)); | |
247 | if (bytesWritten < 0) { | |
248 | perror("client: ERROR: write"); | |
249 | exit(1); | |
250 | } else if (bytesWritten != strlen(msg)) { | |
251 | fprintf(stderr, "client: ERROR: Cannot send request?: %s\n", msg); | |
252 | exit(1); | |
253 | } | |
254 | /* Read the data */ | |
255 | while ((len = read(conn, buf, sizeof(buf))) > 0) { | |
256 | if (to_stdout) | |
257 | fwrite(buf, len, 1, stdout); | |
258 | } | |
259 | (void) close(conn); /* done with socket */ | |
260 | exit(0); | |
261 | /*NOTREACHED */ | |
983061ed | 262 | return 0; |
090089c4 | 263 | } |
264 | ||
b8d8561b | 265 | static int |
266 | client_comm_connect(int sock, char *dest_host, u_short dest_port) | |
090089c4 | 267 | { |
0ee4272b | 268 | const struct hostent *hp; |
090089c4 | 269 | static struct sockaddr_in to_addr; |
270 | ||
271 | /* Set up the destination socket address for message to send to. */ | |
272 | to_addr.sin_family = AF_INET; | |
273 | ||
274 | if ((hp = gethostbyname(dest_host)) == 0) { | |
275 | return (-1); | |
276 | } | |
30a4f2a8 | 277 | xmemcpy(&to_addr.sin_addr, hp->h_addr, hp->h_length); |
090089c4 | 278 | to_addr.sin_port = htons(dest_port); |
279 | return connect(sock, (struct sockaddr *) &to_addr, sizeof(struct sockaddr_in)); | |
280 | } |