1/* 2 * "$Id: testhttp.c 11528 2014-01-14 20:24:03Z msweet $" 3 * 4 * HTTP test program for CUPS. 5 * 6 * Copyright 2007-2013 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 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_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, 617 NULL); 618 if (http == NULL) 619 { 620 perror(hostname); 621 continue; 622 } 623 printf("Checking file \"%s\"...\n", resource); 624 625 do 626 { 627 if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) 628 { 629 httpClearFields(http); 630 if (httpReconnect2(http, 30000, NULL)) 631 { 632 status = HTTP_STATUS_ERROR; 633 break; 634 } 635 } 636 637 httpClearFields(http); 638 httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); 639 httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); 640 if (httpHead(http, resource)) 641 { 642 if (httpReconnect2(http, 30000, NULL)) 643 { 644 status = HTTP_STATUS_ERROR; 645 break; 646 } 647 else 648 { 649 status = HTTP_STATUS_UNAUTHORIZED; 650 continue; 651 } 652 } 653 654 while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); 655 656 if (status == HTTP_STATUS_UNAUTHORIZED) 657 { 658 /* 659 * Flush any error message... 660 */ 661 662 httpFlush(http); 663 664 /* 665 * See if we can do authentication... 666 */ 667 668 if (cupsDoAuthentication(http, "GET", resource)) 669 { 670 status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; 671 break; 672 } 673 674 if (httpReconnect2(http, 30000, NULL)) 675 { 676 status = HTTP_STATUS_ERROR; 677 break; 678 } 679 680 continue; 681 } 682#ifdef HAVE_SSL 683 else if (status == HTTP_STATUS_UPGRADE_REQUIRED) 684 { 685 /* Flush any error message... */ 686 httpFlush(http); 687 688 /* Reconnect... */ 689 if (httpReconnect2(http, 30000, NULL)) 690 { 691 status = HTTP_STATUS_ERROR; 692 break; 693 } 694 695 /* Upgrade with encryption... */ 696 httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); 697 698 /* Try again, this time with encryption enabled... */ 699 continue; 700 } 701#endif /* HAVE_SSL */ 702 } 703 while (status == HTTP_STATUS_UNAUTHORIZED || 704 status == HTTP_STATUS_UPGRADE_REQUIRED); 705 706 if (status == HTTP_STATUS_OK) 707 puts("HEAD OK:"); 708 else 709 printf("HEAD failed with status %d...\n", status); 710 711 encoding = httpGetContentEncoding(http); 712 713 printf("Requesting file \"%s\" (Accept-Encoding: %s)...\n", resource, 714 encoding ? encoding : "identity"); 715 716 do 717 { 718 if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) 719 { 720 httpClearFields(http); 721 if (httpReconnect2(http, 30000, NULL)) 722 { 723 status = HTTP_STATUS_ERROR; 724 break; 725 } 726 } 727 728 httpClearFields(http); 729 httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); 730 httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); 731 httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, encoding); 732 733 if (httpGet(http, resource)) 734 { 735 if (httpReconnect2(http, 30000, NULL)) 736 { 737 status = HTTP_STATUS_ERROR; 738 break; 739 } 740 else 741 { 742 status = HTTP_STATUS_UNAUTHORIZED; 743 continue; 744 } 745 } 746 747 while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); 748 749 if (status == HTTP_STATUS_UNAUTHORIZED) 750 { 751 /* 752 * Flush any error message... 753 */ 754 755 httpFlush(http); 756 757 /* 758 * See if we can do authentication... 759 */ 760 761 if (cupsDoAuthentication(http, "GET", resource)) 762 { 763 status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; 764 break; 765 } 766 767 if (httpReconnect2(http, 30000, NULL)) 768 { 769 status = HTTP_STATUS_ERROR; 770 break; 771 } 772 773 continue; 774 } 775#ifdef HAVE_SSL 776 else if (status == HTTP_STATUS_UPGRADE_REQUIRED) 777 { 778 /* Flush any error message... */ 779 httpFlush(http); 780 781 /* Reconnect... */ 782 if (httpReconnect2(http, 30000, NULL)) 783 { 784 status = HTTP_STATUS_ERROR; 785 break; 786 } 787 788 /* Upgrade with encryption... */ 789 httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); 790 791 /* Try again, this time with encryption enabled... */ 792 continue; 793 } 794#endif /* HAVE_SSL */ 795 } 796 while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); 797 798 if (status == HTTP_STATUS_OK) 799 puts("GET OK:"); 800 else 801 printf("GET failed with status %d...\n", status); 802 803 start = time(NULL); 804 length = httpGetLength2(http); 805 total = 0; 806 807 while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0) 808 { 809 total += bytes; 810 fwrite(buffer, bytes, 1, out); 811 if (out != stdout) 812 { 813 current = time(NULL); 814 if (current == start) current ++; 815 printf("\r" CUPS_LLFMT "/" CUPS_LLFMT " bytes (" 816 CUPS_LLFMT " bytes/sec) ", CUPS_LLCAST total, 817 CUPS_LLCAST length, CUPS_LLCAST (total / (current - start))); 818 fflush(stdout); 819 } 820 } 821 } 822 823 puts("Closing connection to server..."); 824 httpClose(http); 825 826 if (out != stdout) 827 fclose(out); 828 829 return (0); 830} 831 832 833/* 834 * End of "$Id: testhttp.c 11528 2014-01-14 20:24:03Z msweet $". 835 */ 836