You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2007/08/31 18:01:38 UTC

svn commit: r571503 - in /harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/net/URLConnection.java test/api/common/tests/api/java/net/URLConnectionTest.java

Author: tellison
Date: Fri Aug 31 09:01:38 2007
New Revision: 571503

URL: http://svn.apache.org/viewvc?rev=571503&view=rev
Log:
Enhancements to do a better guess at the content type of a stream.

Modified:
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLConnection.java
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/tests/api/java/net/URLConnectionTest.java

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLConnection.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLConnection.java?rev=571503&r1=571502&r2=571503&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLConnection.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/URLConnection.java Fri Aug 31 09:01:38 2007
@@ -722,26 +722,83 @@
      * @throws IOException
      *             If an IO error occurs
      */
+    @SuppressWarnings("nls")
     public static String guessContentTypeFromStream(InputStream is)
             throws IOException {
+
         if (!is.markSupported()) {
             return null;
         }
-        is.mark(4);
-        char[] chars = new char[4];
-        for (int i = 0; i < chars.length; i++) {
-            chars[i] = (char) is.read();
-        }
+        // Look ahead up to 64 bytes for the longest encoded header
+        is.mark(64);
+        byte[] bytes = new byte[64];
+        int length = is.read(bytes);
         is.reset();
-        if ((chars[0] == 'P') && (chars[1] == 'K')) {
-            return "application/zip"; //$NON-NLS-1$
+
+        // Check for Unicode BOM encoding indicators
+        String encoding = "ASCII";
+        int start = 0;
+        if (length > 1) {
+            if ((bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)) {
+                encoding = "UTF-16LE";
+                start = 2;
+                length -= length & 1;
+            }
+            if ((bytes[0] == (byte) 0xFE) && (bytes[1] == (byte) 0xFF)) {
+                encoding = "UTF-16BE";
+                start = 2;
+                length -= length & 1;
+            }
+            if (length > 2) {
+                if ((bytes[0] == (byte) 0xEF) && (bytes[1] == (byte) 0xBB)
+                        && (bytes[2] == (byte) 0xBF)) {
+                    encoding = "UTF-8";
+                    start = 3;
+                }
+                if (length > 3) {
+                    if ((bytes[0] == (byte) 0x00) && (bytes[1] == (byte) 0x00)
+                            && (bytes[2] == (byte) 0xFE)
+                            && (bytes[3] == (byte) 0xFF)) {
+                        encoding = "UTF-32BE";
+                        start = 4;
+                        length -= length & 3;
+                    }
+                    if ((bytes[0] == (byte) 0xFF) && (bytes[1] == (byte) 0xFE)
+                            && (bytes[2] == (byte) 0x00)
+                            && (bytes[3] == (byte) 0x00)) {
+                        encoding = "UTF-32LE";
+                        start = 4;
+                        length -= length & 3;
+                    }
+                }
+            }
+        }
+
+        String header = new String(bytes, start, length - start, encoding);
+
+        // Check binary types
+        if (header.startsWith("PK")) {
+            return "application/zip";
+        }
+        if (header.startsWith("GI")) {
+            return "image/gif";
         }
-        if ((chars[0] == 'G') && (chars[1] == 'I')) {
-            return "image/gif"; //$NON-NLS-1$
+
+        // Check text types
+        String textHeader = header.trim().toUpperCase();
+        if (textHeader.startsWith("<!DOCTYPE HTML") ||
+                textHeader.startsWith("<HTML") ||
+                textHeader.startsWith("<HEAD") ||
+                textHeader.startsWith("<BODY") ||
+                textHeader.startsWith("<HEAD")) {
+            return "text/html";
         }
-        if (new String(chars).trim().startsWith("<")) { //$NON-NLS-1$
-            return "text/html"; //$NON-NLS-1$
+
+        if (textHeader.startsWith("<?XML")) {
+            return "application/xml";
         }
+
+        // Give up
         return null;
     }
 

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/tests/api/java/net/URLConnectionTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/tests/api/java/net/URLConnectionTest.java?rev=571503&r1=571502&r2=571503&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/tests/api/java/net/URLConnectionTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/tests/api/java/net/URLConnectionTest.java Fri Aug 31 09:01:38 2007
@@ -18,6 +18,7 @@
 package tests.api.java.net;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FilePermission;
@@ -887,28 +888,76 @@
 		assertTrue("getUseCaches should have returned true", uc.getUseCaches());
 	}
 
-	/**
-	 * @tests java.net.URLConnection#guessContentTypeFromStream(java.io.InputStream)
-	 */
-	public void test_guessContentTypeFromStreamLjava_io_InputStream() throws IOException {
-        InputStream in = uc.getInputStream();
-        byte[] bytes = new byte[in.available()];
-
-        in.read(bytes, 0, bytes.length);
-        in.close();
-        // RI fails and it's a non-bug difference.
-        assertEquals("Should have returned text/html", "text/html",
-                URLConnection
-                        .guessContentTypeFromStream(new ByteArrayInputStream(
-                                bytes)));
+    private byte[] toBOMBytes(String text, String enc) throws IOException {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
 
-        try {
+        if (enc.equals("UTF-8")) bos.write(new byte[] {(byte)0xEF, (byte)0xBB, (byte)0xBF});
+        if (enc.equals("UTF-16BE")) bos.write(new byte[] {(byte)0xFE, (byte)0xFF});
+        if (enc.equals("UTF-16LE")) bos.write(new byte[] {(byte)0xFF, (byte)0xFE});
+        if (enc.equals("UTF-32BE")) bos.write(new byte[] {(byte)0x00, (byte)0x00, (byte)0xFE, (byte)0xFF});
+        if (enc.equals("UTF-32LE")) bos.write(new byte[] {(byte)0xFF, (byte)0xFE, (byte)0x00, (byte)0x00});
+
+        bos.write(text.getBytes(enc));
+        return bos.toByteArray();
+    }
+    
+    /**
+     * @tests java.net.URLConnection#guessContentTypeFromStream(java.io.InputStream)
+     */
+    public void test_guessContentTypeFromStreamLjava_io_InputStream() throws IOException {
+        String[] headers = new String[] {
+                "<html>",
+                "<head>",
+                " <head ",
+                "<body",
+                "<BODY ",
+                "<!DOCTYPE html",
+                "<?xml "
+        };
+        String[] expected = new String[] {
+                "text/html",
+                "text/html",
+                "text/html",
+                "text/html",
+                "text/html",
+                "text/html",
+                "application/xml"
+        };
+
+        String[] encodings = new String[] {"ASCII", "UTF-8", "UTF-16BE", "UTF-16LE", "UTF-32BE", "UTF-32LE"};
+        for (int i = 0; i < headers.length; i++) {
+            for (String enc : encodings) {
+                InputStream is = new ByteArrayInputStream(toBOMBytes(headers[i], enc));
+                String mime = URLConnection.guessContentTypeFromStream(is);
+                assertEquals("checking " + headers[i] + " with " + enc,
+                        expected[i], mime);
+            }
+        }
+
+        // Try simple case
+         try {
             URLConnection.guessContentTypeFromStream(null);
             fail("should throw NullPointerException");
         } catch (NullPointerException e){
             // expected
         }
+
+        // Test magic bytes
+        byte[][] bytes = new byte[][] {
+                { 'P', 'K' },
+                { 'G', 'I' }
+        };
+        expected = new String[] {
+                "application/zip",
+                "image/gif"
+        };
+
+        for (int i = 0; i < bytes.length; i++) {
+            InputStream is = new ByteArrayInputStream(bytes[i]);
+            assertEquals(expected[i], URLConnection.guessContentTypeFromStream(is));
+        }
     }
+
 
 	/**
 	 * @tests java.net.URLConnection#setAllowUserInteraction(boolean)