diff options
author | Philip P. Moltmann <moltmann@google.com> | 2016-12-15 12:16:46 -0800 |
---|---|---|
committer | Philip P. Moltmann <moltmann@google.com> | 2016-12-15 12:29:54 -0800 |
commit | 25aee82d491492e1fa3b005e5880e684dc081ffb (patch) | |
tree | 0ae3dad7b0a56ce344c23dfc5623c064ac93c725 /cups/testhttp.c | |
parent | 4a531e85e511cfa7a4aadada1ecbe505f71305cc (diff) | |
download | libcups-25aee82d491492e1fa3b005e5880e684dc081ffb.tar.gz |
Cups v2.2.0
Test: none
Change-Id: Ic1716fa930940f63b4679144b1459263a35476ef
Diffstat (limited to 'cups/testhttp.c')
-rw-r--r-- | cups/testhttp.c | 886 |
1 files changed, 886 insertions, 0 deletions
diff --git a/cups/testhttp.c b/cups/testhttp.c new file mode 100644 index 00000000..20c6625a --- /dev/null +++ b/cups/testhttp.c @@ -0,0 +1,886 @@ +/* + * HTTP test program for CUPS. + * + * Copyright 2007-2014 by Apple Inc. + * Copyright 1997-2006 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Apple Inc. and are protected by Federal copyright + * law. Distribution and use rights are outlined in the file "LICENSE.txt" + * which should have been included with this file. If this file is + * file is missing or damaged, see the license at "http://www.cups.org/". + * + * This file is subject to the Apple OS-Developed Software exception. + */ + +/* + * Include necessary headers... + */ + +#include "cups-private.h" + + +/* + * Types and structures... + */ + +typedef struct uri_test_s /**** URI test cases ****/ +{ + http_uri_status_t result; /* Expected return value */ + const char *uri, /* URI */ + *scheme, /* Scheme string */ + *username, /* Username:password string */ + *hostname, /* Hostname string */ + *resource; /* Resource string */ + int port, /* Port number */ + assemble_port; /* Port number for httpAssembleURI() */ + http_uri_coding_t assemble_coding;/* Coding for httpAssembleURI() */ +} uri_test_t; + + +/* + * Local globals... + */ + +static uri_test_t uri_tests[] = /* URI test data */ + { + /* Start with valid URIs */ + { HTTP_URI_STATUS_OK, "file:/filename", + "file", "", "", "/filename", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "file:/filename%20with%20spaces", + "file", "", "", "/filename with spaces", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "file:///filename", + "file", "", "", "/filename", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "file:///filename%20with%20spaces", + "file", "", "", "/filename with spaces", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "file://localhost/filename", + "file", "", "localhost", "/filename", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "file://localhost/filename%20with%20spaces", + "file", "", "localhost", "/filename with spaces", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "http://server/", + "http", "", "server", "/", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "http://username@server/", + "http", "username", "server", "/", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "http://username:passwor%64@server/", + "http", "username:password", "server", "/", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "http://username:passwor%64@server:8080/", + "http", "username:password", "server", "/", 8080, 8080, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "http://username:passwor%64@server:8080/directory/filename", + "http", "username:password", "server", "/directory/filename", 8080, 8080, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "http://[2000::10:100]:631/ipp", + "http", "", "2000::10:100", "/ipp", 631, 631, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "https://username:passwor%64@server/directory/filename", + "https", "username:password", "server", "/directory/filename", 443, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "ipp://username:passwor%64@[::1]/ipp", + "ipp", "username:password", "::1", "/ipp", 631, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "lpd://server/queue?reserve=yes", + "lpd", "", "server", "/queue?reserve=yes", 515, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "mailto:user@domain.com", + "mailto", "", "", "user@domain.com", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "socket://server/", + "socket", "", "server", "/", 9100, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "socket://192.168.1.1:9101/", + "socket", "", "192.168.1.1", "/", 9101, 9101, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "tel:8005551212", + "tel", "", "", "8005551212", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "ipp://username:password@[v1.fe80::200:1234:5678:9abc+eth0]:999/ipp", + "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "ipp://username:password@[fe80::200:1234:5678:9abc%25eth0]:999/ipp", + "ipp", "username:password", "fe80::200:1234:5678:9abc%eth0", "/ipp", 999, 999, + (http_uri_coding_t)(HTTP_URI_CODING_MOST | HTTP_URI_CODING_RFC6874) }, + { HTTP_URI_STATUS_OK, "http://server/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", + "http", "", "server", "/admin?DEVICE_URI=usb://HP/Photosmart%25202600%2520series?serial=MY53OK70V10400", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "lpd://Acme%20Laser%20(01%3A23%3A45).local._tcp._printer/", + "lpd", "", "Acme Laser (01:23:45).local._tcp._printer", "/", 515, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "ipp://HP%20Officejet%204500%20G510n-z%20%40%20Will's%20MacBook%20Pro%2015%22._ipp._tcp.local./", + "ipp", "", "HP Officejet 4500 G510n-z @ Will's MacBook Pro 15\"._ipp._tcp.local.", "/", 631, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_OK, "ipp://%22%23%2F%3A%3C%3E%3F%40%5B%5C%5D%5E%60%7B%7C%7D/", + "ipp", "", "\"#/:<>?@[\\]^`{|}", "/", 631, 0, + HTTP_URI_CODING_MOST }, + + /* Missing scheme */ + { HTTP_URI_STATUS_MISSING_SCHEME, "/path/to/file/index.html", + "file", "", "", "/path/to/file/index.html", 0, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_MISSING_SCHEME, "//server/ipp", + "ipp", "", "server", "/ipp", 631, 0, + HTTP_URI_CODING_MOST }, + + /* Unknown scheme */ + { HTTP_URI_STATUS_UNKNOWN_SCHEME, "vendor://server/resource", + "vendor", "", "server", "/resource", 0, 0, + HTTP_URI_CODING_MOST }, + + /* Missing resource */ + { HTTP_URI_STATUS_MISSING_RESOURCE, "socket://[::192.168.2.1]", + "socket", "", "::192.168.2.1", "/", 9100, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_MISSING_RESOURCE, "socket://192.168.1.1:9101", + "socket", "", "192.168.1.1", "/", 9101, 0, + HTTP_URI_CODING_MOST }, + + /* Bad URI */ + { HTTP_URI_STATUS_BAD_URI, "", + "", "", "", "", 0, 0, + HTTP_URI_CODING_MOST }, + + /* Bad scheme */ + { HTTP_URI_STATUS_BAD_SCHEME, "bad_scheme://server/resource", + "", "", "", "", 0, 0, + HTTP_URI_CODING_MOST }, + + /* Bad username */ + { HTTP_URI_STATUS_BAD_USERNAME, "http://username:passwor%6@server/resource", + "http", "", "", "", 80, 0, + HTTP_URI_CODING_MOST }, + + /* Bad hostname */ + { HTTP_URI_STATUS_BAD_HOSTNAME, "http://[/::1]/index.html", + "http", "", "", "", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_BAD_HOSTNAME, "http://[", + "http", "", "", "", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_BAD_HOSTNAME, "http://serve%7/index.html", + "http", "", "", "", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_BAD_HOSTNAME, "http://server with spaces/index.html", + "http", "", "", "", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_BAD_HOSTNAME, "ipp://\"#/:<>?@[\\]^`{|}/", + "ipp", "", "", "", 631, 0, + HTTP_URI_CODING_MOST }, + + /* Bad port number */ + { HTTP_URI_STATUS_BAD_PORT, "http://127.0.0.1:9999a/index.html", + "http", "", "127.0.0.1", "", 0, 0, + HTTP_URI_CODING_MOST }, + + /* Bad resource */ + { HTTP_URI_STATUS_BAD_RESOURCE, "http://server/index.html%", + "http", "", "server", "", 80, 0, + HTTP_URI_CODING_MOST }, + { HTTP_URI_STATUS_BAD_RESOURCE, "http://server/index with spaces.html", + "http", "", "server", "", 80, 0, + HTTP_URI_CODING_MOST } + }; +static const char * const base64_tests[][2] = + { + { "A", "QQ==" }, + /* 010000 01 */ + { "AB", "QUI=" }, + /* 010000 010100 0010 */ + { "ABC", "QUJD" }, + /* 010000 010100 001001 000011 */ + { "ABCD", "QUJDRA==" }, + /* 010000 010100 001001 000011 010001 00 */ + { "ABCDE", "QUJDREU=" }, + /* 010000 010100 001001 000011 010001 000100 0101 */ + { "ABCDEF", "QUJDREVG" }, + /* 010000 010100 001001 000011 010001 000100 010101 000110 */ + }; + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, j, k; /* Looping vars */ + http_t *http; /* HTTP connection */ + http_encryption_t encryption; /* Encryption type */ + http_status_t status; /* Status of GET command */ + int failures; /* Number of test failures */ + char buffer[8192]; /* Input buffer */ + long bytes; /* Number of bytes read */ + FILE *out; /* Output file */ + char encode[256], /* Base64-encoded string */ + decode[256]; /* Base64-decoded string */ + int decodelen; /* Length of decoded string */ + char scheme[HTTP_MAX_URI], /* Scheme from URI */ + hostname[HTTP_MAX_URI], /* Hostname from URI */ + username[HTTP_MAX_URI], /* Username:password from URI */ + resource[HTTP_MAX_URI]; /* Resource from URI */ + int port; /* Port number from URI */ + http_uri_status_t uri_status; /* Status of URI separation */ + http_addrlist_t *addrlist, /* Address list */ + *addr; /* Current address */ + off_t length, total; /* Length and total bytes */ + time_t start, current; /* Start and end time */ + const char *encoding; /* Negotiated Content-Encoding */ + static const char * const uri_status_strings[] = + { + "HTTP_URI_STATUS_OVERFLOW", + "HTTP_URI_STATUS_BAD_ARGUMENTS", + "HTTP_URI_STATUS_BAD_RESOURCE", + "HTTP_URI_STATUS_BAD_PORT", + "HTTP_URI_STATUS_BAD_HOSTNAME", + "HTTP_URI_STATUS_BAD_USERNAME", + "HTTP_URI_STATUS_BAD_SCHEME", + "HTTP_URI_STATUS_BAD_URI", + "HTTP_URI_STATUS_OK", + "HTTP_URI_STATUS_MISSING_SCHEME", + "HTTP_URI_STATUS_UNKNOWN_SCHEME", + "HTTP_URI_STATUS_MISSING_RESOURCE" + }; + + + /* + * Do API tests if we don't have a URL on the command-line... + */ + + if (argc == 1) + { + failures = 0; + + /* + * httpGetDateString()/httpGetDateTime() + */ + + fputs("httpGetDateString()/httpGetDateTime(): ", stdout); + + start = time(NULL); + strlcpy(buffer, httpGetDateString(start), sizeof(buffer)); + current = httpGetDateTime(buffer); + + i = (int)(current - start); + if (i < 0) + i = -i; + + if (!i) + puts("PASS"); + else + { + failures ++; + puts("FAIL"); + printf(" Difference is %d seconds, %02d:%02d:%02d...\n", i, i / 3600, + (i / 60) % 60, i % 60); + printf(" httpGetDateString(%d) returned \"%s\"\n", (int)start, buffer); + printf(" httpGetDateTime(\"%s\") returned %d\n", buffer, (int)current); + printf(" httpGetDateString(%d) returned \"%s\"\n", (int)current, + httpGetDateString(current)); + } + + /* + * httpDecode64_2()/httpEncode64_2() + */ + + fputs("httpDecode64_2()/httpEncode64_2(): ", stdout); + + for (i = 0, j = 0; i < (int)(sizeof(base64_tests) / sizeof(base64_tests[0])); i ++) + { + httpEncode64_2(encode, sizeof(encode), base64_tests[i][0], + (int)strlen(base64_tests[i][0])); + decodelen = (int)sizeof(decode); + httpDecode64_2(decode, &decodelen, base64_tests[i][1]); + + if (strcmp(decode, base64_tests[i][0])) + { + failures ++; + + if (j) + { + puts("FAIL"); + j = 1; + } + + printf(" httpDecode64_2() returned \"%s\", expected \"%s\"...\n", + decode, base64_tests[i][0]); + } + + if (strcmp(encode, base64_tests[i][1])) + { + failures ++; + + if (j) + { + puts("FAIL"); + j = 1; + } + + printf(" httpEncode64_2() returned \"%s\", expected \"%s\"...\n", + encode, base64_tests[i][1]); + } + } + + if (!j) + puts("PASS"); + + /* + * httpGetHostname() + */ + + fputs("httpGetHostname(): ", stdout); + + if (httpGetHostname(NULL, hostname, sizeof(hostname))) + printf("PASS (%s)\n", hostname); + else + { + failures ++; + puts("FAIL"); + } + + /* + * httpAddrGetList() + */ + + printf("httpAddrGetList(%s): ", hostname); + + addrlist = httpAddrGetList(hostname, AF_UNSPEC, NULL); + if (addrlist) + { + for (i = 0, addr = addrlist; addr; i ++, addr = addr->next) + { + char numeric[1024]; /* Numeric IP address */ + + + httpAddrString(&(addr->addr), numeric, sizeof(numeric)); + if (!strcmp(numeric, "UNKNOWN")) + break; + } + + if (addr) + printf("FAIL (bad address for %s)\n", hostname); + else + printf("PASS (%d address(es) for %s)\n", i, hostname); + + httpAddrFreeList(addrlist); + } + else if (isdigit(hostname[0] & 255)) + { + puts("FAIL (ignored because hostname is numeric)"); + } + else + { + failures ++; + puts("FAIL"); + } + + /* + * Test httpSeparateURI()... + */ + + fputs("httpSeparateURI(): ", stdout); + for (i = 0, j = 0; i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); i ++) + { + uri_status = httpSeparateURI(HTTP_URI_CODING_MOST, + uri_tests[i].uri, scheme, sizeof(scheme), + username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + if (uri_status != uri_tests[i].result || + strcmp(scheme, uri_tests[i].scheme) || + strcmp(username, uri_tests[i].username) || + strcmp(hostname, uri_tests[i].hostname) || + port != uri_tests[i].port || + strcmp(resource, uri_tests[i].resource)) + { + failures ++; + + if (!j) + { + puts("FAIL"); + j = 1; + } + + printf(" \"%s\":\n", uri_tests[i].uri); + + if (uri_status != uri_tests[i].result) + printf(" Returned %s instead of %s\n", + uri_status_strings[uri_status + 8], + uri_status_strings[uri_tests[i].result + 8]); + + if (strcmp(scheme, uri_tests[i].scheme)) + printf(" Scheme \"%s\" instead of \"%s\"\n", + scheme, uri_tests[i].scheme); + + if (strcmp(username, uri_tests[i].username)) + printf(" Username \"%s\" instead of \"%s\"\n", + username, uri_tests[i].username); + + if (strcmp(hostname, uri_tests[i].hostname)) + printf(" Hostname \"%s\" instead of \"%s\"\n", + hostname, uri_tests[i].hostname); + + if (port != uri_tests[i].port) + printf(" Port %d instead of %d\n", + port, uri_tests[i].port); + + if (strcmp(resource, uri_tests[i].resource)) + printf(" Resource \"%s\" instead of \"%s\"\n", + resource, uri_tests[i].resource); + } + } + + if (!j) + printf("PASS (%d URIs tested)\n", + (int)(sizeof(uri_tests) / sizeof(uri_tests[0]))); + + /* + * Test httpAssembleURI()... + */ + + fputs("httpAssembleURI(): ", stdout); + for (i = 0, j = 0, k = 0; + i < (int)(sizeof(uri_tests) / sizeof(uri_tests[0])); + i ++) + if (uri_tests[i].result == HTTP_URI_STATUS_OK && + !strstr(uri_tests[i].uri, "%64") && + strstr(uri_tests[i].uri, "//")) + { + k ++; + uri_status = httpAssembleURI(uri_tests[i].assemble_coding, + buffer, sizeof(buffer), + uri_tests[i].scheme, + uri_tests[i].username, + uri_tests[i].hostname, + uri_tests[i].assemble_port, + uri_tests[i].resource); + + if (uri_status != HTTP_URI_STATUS_OK) + { + failures ++; + + if (!j) + { + puts("FAIL"); + j = 1; + } + + printf(" \"%s\": %s\n", uri_tests[i].uri, + uri_status_strings[uri_status + 8]); + } + else if (strcmp(buffer, uri_tests[i].uri)) + { + failures ++; + + if (!j) + { + puts("FAIL"); + j = 1; + } + + printf(" \"%s\": assembled = \"%s\"\n", uri_tests[i].uri, + buffer); + } + } + + if (!j) + printf("PASS (%d URIs tested)\n", k); + + /* + * httpAssembleUUID + */ + + fputs("httpAssembleUUID: ", stdout); + httpAssembleUUID("hostname.example.com", 631, "printer", 12345, buffer, + sizeof(buffer)); + if (strncmp(buffer, "urn:uuid:", 9)) + { + printf("FAIL (%s)\n", buffer); + failures ++; + } + else + printf("PASS (%s)\n", buffer); + + /* + * Show a summary and return... + */ + + if (failures) + printf("\n%d TESTS FAILED!\n", failures); + else + puts("\nALL TESTS PASSED!"); + + return (failures); + } + else if (strstr(argv[1], "._tcp")) + { + /* + * Test resolving an mDNS name. + */ + + char resolved[1024]; /* Resolved URI */ + + + printf("_httpResolveURI(%s, _HTTP_RESOLVE_DEFAULT): ", argv[1]); + fflush(stdout); + + if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), + _HTTP_RESOLVE_DEFAULT, NULL, NULL)) + { + puts("FAIL"); + return (1); + } + else + printf("PASS (%s)\n", resolved); + + printf("_httpResolveURI(%s, _HTTP_RESOLVE_FQDN): ", argv[1]); + fflush(stdout); + + if (!_httpResolveURI(argv[1], resolved, sizeof(resolved), + _HTTP_RESOLVE_FQDN, NULL, NULL)) + { + puts("FAIL"); + return (1); + } + else if (strstr(resolved, ".local:")) + { + printf("FAIL (%s)\n", resolved); + return (1); + } + else + { + printf("PASS (%s)\n", resolved); + return (0); + } + } + else if (!strcmp(argv[1], "-u") && argc == 3) + { + /* + * Test URI separation... + */ + + uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, argv[2], scheme, + sizeof(scheme), username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + printf("uri_status = %s\n", uri_status_strings[uri_status + 8]); + printf("scheme = \"%s\"\n", scheme); + printf("username = \"%s\"\n", username); + printf("hostname = \"%s\"\n", hostname); + printf("port = %d\n", port); + printf("resource = \"%s\"\n", resource); + + return (0); + } + + /* + * Test HTTP GET requests... + */ + + http = NULL; + out = stdout; + + for (i = 1; i < argc; i ++) + { + if (!strcmp(argv[i], "-o")) + { + i ++; + if (i >= argc) + break; + + out = fopen(argv[i], "wb"); + continue; + } + + httpSeparateURI(HTTP_URI_CODING_MOST, argv[i], scheme, sizeof(scheme), + username, sizeof(username), + hostname, sizeof(hostname), &port, + resource, sizeof(resource)); + + if (!_cups_strcasecmp(scheme, "https") || !_cups_strcasecmp(scheme, "ipps") || + port == 443) + encryption = HTTP_ENCRYPTION_ALWAYS; + else + encryption = HTTP_ENCRYPTION_IF_REQUESTED; + + http = httpConnect2(hostname, port, NULL, AF_UNSPEC, encryption, 1, 30000, NULL); + if (http == NULL) + { + perror(hostname); + continue; + } + + if (httpIsEncrypted(http)) + { + cups_array_t *creds; + char info[1024]; + static const char *trusts[] = { "OK", "Invalid", "Changed", "Expired", "Renewed", "Unknown" }; + if (!httpCopyCredentials(http, &creds)) + { + cups_array_t *lcreds; + http_trust_t trust = httpCredentialsGetTrust(creds, hostname); + + httpCredentialsString(creds, info, sizeof(info)); + + printf("Count: %d\n", cupsArrayCount(creds)); + printf("Trust: %s\n", trusts[trust]); + printf("Expiration: %s\n", httpGetDateString(httpCredentialsGetExpiration(creds))); + printf("IsValidName: %d\n", httpCredentialsAreValidForName(creds, hostname)); + printf("String: \"%s\"\n", info); + + printf("LoadCredentials: %d\n", httpLoadCredentials(NULL, &lcreds, hostname)); + httpCredentialsString(lcreds, info, sizeof(info)); + printf(" Count: %d\n", cupsArrayCount(lcreds)); + printf(" String: \"%s\"\n", info); + + if (lcreds && cupsArrayCount(creds) == cupsArrayCount(lcreds)) + { + http_credential_t *cred, *lcred; + + for (i = 1, cred = (http_credential_t *)cupsArrayFirst(creds), lcred = (http_credential_t *)cupsArrayFirst(lcreds); + cred && lcred; + i ++, cred = (http_credential_t *)cupsArrayNext(creds), lcred = (http_credential_t *)cupsArrayNext(lcreds)) + { + if (cred->datalen != lcred->datalen) + printf(" Credential #%d: Different lengths (saved=%d, current=%d)\n", i, (int)cred->datalen, (int)lcred->datalen); + else if (memcmp(cred->data, lcred->data, cred->datalen)) + printf(" Credential #%d: Different data\n", i); + else + printf(" Credential #%d: Matches\n", i); + } + } + + if (trust != HTTP_TRUST_OK) + { + printf("SaveCredentials: %d\n", httpSaveCredentials(NULL, creds, hostname)); + trust = httpCredentialsGetTrust(creds, hostname); + printf("New Trust: %s\n", trusts[trust]); + } + + httpFreeCredentials(creds); + } + else + puts("No credentials!"); + } + + printf("Checking file \"%s\"...\n", resource); + + do + { + if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) + { + httpClearFields(http); + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + } + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); + httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); + if (httpHead(http, resource)) + { + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + else + { + status = HTTP_STATUS_UNAUTHORIZED; + continue; + } + } + + while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); + + if (status == HTTP_STATUS_UNAUTHORIZED) + { + /* + * Flush any error message... + */ + + httpFlush(http); + + /* + * See if we can do authentication... + */ + + if (cupsDoAuthentication(http, "GET", resource)) + { + status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; + break; + } + + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + + continue; + } +#ifdef HAVE_SSL + else if (status == HTTP_STATUS_UPGRADE_REQUIRED) + { + /* Flush any error message... */ + httpFlush(http); + + /* Reconnect... */ + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + + /* Upgrade with encryption... */ + httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); + + /* Try again, this time with encryption enabled... */ + continue; + } +#endif /* HAVE_SSL */ + } + while (status == HTTP_STATUS_UNAUTHORIZED || + status == HTTP_STATUS_UPGRADE_REQUIRED); + + if (status == HTTP_STATUS_OK) + puts("HEAD OK:"); + else + printf("HEAD failed with status %d...\n", status); + + encoding = httpGetContentEncoding(http); + + printf("Requesting file \"%s\" (Accept-Encoding: %s)...\n", resource, + encoding ? encoding : "identity"); + + do + { + if (!_cups_strcasecmp(httpGetField(http, HTTP_FIELD_CONNECTION), "close")) + { + httpClearFields(http); + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + } + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, httpGetAuthString(http)); + httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); + httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, encoding); + + if (httpGet(http, resource)) + { + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + else + { + status = HTTP_STATUS_UNAUTHORIZED; + continue; + } + } + + while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE); + + if (status == HTTP_STATUS_UNAUTHORIZED) + { + /* + * Flush any error message... + */ + + httpFlush(http); + + /* + * See if we can do authentication... + */ + + if (cupsDoAuthentication(http, "GET", resource)) + { + status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; + break; + } + + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + + continue; + } +#ifdef HAVE_SSL + else if (status == HTTP_STATUS_UPGRADE_REQUIRED) + { + /* Flush any error message... */ + httpFlush(http); + + /* Reconnect... */ + if (httpReconnect2(http, 30000, NULL)) + { + status = HTTP_STATUS_ERROR; + break; + } + + /* Upgrade with encryption... */ + httpEncryption(http, HTTP_ENCRYPTION_REQUIRED); + + /* Try again, this time with encryption enabled... */ + continue; + } +#endif /* HAVE_SSL */ + } + while (status == HTTP_STATUS_UNAUTHORIZED || status == HTTP_STATUS_UPGRADE_REQUIRED); + + if (status == HTTP_STATUS_OK) + puts("GET OK:"); + else + printf("GET failed with status %d...\n", status); + + start = time(NULL); + length = httpGetLength2(http); + total = 0; + + while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0) + { + total += bytes; + fwrite(buffer, (size_t)bytes, 1, out); + if (out != stdout) + { + current = time(NULL); + if (current == start) + current ++; + + printf("\r" CUPS_LLFMT "/" CUPS_LLFMT " bytes (" + CUPS_LLFMT " bytes/sec) ", CUPS_LLCAST total, + CUPS_LLCAST length, CUPS_LLCAST (total / (current - start))); + fflush(stdout); + } + } + } + + if (out != stdout) + putchar('\n'); + + puts("Closing connection to server..."); + httpClose(http); + + if (out != stdout) + fclose(out); + + return (0); +} |