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