]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Added support for RFC 6874's IPv6 link local address format in URIs
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Fri, 24 May 2013 21:21:04 +0000 (21:21 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Fri, 24 May 2013 21:21:04 +0000 (21:21 +0000)
(<rdar://problem/13979453>)

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@10990 a1ca3aef-8c08-0410-bb20-df032aa958be

CHANGES-1.6.txt
cups/http-support.c
cups/http.h
cups/testhttp.c

index 22d871068673f31b1547ec3a6b7a9a26eb4e7609..cf564acb1356a6853ce442b13fa96d815df1ce90 100644 (file)
@@ -5,6 +5,8 @@ CHANGES IN CUPS V1.6.3
 
        - The configure script now prefers Clang over GCC.
        - Fixed a compile problem on AIX (STR #4307)
+       - Added support for RFC 6874's IPv6 link local address format in URIs
+         (<rdar://problem/13979453>)
        - The USB backend could crash on libusb-based systems if USB was
          disabled in the BIOS (<rdar://problem/13875729>)
        - Fixed a rounding error in the PWG media size mapping code
index 4c7cbc9a4718a726b56cd26b52d15375f18e5c3d..f3fe8c24a1e3abf54a1671700e0604ebbe4a62ea 100644 (file)
@@ -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';
index ea188d2929736976e047acde5c80983ba63a8567..555f52b3867afba8cac11f417591cc703f27676e 100644 (file)
@@ -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 ****/
index e6823abd1265b73fc2fc6e287a1b3fc1ba86ca7c..5d1dc0adf4ea4d089425a31709f8ffe98b315e72 100644 (file)
@@ -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,