summaryrefslogtreecommitdiff
path: root/cups
diff options
context:
space:
mode:
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2013-05-24 21:21:04 +0000
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>2013-05-24 21:21:04 +0000
commit86c809d99ca685fa08dac9f753c91521789dbd0d (patch)
treeb46903a0f3dd8d103757e16e5fd3577eac282c96 /cups
parent4fcfa0cf96808fcf7893cb89350105fc821eaf5d (diff)
Added support for RFC 6874's IPv6 link local address format in URIs
(<rdar://problem/13979453>) git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@10990 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'cups')
-rw-r--r--cups/http-support.c50
-rw-r--r--cups/http.h3
-rw-r--r--cups/testhttp.c119
3 files changed, 127 insertions, 45 deletions
diff --git a/cups/http-support.c b/cups/http-support.c
index 4c7cbc9a4..f3fe8c24a 100644
--- a/cups/http-support.c
+++ b/cups/http-support.c
@@ -272,7 +272,7 @@ httpAssembleURI(
* We have a raw IPv6 address...
*/
- if (strchr(host, '%'))
+ if (strchr(host, '%') && !(encoding & HTTP_URI_CODING_RFC6874))
{
/*
* We have a link-local address, add "[v1." prefix...
@@ -307,8 +307,23 @@ httpAssembleURI(
while (ptr < end && *host)
{
if (*host == '%')
- {
- *ptr++ = '+'; /* Convert zone separator */
+ {
+ /*
+ * Convert/encode zone separator
+ */
+
+ if (encoding & HTTP_URI_CODING_RFC6874)
+ {
+ if (ptr >= (end - 2))
+ goto assemble_overflow;
+
+ *ptr++ = '%';
+ *ptr++ = '2';
+ *ptr++ = '5';
+ }
+ else
+ *ptr++ = '+';
+
host ++;
}
else
@@ -1097,8 +1112,25 @@ httpSeparateURI(
*/
uri ++;
- if (!strncmp(uri, "v1.", 3))
- uri += 3; /* Skip IPvN leader... */
+ if (*uri == 'v')
+ {
+ /*
+ * Skip IPvFuture ("vXXXX.") prefix...
+ */
+
+ uri ++;
+
+ while (isxdigit(*uri & 255))
+ uri ++;
+
+ if (*uri != '.')
+ {
+ *host = '\0';
+ return (HTTP_URI_STATUS_BAD_HOSTNAME);
+ }
+
+ uri ++;
+ }
uri = http_copy_decode(host, uri, hostlen, "]",
decoding & HTTP_URI_CODING_HOSTNAME);
@@ -1131,6 +1163,14 @@ httpSeparateURI(
*ptr = '%';
break;
}
+ else if (*ptr == '%')
+ {
+ /*
+ * Stop at zone separator (RFC 6874)
+ */
+
+ break;
+ }
else if (*ptr != ':' && *ptr != '.' && !isxdigit(*ptr & 255))
{
*host = '\0';
diff --git a/cups/http.h b/cups/http.h
index ea188d292..555f52b38 100644
--- a/cups/http.h
+++ b/cups/http.h
@@ -383,7 +383,8 @@ typedef enum http_uri_coding_e /**** URI en/decode flags ****/
HTTP_URI_CODING_RESOURCE = 4, /* En/decode the resource portion */
HTTP_URI_CODING_MOST = 7, /* En/decode all but the query */
HTTP_URI_CODING_QUERY = 8, /* En/decode the query portion */
- HTTP_URI_CODING_ALL = 15 /* En/decode everything */
+ HTTP_URI_CODING_ALL = 15, /* En/decode everything */
+ HTTP_URI_CODING_RFC6874 = 16 /* Use RFC 6874 address format */
} http_uri_coding_t;
typedef enum http_version_e /**** HTTP version numbers ****/
diff --git a/cups/testhttp.c b/cups/testhttp.c
index e6823abd1..5d1dc0adf 100644
--- a/cups/testhttp.c
+++ b/cups/testhttp.c
@@ -40,7 +40,8 @@ typedef struct uri_test_s /**** URI test cases ****/
*hostname, /* Hostname string */
*resource; /* Resource string */
int port, /* Port number */
- assemble_port; /* Port number for httpAssembleURI() */
+ assemble_port, /* Port number for httpAssembleURI() */
+ assemble_coding;/* Coding for httpAssembleURI() */
} uri_test_t;
@@ -52,97 +53,137 @@ static uri_test_t uri_tests[] = /* URI test data */
{
/* 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, "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_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 },
/* 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", "", "", "", 80, 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", "", "server", "", 80, 0,
+ HTTP_URI_CODING_MOST }
};
static const char * const base64_tests[][2] =
{
@@ -412,7 +453,7 @@ main(int argc, /* I - Number of command-line arguments */
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,