]> git.ipfire.org Git - thirdparty/cups.git/blame - cups/testhttp.c
Load cups into easysw/current.
[thirdparty/cups.git] / cups / testhttp.c
CommitLineData
ef416fc2 1/*
2 * "$Id: testhttp.c 4809 2005-10-21 19:43:55Z mike $"
3 *
4 * HTTP test program for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2005 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * This file is subject to the Apple OS-Developed Software exception.
25 *
26 * Contents:
27 *
28 * main() - Main entry.
29 */
30
31/*
32 * Include necessary headers...
33 */
34
35#include <stdio.h>
36#include <stdlib.h>
37#include "http.h"
38#include "string.h"
39
40
41/*
42 * Types and structures...
43 */
44
45typedef struct uri_test_s /**** URI test cases ****/
46{
47 http_uri_status_t result; /* Expected return value */
48 const char *uri, /* URI */
49 *scheme, /* Scheme string */
50 *username, /* Username:password string */
51 *hostname, /* Hostname string */
52 *resource; /* Resource string */
53 int port, /* Port number */
54 assemble_port; /* Port number for httpAssembleURI() */
55} uri_test_t;
56
57
58/*
59 * Local globals...
60 */
61
62static uri_test_t uri_tests[] = /* URI test data */
63 {
64 /* Start with valid URIs */
65 { HTTP_URI_OK, "file:/filename",
66 "file", "", "", "/filename", 0, 0 },
67 { HTTP_URI_OK, "file:/filename%20with%20spaces",
68 "file", "", "", "/filename with spaces", 0, 0 },
69 { HTTP_URI_OK, "file:///filename",
70 "file", "", "", "/filename", 0, 0 },
71 { HTTP_URI_OK, "file:///filename%20with%20spaces",
72 "file", "", "", "/filename with spaces", 0, 0 },
73 { HTTP_URI_OK, "file://localhost/filename",
74 "file", "", "localhost", "/filename", 0, 0 },
75 { HTTP_URI_OK, "file://localhost/filename%20with%20spaces",
76 "file", "", "localhost", "/filename with spaces", 0, 0 },
77 { HTTP_URI_OK, "http://server/",
78 "http", "", "server", "/", 80, 0 },
79 { HTTP_URI_OK, "http://username@server/",
80 "http", "username", "server", "/", 80, 0 },
81 { HTTP_URI_OK, "http://username:passwor%64@server/",
82 "http", "username:password", "server", "/", 80, 0 },
83 { HTTP_URI_OK, "http://username:passwor%64@server:8080/",
84 "http", "username:password", "server", "/", 8080, 8080 },
85 { HTTP_URI_OK, "http://username:passwor%64@server:8080/directory/filename",
86 "http", "username:password", "server", "/directory/filename", 8080, 8080 },
87 { HTTP_URI_OK, "https://username:passwor%64@server/directory/filename",
88 "https", "username:password", "server", "/directory/filename", 443, 0 },
89 { HTTP_URI_OK, "ipp://username:passwor%64@[::1]/ipp",
90 "ipp", "username:password", "::1", "/ipp", 631, 0 },
91 { HTTP_URI_OK, "lpd://server/queue?reserve=yes",
92 "lpd", "", "server", "/queue?reserve=yes", 515, 0 },
93 { HTTP_URI_OK, "mailto:user@domain.com",
94 "mailto", "", "", "user@domain.com", 0, 0 },
95 { HTTP_URI_OK, "socket://server/",
96 "socket", "", "server", "/", 9100, 0 },
97 { HTTP_URI_OK, "ipp://username:password@[v1.fe80::200:1234:5678:9abc+eth0]:999/ipp",
98 "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999 },
99
100 /* Missing scheme */
101 { HTTP_URI_MISSING_SCHEME, "/path/to/file/index.html",
102 "file", "", "", "/path/to/file/index.html", 0, 0 },
103 { HTTP_URI_MISSING_SCHEME, "//server/ipp",
104 "ipp", "", "server", "/ipp", 631, 0 },
105
106 /* Unknown scheme */
107 { HTTP_URI_UNKNOWN_SCHEME, "vendor://server/resource",
108 "vendor", "", "server", "/resource", 0, 0 },
109
110 /* Missing resource */
111 { HTTP_URI_MISSING_RESOURCE, "socket://[::192.168.2.1]",
112 "socket", "", "::192.168.2.1", "/", 9100, 0 },
113
114 /* Bad URI */
115 { HTTP_URI_BAD_URI, "",
116 "", "", "", "", 0, 0 },
117
118 /* Bad scheme */
119 { HTTP_URI_BAD_SCHEME, "bad_scheme://server/resource",
120 "", "", "", "", 0, 0 },
121
122 /* Bad username */
123 { HTTP_URI_BAD_USERNAME, "http://username:passwor%6@server/resource",
124 "http", "", "", "", 80, 0 },
125
126 /* Bad hostname */
127 { HTTP_URI_BAD_HOSTNAME, "http://[/::1]/index.html",
128 "http", "", "", "", 80, 0 },
129 { HTTP_URI_BAD_HOSTNAME, "http://[",
130 "http", "", "", "", 80, 0 },
131 { HTTP_URI_BAD_HOSTNAME, "http://serve%7/index.html",
132 "http", "", "", "", 80, 0 },
133
134 /* Bad port number */
135 { HTTP_URI_BAD_PORT, "http://127.0.0.1:9999a/index.html",
136 "http", "", "127.0.0.1", "", 0, 0 },
137
138 /* Bad resource */
139 { HTTP_URI_BAD_RESOURCE, "http://server/index.html%",
140 "http", "", "server", "", 80, 0 }
141 };
142static const char * const base64_tests[][2] =
143 {
144 { "A", "QQ==" },
145 /* 010000 01 */
146 { "AB", "QUI=" },
147 /* 010000 010100 0010 */
148 { "ABC", "QUJD" },
149 /* 010000 010100 001001 000011 */
150 { "ABCD", "QUJDRA==" },
151 /* 010000 010100 001001 000011 010001 00 */
152 { "ABCDE", "QUJDREU=" },
153 /* 010000 010100 001001 000011 010001 000100 0101 */
154 { "ABCDEF", "QUJDREVG" },
155 /* 010000 010100 001001 000011 010001 000100 010101 000110 */
156 };
157
158
159/*
160 * 'main()' - Main entry.
161 */
162
163int /* O - Exit status */
164main(int argc, /* I - Number of command-line arguments */
165 char *argv[]) /* I - Command-line arguments */
166{
167 int i, j, k; /* Looping vars */
168 http_t *http; /* HTTP connection */
169 http_status_t status; /* Status of GET command */
170 int failures; /* Number of test failures */
171 char buffer[8192]; /* Input buffer */
172 long bytes; /* Number of bytes read */
173 FILE *out; /* Output file */
174 char encode[256], /* Base64-encoded string */
175 decode[256]; /* Base64-decoded string */
176 int decodelen; /* Length of decoded string */
177 char scheme[HTTP_MAX_URI], /* Scheme from URI */
178 hostname[HTTP_MAX_URI], /* Hostname from URI */
179 username[HTTP_MAX_URI], /* Username:password from URI */
180 resource[HTTP_MAX_URI]; /* Resource from URI */
181 int port; /* Port number from URI */
182 http_uri_status_t uri_status; /* Status of URI separation */
183 http_addrlist_t *addrlist, /* Address list */
184 *addr; /* Current address */
185 off_t length, total; /* Length and total bytes */
186 time_t start, current; /* Start and end time */
187 static const char * const uri_status_strings[] =
188 {
189 "HTTP_URI_OVERFLOW",
190 "HTTP_URI_BAD_ARGUMENTS",
191 "HTTP_URI_BAD_RESOURCE",
192 "HTTP_URI_BAD_PORT",
193 "HTTP_URI_BAD_HOSTNAME",
194 "HTTP_URI_BAD_USERNAME",
195 "HTTP_URI_BAD_SCHEME",
196 "HTTP_URI_BAD_URI",
197 "HTTP_URI_OK",
198 "HTTP_URI_MISSING_SCHEME",
199 "HTTP_URI_UNKNOWN_SCHEME",
200 "HTTP_URI_MISSING_RESOURCE"
201 };
202
203
204 /*
205 * Do API tests if we don't have a URL on the command-line...
206 */
207
208 if (argc == 1)
209 {
210 failures = 0;
211
212 /*
213 * httpGetDateString()/httpGetDateTime()
214 */
215
216 fputs("httpGetDateString()/httpGetDateTime(): ", stdout);
217
218 start = time(NULL);
219 strcpy(buffer, httpGetDateString(start));
220 current = httpGetDateTime(buffer);
221
222 i = (int)(current - start);
223 if (i < 0)
224 i = -i;
225
226 if (!i)
227 puts("PASS");
228 else
229 {
230 failures ++;
231 puts("FAIL");
232 printf(" Difference is %d seconds, %02d:%02d:%02d...\n", i, i / 3600,
233 (i / 60) % 60, i % 60);
234 printf(" httpGetDateString(%d) returned \"%s\"\n", (int)start, buffer);
235 printf(" httpGetDateTime(\"%s\") returned %d\n", buffer, (int)current);
236 printf(" httpGetDateString(%d) returned \"%s\"\n", (int)current,
237 httpGetDateString(current));
238 }
239
240 /*
241 * httpDecode64_2()/httpEncode64_2()
242 */
243
244 fputs("httpDecode64_2()/httpEncode64_2(): ", stdout);
245
246 for (i = 0, j = 0; i < (int)(sizeof(base64_tests) / sizeof(base64_tests[0])); i ++)
247 {
248 httpEncode64_2(encode, sizeof(encode), base64_tests[i][0],
249 strlen(base64_tests[i][0]));
250 decodelen = (int)sizeof(decode);
251 httpDecode64_2(decode, &decodelen, base64_tests[i][1]);
252
253 if (strcmp(decode, base64_tests[i][0]))
254 {
255 failures ++;
256
257 if (j)
258 {
259 puts("FAIL");
260 j = 1;
261 }
262
263 printf(" httpDecode64_2() returned \"%s\", expected \"%s\"...\n",
264 decode, base64_tests[i][0]);
265 }
266
267 if (strcmp(encode, base64_tests[i][1]))
268 {
269 failures ++;
270
271 if (j)
272 {
273 puts("FAIL");
274 j = 1;
275 }
276
277 printf(" httpEncode64_2() returned \"%s\", expected \"%s\"...\n",
278 encode, base64_tests[i][1]);
279 }
280 }
281
282 if (!j)
283 puts("PASS");
284
285 /*
286 * httpGetHostname()
287 */
288
289 fputs("httpGetHostname(): ", stdout);
290
291 if (httpGetHostname(hostname, sizeof(hostname)))
292 printf("PASS (%s)\n", hostname);
293 else
294 {
295 failures ++;
296 puts("FAIL");
297 }
298
299 /*
300 * httpAddrGetList()
301 */
302
303 fputs("httpAddrGetList(): ", stdout);
304
305 addrlist = httpAddrGetList(hostname, AF_UNSPEC, NULL);
306 if (addrlist)
307 {
308 for (i = 0, addr = addrlist; addr; i ++, addr = addr->next);
309
310 printf("PASS (%d address(es) for %s)\n", i, hostname);
311 httpAddrFreeList(addrlist);
312 }
313 else
314 {
315 failures ++;
316 puts("FAIL");
317 }
318
319 /*
320 * Test httpSeparateURI()...
321 */
322
323 fputs("httpSeparateURI(): ", stdout);
324 for (i = 0, j = 0; i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); i ++)
325 {
326 uri_status = httpSeparateURI(uri_tests[i].uri, scheme, sizeof(scheme),
327 username, sizeof(username),
328 hostname, sizeof(hostname), &port,
329 resource, sizeof(resource));
330 if (uri_status != uri_tests[i].result ||
331 strcmp(scheme, uri_tests[i].scheme) ||
332 strcmp(username, uri_tests[i].username) ||
333 strcmp(hostname, uri_tests[i].hostname) ||
334 port != uri_tests[i].port ||
335 strcmp(resource, uri_tests[i].resource))
336 {
337 failures ++;
338
339 if (!j)
340 {
341 puts("FAIL");
342 j = 1;
343 }
344
345 printf(" \"%s\":\n", uri_tests[i].uri);
346
347 if (uri_status != uri_tests[i].result)
348 printf(" Returned %s instead of %s\n",
349 uri_status_strings[uri_status + 8],
350 uri_status_strings[uri_tests[i].result + 8]);
351
352 if (strcmp(scheme, uri_tests[i].scheme))
353 printf(" Scheme \"%s\" instead of \"%s\"\n",
354 scheme, uri_tests[i].scheme);
355
356 if (strcmp(username, uri_tests[i].username))
357 printf(" Username \"%s\" instead of \"%s\"\n",
358 username, uri_tests[i].username);
359
360 if (strcmp(hostname, uri_tests[i].hostname))
361 printf(" Hostname \"%s\" instead of \"%s\"\n",
362 hostname, uri_tests[i].hostname);
363
364 if (port != uri_tests[i].port)
365 printf(" Port %d instead of %d\n",
366 port, uri_tests[i].port);
367
368 if (strcmp(resource, uri_tests[i].resource))
369 printf(" Resource \"%s\" instead of \"%s\"\n",
370 resource, uri_tests[i].resource);
371 }
372 }
373
374 if (!j)
375 printf("PASS (%d URIs tested)\n",
376 (int)(sizeof(uri_tests) / sizeof(uri_tests[0])));
377
378 /*
379 * Test httpAssembleURI()...
380 */
381
382 fputs("httpAssembleURI(): ", stdout);
383 for (i = 0, j = 0, k = 0;
384 i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0]));
385 i ++)
386 if (uri_tests[i].result == HTTP_URI_OK &&
387 !strstr(uri_tests[i].uri, "%64") &&
388 strstr(uri_tests[i].uri, "//"))
389 {
390 k ++;
391 uri_status = httpAssembleURI(buffer, sizeof(buffer),
392 uri_tests[i].scheme,
393 uri_tests[i].username,
394 uri_tests[i].hostname,
395 uri_tests[i].assemble_port,
396 uri_tests[i].resource);
397
398 if (uri_status != HTTP_URI_OK)
399 {
400 failures ++;
401
402 if (!j)
403 {
404 puts("FAIL");
405 j = 1;
406 }
407
408 printf(" \"%s\": %s\n", uri_tests[i].uri,
409 uri_status_strings[uri_status + 8]);
410 }
411 else if (strcmp(buffer, uri_tests[i].uri))
412 {
413 failures ++;
414
415 if (!j)
416 {
417 puts("FAIL");
418 j = 1;
419 }
420
421 printf(" \"%s\": assembled = \"%s\"\n", uri_tests[i].uri,
422 buffer);
423 }
424 }
425
426 if (!j)
427 printf("PASS (%d URIs tested)\n", k);
428
429 /*
430 * Show a summary and return...
431 */
432
433 if (failures)
434 printf("\n%d TESTS FAILED!\n", failures);
435 else
436 puts("\nALL TESTS PASSED!");
437
438 return (failures);
439 }
440
441 /*
442 * Test HTTP GET requests...
443 */
444
445 http = NULL;
446 out = stdout;
447
448 for (i = 1; i < argc; i ++)
449 {
450 if (!strcmp(argv[i], "-o"))
451 {
452 i ++;
453 if (i >= argc)
454 break;
455
456 out = fopen(argv[i], "wb");
457 continue;
458 }
459
460 httpSeparateURI(argv[i], scheme, sizeof(scheme), username, sizeof(username),
461 hostname, sizeof(hostname), &port,
462 resource, sizeof(resource));
463
464 http = httpConnectEncrypt(hostname, port, HTTP_ENCRYPT_IF_REQUESTED);
465 if (http == NULL)
466 {
467 perror(hostname);
468 continue;
469 }
470 printf("Requesting file \"%s\"...\n", resource);
471 httpClearFields(http);
472 httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
473 httpGet(http, resource);
474 while ((status = httpUpdate(http)) == HTTP_CONTINUE);
475
476 if (status == HTTP_OK)
477 puts("GET OK:");
478 else
479 printf("GET failed with status %d...\n", status);
480
481
482 start = time(NULL);
483 length = httpGetLength2(http);
484 total = 0;
485
486 while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
487 {
488 total += bytes;
489 fwrite(buffer, bytes, 1, out);
490 if (out != stdout)
491 {
492 current = time(NULL);
493 if (current == start) current ++;
494 printf("\r" CUPS_LLFMT "/" CUPS_LLFMT " bytes ("
495 CUPS_LLFMT " bytes/sec) ", total, length,
496 total / (current - start));
497 fflush(stdout);
498 }
499 }
500 }
501
502 puts("Closing connection to server...");
503 httpClose(http);
504
505 if (out != stdout)
506 fclose(out);
507
508 return (0);
509}
510
511
512/*
513 * End of "$Id: testhttp.c 4809 2005-10-21 19:43:55Z mike $".
514 */