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)