diff --git a/tika-parsers/src/main/java/org/apache/tika/parser/html/HtmlParser.java b/tika-parsers/src/main/java/org/apache/tika/parser/html/HtmlParser.java index e0d7ac2..66100f1 100644 --- a/tika-parsers/src/main/java/org/apache/tika/parser/html/HtmlParser.java +++ b/tika-parsers/src/main/java/org/apache/tika/parser/html/HtmlParser.java @@ -45,10 +45,11 @@ public class HtmlParser implements Parser { // Use the widest, most common charset as our default. private static final String DEFAULT_CHARSET = "windows-1252"; private static final int META_TAG_BUFFER_SIZE = 4096; - private static final Pattern HTTP_EQUIV_CHARSET_PATTERN = Pattern.compile( - "(?is)"); + private static final Pattern CONTENT_TYPE_PATTERN = Pattern.compile("(?i);\\s*charset\\s*=\\s*(.*)"); @@ -67,12 +68,20 @@ public class HtmlParser implements Parser { if (bufferSize != -1) { String metaString = new String(buffer, 0, bufferSize); - Matcher m = HTTP_EQUIV_CHARSET_PATTERN.matcher(metaString); + Matcher m = HTTP_EQUIV_PATTERN.matcher(metaString); if (m.find()) { - String charset = m.group(1); - if (Charset.isSupported(charset)) { - metadata.set(Metadata.CONTENT_ENCODING, charset); - return charset; + // TIKA-349: flexible handling of attributes + // We have one or more x or x=y attributes, separated by ';' + String[] attrs = m.group(1).split(";"); + for (String attr : attrs) { + String[] keyValue = attr.trim().split("="); + if ((keyValue.length == 2) && keyValue[0].equalsIgnoreCase("charset")) { + String charset = keyValue[1]; + if (Charset.isSupported(charset)) { + metadata.set(Metadata.CONTENT_ENCODING, charset); + return charset; + } + } } } } diff --git a/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java b/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java index fcdc0bc..da90393 100644 --- a/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java +++ b/tika-parsers/src/test/java/org/apache/tika/parser/html/HtmlParserTest.java @@ -267,7 +267,7 @@ public class HtmlParserTest extends TestCase { /** * Test case for TIKA-341 - * @see TIKA-XXX + * @see TIKA-341 */ public void testUsingCharsetInContentTypeHeader() throws Exception { final String test = @@ -307,5 +307,34 @@ public class HtmlParserTest extends TestCase { assertEquals("baz", parts[2]); } + /** + * Test case for TIKA-349 + * @see TIKA-349 + */ + public void testHttpEquivCharsetFunkyAttributes() throws Exception { + String test1 = + "" + + "the name is \u00e1ndre" + + ""; + Metadata metadata = new Metadata(); + new HtmlParser().parse ( + new ByteArrayInputStream(test1.getBytes("UTF-8")), + new BodyContentHandler(), metadata, new ParseContext()); + assertEquals("ISO-8859-1", metadata.get(Metadata.CONTENT_ENCODING)); + + // Some HTML pages have errors like ';;' versus '; ' as separator + String test2 = + "" + + "the name is \u00e1ndre" + + ""; + metadata = new Metadata(); + new HtmlParser().parse ( + new ByteArrayInputStream(test2.getBytes("UTF-8")), + new BodyContentHandler(), metadata, new ParseContext()); + assertEquals("ISO-8859-1", metadata.get(Metadata.CONTENT_ENCODING)); + } + }