1/* 2 * "$Id: testhttp.c 12078 2014-07-31 11:45:57Z msweet $" 3 * 4 * HTTP test program for CUPS. 5 * 6 * Copyright 2007-2014 by Apple Inc. 7 * Copyright 1997-2006 by Easy Software Products. 8 * 9 * These coded instructions, statements, and computer programs are the 10 * property of Apple Inc. and are protected by Federal copyright 11 * law. Distribution and use rights are outlined in the file "LICENSE.txt" 12 * which should have been included with this file. If this file is 13 * file is missing or damaged, see the license at "http://www.cups.org/". 14 * 15 * This file is subject to the Apple OS-Developed Software exception. 16 */ 17 18/* 19 * Include necessary headers... 20 */ 21 22#include "cups-private.h" 23 24 25/* 26 * Types and structures... 27 */ 28 29typedef struct uri_test_s /**** URI test cases ****/ 30{ 31 http_uri_status_t result; /* Expected return value */ 32 const char *uri, /* URI */ 33 *scheme, /* Scheme string */ 34 *username, /* Username:password string */ 35 *hostname, /* Hostname string */ 36 *resource; /* Resource string */ 37 int port, /* Port number */ 38 assemble_port; /* Port number for httpAssembleURI() */ 39 http_uri_coding_t assemble_coding;/* Coding for httpAssembleURI() */ 40} uri_test_t; 41 42 43/* 44 * Local globals... 45 */ 46 47static uri_test_t uri_tests[] = /* URI test data */ 48 { 49 /* Start with valid URIs */ 50 { HTTP_URI_STATUS_OK, "file:/filename", 51 "file", "", "", "/filename", 0, 0, 52 HTTP_URI_CODING_MOST }, 53 { HTTP_URI_STATUS_OK, "file:/filename%20with%20spaces", 54 "file", "", "", "/filename with spaces", 0, 0, 55 HTTP_URI_CODING_MOST }, 56 { HTTP_URI_STATUS_OK, "file:///filename", 57 "file", "", "", "/filename", 0, 0, 58 HTTP_URI_CODING_MOST }, 59 { HTTP_URI_STATUS_OK, "file:///filename%20with%20spaces", 60 "file", "", "", "/filename with spaces", 0, 0, 61 HTTP_URI_CODING_MOST }, 62 { HTTP_URI_STATUS_OK, "file://localhost/filename", 63 "file", "", "localhost", "/filename", 0, 0, 64 HTTP_URI_CODING_MOST }, 65 { HTTP_URI_STATUS_OK, "file://localhost/filename%20with%20spaces", 66 "file", "", "localhost", "/filename with spaces", 0, 0, 67 HTTP_URI_CODING_MOST }, 68 { HTTP_URI_STATUS_OK, "http://server/", 69 "http", "", "server", "/", 80, 0, 70 HTTP_URI_CODING_MOST }, 71 { HTTP_URI_STATUS_OK, "http://username@server/", 72 "http", "username", "server", "/", 80, 0, 73 HTTP_URI_CODING_MOST }, 74 { HTTP_URI_STATUS_OK, "http://username:passwor%64@server/", 75 "http", "username:password", "server", "/", 80, 0, 76 HTTP_URI_CODING_MOST }, 77 { HTTP_URI_STATUS_OK, "http://username:passwor%64@server:8080/", 78 "http", "username:password", "server", "/", 8080, 8080, 79 HTTP_URI_CODING_MOST }, 80 { HTTP_URI_STATUS_OK, "http://username:passwor%64@server:8080/directory/filename", 81 "http", "username:password", "server", "/directory/filename", 8080, 8080, 82 HTTP_URI_CODING_MOST }, 83 { HTTP_URI_STATUS_OK, "http://[2000::10:100]:631/ipp", 84 "http", "", "2000::10:100", "/ipp", 631, 631, 85 HTTP_URI_CODING_MOST }, 86 { HTTP_URI_STATUS_OK, "https://username:passwor%64@server/directory/filename", 87 "https", "username:password", "server", "/directory/filename", 443, 0, 88 HTTP_URI_CODING_MOST }, 89 { HTTP_URI_STATUS_OK, "ipp://username:passwor%64@[::1]/ipp", 90 "ipp", "username:password", "::1", "/ipp", 631, 0, 91 HTTP_URI_CODING_MOST }, 92 { HTTP_URI_STATUS_OK, "lpd://server/queue?reserve=yes", 93 "lpd", "", "server", "/queue?reserve=yes", 515, 0, 94 HTTP_URI_CODING_MOST }, 95 { HTTP_URI_STATUS_OK, "mailto:user@domain.com", 96 "mailto", "", "", "user@domain.com", 0, 0, 97 HTTP_URI_CODING_MOST }, 98 { HTTP_URI_STATUS_OK, "socket://server/", 99 "socket", "", "server", "/", 9100, 0, 100 HTTP_URI_CODING_MOST }, 101 { HTTP_URI_STATUS_OK, "socket://192.168.1.1:9101/", 102 "socket", "", "192.168.1.1", "/", 9101, 9101, 103 HTTP_URI_CODING_MOST }, 104 { HTTP_URI_STATUS_OK, "tel:8005551212", 105 "tel", "", "", "8005551212", 0, 0, 106 HTTP_URI_CODING_MOST }, 107 { HTTP_URI_STATUS_OK, "ipp://username:password@[v1.fe80::200:1234:5678:9abc+eth0]:999/ipp", 108 "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999, 109 HTTP_URI_CODING_MOST }, 110 { HTTP_URI_STATUS_OK, "ipp://username:password@[fe80::200:1234:5678:9abc%25eth0]:999/ipp", 111 "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999, 112 (http_uri_coding_t)(HTTP_URI_CODING_MOST | HTTP_URI_CODING_RFC6874) }, 113 { HTTP_URI_STATUS_OK, "http://server/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", 114 "http", "", "server", "/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", 80, 0, 115 HTTP_URI_CODING_MOST }, 116 { HTTP_URI_STATUS_OK, "lpd://Acme%20Laser%20(01%3A23%3A45).local._tcp._printer/", 117 "lpd", "", "Acme Laser (01:23:45).local._tcp._printer", "/", 515, 0, 118 HTTP_URI_CODING_MOST }, 119 { HTTP_URI_STATUS_OK, "ipp://HP%20Officejet%204500%20G510n-z%20%40%20Will's%20MacBook%20Pro%2015%22._ipp._tcp.local./", 120 "ipp", "", "HP Officejet 4500 G510n-z @ Will's MacBook Pro 15\"._ipp._tcp.local.", "/", 631, 0, 121 HTTP_URI_CODING_MOST }, 122 { HTTP_URI_STATUS_OK, "ipp://%22%23%2F%3A%3C%3E%3F%40%5B%5C%5D%5E%60%7B%7C%7D/", 123 "ipp", "", "\"#/:<>?@[\\]^`{|}", "/", 631, 0, 124 HTTP_URI_CODING_MOST }, 125 126 /* Missing scheme */ 127 { HTTP_URI_STATUS_MISSING_SCHEME, "/path/to/file/index.html", 128 "file", "", "", "/path/to/file/index.html", 0, 0, 129 HTTP_URI_CODING_MOST }, 130 { HTTP_URI_STATUS_MISSING_SCHEME, "//server/ipp", 131 "ipp", "", "server", "/ipp", 631, 0, 132 HTTP_URI_CODING_MOST }, 133 134 /* Unknown scheme */ 135 { HTTP_URI_STATUS_UNKNOWN_SCHEME, "vendor://server/resource", 136 "vendor", "", "server", "/resource", 0, 0, 137 HTTP_URI_CODING_MOST }, 138 139 /* Missing resource */ 140 { HTTP_URI_STATUS_MISSING_RESOURCE, "socket://[::192.168.2.1]", 141 "socket", "", "::192.168.2.1", "/", 9100, 0, 142 HTTP_URI_CODING_MOST }, 143 { HTTP_URI_STATUS_MISSING_RESOURCE, "socket://192.168.1.1:9101", 144 "socket", "", "192.168.1.1", "/", 9101, 0, 145 HTTP_URI_CODING_MOST }, 146 147 /* Bad URI */ 148 { HTTP_URI_STATUS_BAD_URI, "", 149 "", "", "", "", 0, 0, 150 HTTP_URI_CODING_MOST }, 151 152 /* Bad scheme */ 153 { HTTP_URI_STATUS_BAD_SCHEME, "bad_scheme://server/resource", 154 "", "", "", "", 0, 0, 155 HTTP_URI_CODING_MOST }, 156 157 /* Bad username */ 158 { HTTP_URI_STATUS_BAD_USERNAME, "http://username:passwor%6@server/resource", 159 "http", "", "", "", 80, 0, 160 HTTP_URI_CODING_MOST }, 161 162 /* Bad hostname */ 163 { HTTP_URI_STATUS_BAD_HOSTNAME, "http://[/::1]/index.html", 164 "http", "", "", "", 80, 0, 165 HTTP_URI_CODING_MOST }, 166 { HTTP_URI_STATUS_BAD_HOSTNAME, "http://[", 167 "http", "", "", "", 80, 0, 168 HTTP_URI_CODING_MOST }, 169 { HTTP_URI_STATUS_BAD_HOSTNAME, "http://serve%7/index.html", 170 "http", "", "", "", 80, 0, 171 HTTP_URI_CODING_MOST }, 172 { HTTP_URI_STATUS_BAD_HOSTNAME, "http://server with spaces/index.html", 173 "http", "", "", "", 80, 0, 174 HTTP_URI_CODING_MOST }, 175 { HTTP_URI_STATUS_BAD_HOSTNAME, "ipp://\"#/:<>?@[\\]^`{|}/", 176 "ipp", "", "", "", 631, 0, 177 HTTP_URI_CODING_MOST }, 178 179 /* Bad port number */ 180 { HTTP_URI_STATUS_BAD_PORT, "http://127.0.0.1:9999a/index.html", 181 "http", "", "127.0.0.1", "", 0, 0, 182 HTTP_URI_CODING_MOST }, 183 184 /* Bad resource */ 185 { HTTP_URI_STATUS_BAD_RESOURCE, "http://server/index.html%", 186 "http", "", "server", "", 80, 0, 187 HTTP_URI_CODING_MOST }, 188 { HTTP_URI_STATUS_BAD_RESOURCE, "http://server/index with spaces.html", 189 "http", "", "server", "", 80, 0, 190 HTTP_URI_CODING_MOST } 191 }; 192static const char * const base64_tests[][2] = 193 { 194 { "A", "QQ==" }, 195 /* 010000 01 */ 196 { "AB", "QUI=" }, 197 /* 010000 010100 0010 */ 198 { "ABC", "QUJD" }, 199 /* 010000 010100 001001 000011 */ 200 { "ABCD", "QUJDRA==" }, 201 /* 010000 010100 001001 000011 010001 00 */ 202 { "ABCDE", "QUJDREU=" }, 203 /* 010000 010100 001001 000011 010001 000100 0101 */ 204 { "ABCDEF", "QUJDREVG" }, 205 /* 010000 010100 001001 000011 010001 000100 010101 000110 */ 206 }; 207 208 209/* 210 * 'main()' - Main entry. 211 */ 212 213int /* O - Exit status */ 214main(int argc, /* I - Number of command-line arguments */ 215 char *argv[]) /* I - Command-line arguments */ 216{ 217 int i, j, k; /* Looping vars */ 218 http_t *http; /* HTTP connection */ 219 http_encryption_t encryption; /* Encryption type */ 220 http_status_t status; /* Status of GET command */ 221 int failures; /* Number of test failures */ 222 char buffer[8192]; /* Input buffer */ 223 long bytes; /* Number of bytes read */ 224 FILE *out; /* Output file */ 225 char encode[256], /* Base64-encoded string */ 226 decode[256]; /* Base64-decoded string */ 227 int decodelen; /* Length of decoded string */ 228 char scheme[HTTP_MAX_URI], /* Scheme from URI */ 229 hostname[HTTP_MAX_URI], /* Hostname from URI */ 230 username[HTTP_MAX_URI], /* Username:password from URI */ 231 resource[HTTP_MAX_URI]; /* Resource from URI */ 232 int port; /* Port number from URI */ 233 http_uri_status_t uri_status; /* Status of URI separation */ 234 http_addrlist_t *addrlist, /* Address list */ 235 *addr; /* Current address */ 236 off_t length, total; /* Length and total bytes */ 237 time_t start, current; /* Start and end time */ 238 const char *encoding; /* Negotiated Content-Encoding */ 239 static const char * const uri_status_strings[] = 240 { 241 "HTTP_URI_STATUS_OVERFLOW", 242 "HTTP_URI_STATUS_BAD_ARGUMENTS", 243 "HTTP_URI_STATUS_BAD_RESOURCE", 244 "HTTP_URI_STATUS_BAD_PORT", 245 "HTTP_URI_STATUS_BAD_HOSTNAME", 246 "HTTP_URI_STATUS_BAD_USERNAME", 247 "HTTP_URI_STATUS_BAD_SCHEME", 248 "HTTP_URI_STATUS_BAD_URI", 249 "HTTP_URI_STATUS_OK", 250 "HTTP_URI_STATUS_MISSING_SCHEME", 251 "HTTP_URI_STATUS_UNKNOWN_SCHEME", 252 "HTTP_URI_STATUS_MISSING_RESOURCE" 253 }; 254 255 256 /* 257 * Do API tests if we don't have a URL on the command-line... 258 */ 259 260 if (argc == 1) 261 { 262 failures = 0; 263 264 /* 265 * httpGetDateString()/httpGetDateTime() 266 */ 267 268 fputs("httpGetDateString()/httpGetDateTime(): ", stdout); 269 270 start = time(NULL); 271 strlcpy(buffer, httpGetDateString(start), sizeof(buffer)); 272 current = httpGetDateTime(buffer); 273 274 i = (int)(current - start); 275 if (i < 0) 276 i = -i; 277 278 if (!i) 279 puts("PASS"); 280 else 281 { 282 failures ++; 283 puts("FAIL"); 284 printf(" Difference is %d seconds, %02d:%02d:%02d...\n", i, i / 3600, 285 (i / 60) % 60, i % 60); 286 printf(" httpGetDateString(%d) returned \"%s\"\n", (int)start, buffer); 287 printf(" httpGetDateTime(\"%s\") returned %d\n", buffer, (int)current); 288 printf(" httpGetDateString(%d) returned \"%s\"\n", (int)current, 289 httpGetDateString(current)); 290 } 291 292 /* 293 * httpDecode64_2()/httpEncode64_2() 294 */ 295 296 fputs("httpDecode64_2()/httpEncode64_2(): ", stdout); 297 298 for (i = 0, j = 0; i < (int)(sizeof(base64_tests) / sizeof(base64_tests[0])); i ++) 299 { 300 httpEncode64_2(encode, sizeof(encode), base64_tests[i][0], 301 (int)strlen(base64_tests[i][0])); 302 decodelen = (int)sizeof(decode); 303 httpDecode64_2(decode, &decodelen, base64_tests[i][1]); 304 305 if (strcmp(decode, base64_tests[i][0])) 306 { 307 failures ++; 308 309 if (j) 310 { 311 puts("FAIL"); 312 j = 1; 313 } 314 315 printf(" httpDecode64_2() returned \"%s\", expected \"%s\"...\n", 316 decode, base64_tests[i][0]); 317 } 318 319 if (strcmp(encode, base64_tests[i][1])) 320 { 321 failures ++; 322 323 if (j) 324 { 325 puts("FAIL"); 326 j = 1; 327 } 328 329 printf(" httpEncode64_2() returned \"%s\", expected \"%s\"...\n", 330 encode, base64_tests[i][1]); 331 } 332 } 333 334 if (!j) 335 puts("PASS"); 336 337 /* 338 * httpGetHostname() 339 */ 340 341 fputs("httpGetHostname(): ", stdout); 342 343 if (httpGetHostname(NULL, hostname, sizeof(hostname))) 344 printf("PASS (%s)\n", hostname); 345 else 346 { 347 failures ++; 348 puts("FAIL"); 349 } 350 351 /* 352 * httpAddrGetList() 353 */ 354 355 printf("httpAddrGetList(%s): ", hostname); 356 357 addrlist = httpAddrGetList(hostname, AF_UNSPEC, NULL); 358 if (addrlist) 359 { 360 for (i = 0, addr = addrlist; addr; i ++, addr = addr->next) 361 { 362 char numeric[1024]; /* Numeric IP address */ 363 364 365 httpAddrString(&(addr->addr), numeric, sizeof(numeric)); 366 if (!strcmp(numeric, "UNKNOWN")) 367 break; 368 } 369 370 if (addr) 371 printf("FAIL (bad address for %s)\n", hostname); 372 else 373 printf("PASS (%d address(es) for %s)\n", i, hostname); 374 375 httpAddrFreeList(addrlist); 376 } 377 else if (isdigit(hostname[0] & 255)) 378 { 379 puts("FAIL (ignored because hostname is numeric)"); 380 } 381 else 382 { 383 failures ++; 384 puts("FAIL"); 385 } 386 387 /* 388 * Test httpSeparateURI()... 389 */ 390 391 fputs("httpSeparateURI(): ", stdout); 392 for (i = 0, j = 0; i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); i ++) 393 { 394 uri_status = httpSeparateURI(HTTP_URI_CODING_MOST, 395 uri_tests[i].uri, scheme, sizeof(scheme), 396 username, sizeof(username), 397 hostname, sizeof(hostname), &port, 398 resource, sizeof(resource)); 399 if (uri_status != uri_tests[i].result || 400 strcmp(scheme, uri_tests[i].scheme) || 401 strcmp(username, uri_tests[i].username) || 402 strcmp(hostname, uri_tests[i].hostname) || 403 port != uri_tests[i].port || 404 strcmp(resource, uri_tests[i].resource)) 405 { 406 failures ++; 407 408 if (!j) 409 { 410 puts("FAIL"); 411 j = 1; 412 } 413 414 printf(" \"%s\":\n", uri_tests[i].uri); 415 416 if (uri_status != uri_tests[i].result) 417 printf(" Returned %s instead of %s\n", 418 uri_status_strings[uri_status + 8], 419 uri_status_strings[uri_tests[i].result + 8]); 420 421 if (strcmp(scheme, uri_tests[i].scheme)) 422 printf(" Scheme \"%s\" instead of \"%s\"\n", 423 scheme, uri_tests[i].scheme); 424 425 if (strcmp(username, uri_tests[i].username)) 426 printf(" Username \"%s\" instead of \"%s\"\n", 427 username, uri_tests[i].username); 428 429 if (strcmp(hostname, uri_tests[i].hostname)) 430 printf(" Hostname \"%s\" instead of \"%s\"\n", 431 hostname, uri_tests[i].hostname); 432 433 if (port != uri_tests[i].port) 434 printf(" Port %d instead of %d\n", 435 port, uri_tests[i].port); 436 437 if (strcmp(resource, uri_tests[i].resource)) 438 printf(" Resource \"%s\" instead of \"%s\"\n", 439 resource, uri_tests[i].resource); 440 } 441 } 442 443 if (!j) 444 printf("PASS (%d URIs tested)\n", 445 (int)(sizeof(uri_tests) / sizeof(uri_tests[0]))); 446 447 /* 448 * Test httpAssembleURI()... 449 */ 450 451 fputs("httpAssembleURI(): ", stdout); 452 for (i = 0, j = 0, k = 0; 453 i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); 454 i ++) 455 if (uri_tests[i].result == HTTP_URI_STATUS_OK && 456 !strstr(uri_tests[i].uri, "%64") && 457 strstr(uri_tests[i].uri, "//")) 458 { 459 k ++; 460 uri_status = httpAssembleURI(uri_tests[i].assemble_coding, 461 buffer, sizeof(buffer), 462 uri_tests[i].scheme, 463 uri_tests[i].username, 464 uri_tests[i].hostname, 465 uri_tests[i].assemble_port, 466 uri_tests[i].resource); 467 468 if (uri_status != HTTP_URI_STATUS_OK) 469 { 470 failures ++; 471 472 if (!j) 473 { 474 puts("FAIL"); 475 j = 1; 476 } 477 478 printf(" \"%s\": %s\n", uri_tests[i].uri, 479 uri_status_strings[uri_status + 8]); 480 } 481 else if (strcmp(buffer, uri_tests[i].uri)) 482 { 483 failures ++; 484 485 if (!j) 486 { 487 puts("FAIL"); 488 j = 1; 489 } 490 491 printf(" \"%s\": assembled = \"%s\"\n", uri_tests[i].uri, 492 buffer); 493 } 494 } 495 496 if (!j) 497 printf("PASS (%d URIs tested)\n", k); 498 499 /* 500 * httpAssembleUUID 501 */ 502 503 fputs("httpAssembleUUID: ", stdout); 504 httpAssembleUUID("hostname.example.com", 631, "printer", 12345, buffer, 505 sizeof(buffer)); 506 if (strncmp(buffer, "urn:uuid:", 9)) 507 { 508 printf("FAIL (%s)\n", buffer); 509 failures ++; 510 } 511 else 512 printf("PASS (%s)\n", buffer); 513 514 /* 515 * Show a summary and return... 516 */ 517 518 if (failures) 519 printf("\n%d TESTS FAILED!\n", failures); 520 else 521 puts("\nALL TESTS PASSED!"); 522 523 return (failures); 524 } 525 else if (strstr(argv[1], "._tcp")) 526 { 527 /* 528 * Test resolving an mDNS name. 529 */ 530 531 char resolved[1024]; /* Resolved URI */ 532 533 534 printf("_httpResolveURI(%s, _HTTP_RESOLVE_DEFAULT): ", argv[1]); 535 fflush(stdout); 536 537 if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 538 _HTTP_RESOLVE_DEFAULT, NULL, NULL)) 539 { 540 puts("FAIL"); 541 return (1); 542 } 543 else 544 printf("PASS (%s)\n", resolved); 545 546 printf("_httpResolveURI(%s, _HTTP_RESOLVE_FQDN): ", argv[1]); 547 fflush(stdout); 548 549 if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), 550 _HTTP_RESOLVE_FQDN, NULL, NULL)) 551 { 552 puts("FAIL"); 553 return (1); 554 } 555 else if (strstr(resolved, ".local:")) 556 { 557 printf("FAIL (%s)\n", resolved); 558 return (1); 559 } 560 else 561 { 562 printf("PASS (%s)\n", resolved); 563 return (0); 564 } 565 } 566 else if (!strcmp(argv[1], "-u") && argc == 3) 567 { 568 /* 569 * Test URI separation... 570 */ 571 572 uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, argv[2], scheme, 573 sizeof(scheme), username, sizeof(username), 574 hostname, sizeof(hostname), &port, 575 resource, sizeof(resource)); 576 printf("uri_status = %s\n", uri_status_strings[uri_status + 8]); 577 printf("scheme = \"%s\"\n", scheme); 578 printf("username = \"%s\"\n", username); 579 printf("hostname = \"%s\"\n", hostname); 580 printf("port = %d\n", port); 581 printf("resource = \"%s\"\n", resource); 582 583 return (0); 584 } 585 586 /* 587 * Test HTTP GET requests... 588 */ 589 590 http = NULL; 591 out = stdout; 592 593 for (i = 1; i < argc; i ++) 594 { 595 if (!strcmp(argv[i], "-o")) 596 { 597 i ++; 598 if (i >= argc) 599 break; 600 601 out = fopen(argv[i], "wb"); 602 continue; 603 } 604 605 httpSeparateURI(HTTP_URI_CODING_MOST, argv[i], scheme, sizeof(scheme), 606 username, sizeof(username), 607 hostname, sizeof(hostname), &port, 608 resource, sizeof(resource)); 609 610 if (!_cups_strcasecmp(scheme, "https") || !_cups_strcasecmp(scheme, "ipps") || 611 port == 443) 612 encryption = HTTP_ENCRYPTION_ALWAYS; 613 else 614 encryption = HTTP_ENCRYPTION_IF_REQUESTED; 615 616 http = httpConnect2(hostname, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL); 617 if (http == NULL) 618 { 619 perror(hostname); 620 continue; 621 } 622 623 if (httpIsEncrypted(http)) 624 { 625 cups_array_t *creds; 626 char info[1024]; 627 static const char *trusts[] = { "OK", "Invalid", "Changed", "Expired", "Renewed", "Unknown" }; 628 if (!httpCopyCredentials(http, &creds)) 629 { 630 cups_array_t *lcreds; 631 http_trust_t trust = httpCredentialsGetTrust(creds, hostname); 632 633 httpCredentialsString(creds, info, sizeof(info)); 634 635 printf("Count: %d\n", cupsArrayCount(creds)); 636 printf("Trust: %s\n", trusts[trust]); 637 printf("Expiration: %s\n", httpGetDateString(httpCredentialsGetExpiration(creds))); 638 printf("IsValidName: %d\n", httpCredentialsAreValidForName(creds, hostname)); 639 printf("String: \"%s\"\n", info); 640 641 printf("LoadCredentials: %d\n", httpLoadCredentials(NULL, &lcreds, hostname)); 642 httpCredentialsString(lcreds, info, sizeof(info)); 643 printf(" Count: %d\n", cupsArrayCount(lcreds)); 644 printf(" String: \"%s\"\n", info); 645 646 if (lcreds && cupsArrayCount(creds) == cupsArrayCount(lcreds)) 647 { 648 int i; 649 http_credential_t *cred, *lcred; 650 651 for (i = 1, cred = (http_credential_t *)cupsArrayFirst(creds), lcred = (http_credential_t *)cupsArrayFirst(lcreds); 652 cred && lcred; 653 i ++, cred = (http_credential_t *)cupsArrayNext(creds), lcred = (http_credential_t *)cupsArrayNext(lcreds)) 654 { 655 if (cred->datalen != lcred->datalen) 656 printf(" Credential #%d: Different lengths (saved=%d, current=%d)\n", i, (int)cred->datalen, (int)lcred->datalen); 657 else if (memcmp(cred->data, lcred->data, cred->datalen)) 658 printf(" Credential #%d: Different data\n", i); 659 else 660 printf(" Credential #%d: Matches\n", i); 661 } 662 } 663 664 if (trust != HTTP_TRUST_OK) 665 { 666 printf("SaveCredentials: %d\n", httpSaveCredentials(NULL, creds, hostname)); 667 trust = httpCredentialsGetTrust(creds, hostname); 668 printf("New Trust: %s\n", trusts[trust]); 669 } 670 671 httpFreeCredentials(creds); 672 } 673 else 674 puts("No credentials!"); 675 } 676 677 printf("Checking file \"%s\"...\n", resource); 678 679 do 680 { 681 if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) 682 { 683 httpClearFields(http); 684 if (httpReconnect2(http, 30000, NULL)) 685 { 686 status = HTTP_STATUS_ERROR; 687 break; 688 } 689 } 690 691 httpClearFields(http); 692 httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); 693 httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); 694 if (httpHead(http, resource)) 695 { 696 if (httpReconnect2(http, 30000, NULL)) 697 { 698 status = HTTP_STATUS_ERROR; 699 break; 700 } 701 else 702 { 703 status = HTTP_STATUS_UNAUTHORIZED; 704 continue; 705 } 706 } 707 708 while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); 709 710 if (status == HTTP_STATUS_UNAUTHORIZED) 711 { 712 /* 713 * Flush any error message... 714 */ 715 716 httpFlush(http); 717 718 /* 719 * See if we can do authentication... 720 */ 721 722 if (cupsDoAuthentication(http, "GET", resource)) 723 { 724 status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; 725 break; 726 } 727 728 if (httpReconnect2(http, 30000, NULL)) 729 { 730 status = HTTP_STATUS_ERROR; 731 break; 732 } 733 734 continue; 735 } 736#ifdef HAVE_SSL 737 else if (status == HTTP_STATUS_UPGRADE_REQUIRED) 738 { 739 /* Flush any error message... */ 740 httpFlush(http); 741 742 /* Reconnect... */ 743 if (httpReconnect2(http, 30000, NULL)) 744 { 745 status = HTTP_STATUS_ERROR; 746 break; 747 } 748 749 /* Upgrade with encryption... */ 750 httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); 751 752 /* Try again, this time with encryption enabled... */ 753 continue; 754 } 755#endif /* HAVE_SSL */ 756 } 757 while (status == HTTP_STATUS_UNAUTHORIZED || 758 status == HTTP_STATUS_UPGRADE_REQUIRED); 759 760 if (status == HTTP_STATUS_OK) 761 puts("HEAD OK:"); 762 else 763 printf("HEAD failed with status %d...\n", status); 764 765 encoding = httpGetContentEncoding(http); 766 767 printf("Requesting file \"%s\" (Accept-Encoding: %s)...\n", resource, 768 encoding ? encoding : "identity"); 769 770 do 771 { 772 if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) 773 { 774 httpClearFields(http); 775 if (httpReconnect2(http, 30000, NULL)) 776 { 777 status = HTTP_STATUS_ERROR; 778 break; 779 } 780 } 781 782 httpClearFields(http); 783 httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); 784 httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); 785 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, encoding); 786 787 if (httpGet(http, resource)) 788 { 789 if (httpReconnect2(http, 30000, NULL)) 790 { 791 status = HTTP_STATUS_ERROR; 792 break; 793 } 794 else 795 { 796 status = HTTP_STATUS_UNAUTHORIZED; 797 continue; 798 } 799 } 800 801 while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); 802 803 if (status == HTTP_STATUS_UNAUTHORIZED) 804 { 805 /* 806 * Flush any error message... 807 */ 808 809 httpFlush(http); 810 811 /* 812 * See if we can do authentication... 813 */ 814 815 if (cupsDoAuthentication(http, "GET", resource)) 816 { 817 status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; 818 break; 819 } 820 821 if (httpReconnect2(http, 30000, NULL)) 822 { 823 status = HTTP_STATUS_ERROR; 824 break; 825 } 826 827 continue; 828 } 829#ifdef HAVE_SSL 830 else if (status == HTTP_STATUS_UPGRADE_REQUIRED) 831 { 832 /* Flush any error message... */ 833 httpFlush(http); 834 835 /* Reconnect... */ 836 if (httpReconnect2(http, 30000, NULL)) 837 { 838 status = HTTP_STATUS_ERROR; 839 break; 840 } 841 842 /* Upgrade with encryption... */ 843 httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); 844 845 /* Try again, this time with encryption enabled... */ 846 continue; 847 } 848#endif /* HAVE_SSL */ 849 } 850 while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); 851 852 if (status == HTTP_STATUS_OK) 853 puts("GET OK:"); 854 else 855 printf("GET failed with status %d...\n", status); 856 857 start = time(NULL); 858 length = httpGetLength2(http); 859 total = 0; 860 861 while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0) 862 { 863 total += bytes; 864 fwrite(buffer, (size_t)bytes, 1, out); 865 if (out != stdout) 866 { 867 current = time(NULL); 868 if (current == start) 869 current ++; 870 871 printf("\r" CUPS_LLFMT "/" CUPS_LLFMT " bytes (" 872 CUPS_LLFMT " bytes/sec) ", CUPS_LLCAST total, 873 CUPS_LLCAST length, CUPS_LLCAST (total / (current - start))); 874 fflush(stdout); 875 } 876 } 877 } 878 879 if (out != stdout) 880 putchar('\n'); 881 882 puts("Closing connection to server..."); 883 httpClose(http); 884 885 if (out != stdout) 886 fclose(out); 887 888 return (0); 889} 890 891 892/* 893 * End of "$Id: testhttp.c 12078 2014-07-31 11:45:57Z msweet $". 894 */ 895