/*
- * "$Id: testhttp.c 7742 2008-07-15 20:23:09Z mike $"
+ * HTTP test program for CUPS.
*
- * HTTP test program for CUPS.
+ * Copyright 2007-2014 by Apple Inc.
+ * Copyright 1997-2006 by Easy Software Products.
*
- * Copyright 2007-2013 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.
- *
- * Contents:
- *
- * main() - Main entry.
+ * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
*/
/*
* Include necessary headers...
*/
-#include "string-private.h"
-#include "http-private.h"
+#include "cups-private.h"
/*
*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;
{
/* Start with valid URIs */
{ HTTP_URI_STATUS_OK, "file:/filename",
- "file", "", "", "/filename", 0, 0 },
+ "file", "", "", "/filename", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "file:/filename%20with%20spaces",
- "file", "", "", "/filename with spaces", 0, 0 },
+ "file", "", "", "/filename with spaces", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "file:///filename",
- "file", "", "", "/filename", 0, 0 },
+ "file", "", "", "/filename", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "file:///filename%20with%20spaces",
- "file", "", "", "/filename with spaces", 0, 0 },
+ "file", "", "", "/filename with spaces", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "file://localhost/filename",
- "file", "", "localhost", "/filename", 0, 0 },
+ "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 },
+ "file", "", "localhost", "/filename with spaces", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "http://server/",
- "http", "", "server", "/", 80, 0 },
+ "http", "", "server", "/", 80, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "http://username@server/",
- "http", "username", "server", "/", 80, 0 },
+ "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", "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", "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", "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", "", "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 },
+ "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 },
+ "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 },
+ "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 },
+ "mailto", "", "", "user@domain.com", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_OK, "socket://server/",
- "socket", "", "server", "/", 9100, 0 },
+ "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 },
+ "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 },
+ "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", "", "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 },
+ "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 },
+ "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 },
+ "file", "", "", "/path/to/file/index.html", 0, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_MISSING_SCHEME, "//server/ipp",
- "ipp", "", "server", "/ipp", 631, 0 },
+ "ipp", "", "server", "/ipp", 631, 0,
+ HTTP_URI_CODING_MOST },
/* Unknown scheme */
{ HTTP_URI_STATUS_UNKNOWN_SCHEME, "vendor://server/resource",
- "vendor", "", "server", "/resource", 0, 0 },
+ "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 },
+ "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 },
+ "socket", "", "192.168.1.1", "/", 9101, 0,
+ HTTP_URI_CODING_MOST },
/* Bad URI */
{ HTTP_URI_STATUS_BAD_URI, "",
- "", "", "", "", 0, 0 },
+ "", "", "", "", 0, 0,
+ HTTP_URI_CODING_MOST },
/* Bad scheme */
{ HTTP_URI_STATUS_BAD_SCHEME, "bad_scheme://server/resource",
- "", "", "", "", 0, 0 },
+ "", "", "", "", 0, 0,
+ HTTP_URI_CODING_MOST },
/* Bad username */
{ HTTP_URI_STATUS_BAD_USERNAME, "http://username:passwor%6@server/resource",
- "http", "", "", "", 80, 0 },
+ "http", "", "", "", 80, 0,
+ HTTP_URI_CODING_MOST },
/* Bad hostname */
{ HTTP_URI_STATUS_BAD_HOSTNAME, "http://[/::1]/index.html",
- "http", "", "", "", 80, 0 },
+ "http", "", "", "", 80, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_BAD_HOSTNAME, "http://[",
- "http", "", "", "", 80, 0 },
+ "http", "", "", "", 80, 0,
+ HTTP_URI_CODING_MOST },
{ HTTP_URI_STATUS_BAD_HOSTNAME, "http://serve%7/index.html",
- "http", "", "", "", 80, 0 },
+ "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", "", "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", "", "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] =
{
strstr(uri_tests[i].uri, "//"))
{
k ++;
- uri_status = httpAssembleURI(HTTP_URI_CODING_MOST,
+ uri_status = httpAssembleURI(uri_tests[i].assemble_coding,
buffer, sizeof(buffer),
uri_tests[i].scheme,
uri_tests[i].username,
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...
*/
else
encryption = HTTP_ENCRYPTION_IF_REQUESTED;
- http = httpConnect2(hostname, port, NULL, AF_UNSPEC, encryption, 1, 30000,
- NULL);
+ 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);
- httpClearFields(http);
- httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
- httpHead(http, resource);
- while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
+
+ 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:");
printf("Requesting file \"%s\" (Accept-Encoding: %s)...\n", resource,
encoding ? encoding : "identity");
- httpClearFields(http);
- httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en");
- httpSetField(http, HTTP_FIELD_ACCEPT_ENCODING, encoding);
- httpGet(http, resource);
- while ((status = httpUpdate(http)) == HTTP_STATUS_CONTINUE);
+
+ 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:");
while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0)
{
total += bytes;
- fwrite(buffer, bytes, 1, out);
+ fwrite(buffer, (size_t)bytes, 1, out);
if (out != stdout)
{
current = time(NULL);
- if (current == start) current ++;
+ 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)));
}
}
+ if (out != stdout)
+ putchar('\n');
+
puts("Closing connection to server...");
httpClose(http);
return (0);
}
-
-
-/*
- * End of "$Id: testhttp.c 7742 2008-07-15 20:23:09Z mike $".
- */