2011-05-24 Jay Civelli <jcivelli@chromium.org>
authorjcivelli@chromium.org <jcivelli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 May 2011 19:32:03 +0000 (19:32 +0000)
committerjcivelli@chromium.org <jcivelli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 May 2011 19:32:03 +0000 (19:32 +0000)
        Reviewed by Adam Barth.

        Adding MHTML reading support.
        https://bugs.webkit.org/show_bug.cgi?id=7168

        * configure.ac:
2011-05-24  Jay Civelli  <jcivelli@chromium.org>

        Reviewed by Adam Barth.

        Adding MHTML reading support to WebCore.
        https://bugs.webkit.org/show_bug.cgi?id=7168

        * mhtml/frame_0.html_original: Added.
        * mhtml/frame_1.html_original: Added.
        * mhtml/frame_2.html_original: Added.
        * mhtml/frame_4.html_original: Added.
        * mhtml/multi_frames.html_original: Added.
        * mhtml/multi_frames_ie.mht: Added.
        * mhtml/multi_frames_unmht.mht: Added.
        * mhtml/page_with_css_and_js.html_original: Added.
        * mhtml/page_with_css_and_js_ie.mht: Added.
        * mhtml/page_with_css_and_js_unmht.mht: Added.
        * mhtml/page_with_image.html_original: Added.
        * mhtml/page_with_image_ie.mht: Added.
        * mhtml/page_with_image_unmht.mht: Added.
        * mhtml/resources/red_square.png: Added.
        * mhtml/simple_page.html_original: Added.
        * mhtml/simple_page_ie.mht: Added.
        * mhtml/simple_page_unmht.mht: Added.
        * platform/chromium/mhtml/multi_frames_ie-expected.txt: Added.
        * platform/chromium/mhtml/multi_frames_unmht-expected.txt: Added.
        * platform/chromium/mhtml/page_with_css_and_js_ie-expected.txt: Added.
        * platform/chromium/mhtml/page_with_css_and_js_unmht-expected.txt: Added.
        * platform/chromium/mhtml/page_with_image_ie-expected.txt: Added.
        * platform/chromium/mhtml/page_with_image_unmht-expected.txt: Added.
        * platform/chromium/mhtml/simple_page_ie-expected.txt: Added.
        * platform/chromium/mhtml/simple_page_unmht-expected.txt: Added.
2011-05-24  Jay Civelli  <jcivelli@chromium.org>

        Reviewed by Adam Barth.

        Adding MHTML reading support. That required some basic MIME header parsing.
        Modified DocumentLoader to keep a reference to the currently Archive loaded,
        so we can have different policies for loading subresources depending on the
        archive type.
        https://bugs.webkit.org/show_bug.cgi?id=7168

        * CMakeLists.txt:
        * Configurations/FeatureDefines.xcconfig:
        * GNUmakefile.am:
        * GNUmakefile.list.am:
        * WebCore.gyp/WebCore.gyp:
        * WebCore.gypi:
        * WebCore.pro:
        * WebCore.vcproj/WebCore.vcproj:
        * WebCore.xcodeproj/project.pbxproj:
        * features.pri:
        * loader/DocumentLoader.cpp:
        (WebCore::DocumentLoader::commitLoad):
        (WebCore::DocumentLoader::setupForReplaceByMIMEType):
        (WebCore::DocumentLoader::popArchiveForSubframe):
        (WebCore::DocumentLoader::scheduleArchiveLoad):
        * loader/DocumentLoader.h:
        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::loadURLIntoChildFrame):
        (WebCore::FrameLoader::loadArchive):
        (WebCore::FrameLoader::stopAllLoaders):
        (WebCore::FrameLoader::finishedLoadingDocument):
        * loader/FrameLoader.h:
        (WebCore::FrameLoader::archive):
        * loader/MainResourceLoader.cpp:
        (WebCore::MainResourceLoader::continueAfterContentPolicy):
        * loader/ResourceLoader.cpp:
        (WebCore::ResourceLoader::start):
        * loader/archive/Archive.cpp: Added.
        * loader/archive/Archive.h:
        (WebCore::Archive::mainResource):
        * loader/archive/ArchiveFactory.cpp:
        (WebCore::archiveFactoryCreate):
        (WebCore::archiveMIMETypes):
        (WebCore::ArchiveFactory::create):
        (WebCore::ArchiveFactory::registerKnownArchiveMIMETypes):
        * loader/archive/ArchiveFactory.h:
        * loader/archive/ArchiveResourceCollection.cpp:
        (WebCore::ArchiveResourceCollection::addAllResources):
        (WebCore::ArchiveResourceCollection::popSubframeArchive):
        * loader/archive/ArchiveResourceCollection.h:
        * loader/archive/cf/LegacyWebArchive.cpp:
        (WebCore::LegacyWebArchive::create):
        (WebCore::LegacyWebArchive::type):
        * loader/archive/cf/LegacyWebArchive.h:
        * loader/archive/mhtml/MHTMLArchive.cpp: Added.
        * loader/archive/mhtml/MHTMLArchive.h: Added.
        * loader/archive/mhtml/MHTMLParser.cpp: Added.
        * loader/archive/mhtml/MHTMLParser.h: Added.
        * platform/MIMETypeRegistry.cpp:
        (WebCore::initializeSupportedNonImageMimeTypes):
        * platform/mac/PasteboardMac.mm:
        (WebCore::Pasteboard::documentFragment):
        * platform/network/MIMEHeader.cpp: Added.
        * platform/network/MIMEHeader.h: Added.
2011-05-24  Jay Civelli  <jcivelli@chromium.org>

        Reviewed by Adam Barth.

        Adding MHTML reading support to WebCore.
        https://bugs.webkit.org/show_bug.cgi?id=7168

       * features.gypi:
2011-05-24  Jay Civelli  <jcivelli@chromium.org>

        Reviewed by Adam Barth.

        Adding MHTML reading support.
        https://bugs.webkit.org/show_bug.cgi?id=7168

        * Scripts/build-webkit:
        * Scripts/old-run-webkit-tests:
        * Scripts/webkitperl/features.pm:
        * Scripts/webkitpy/layout_tests/port/test_files.py:
        * Scripts/webkitpy/layout_tests/port/webkit.py:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@87189 268f45cc-cd09-0410-ab3c-d52691b4dbfc

68 files changed:
ChangeLog
LayoutTests/ChangeLog
LayoutTests/mhtml/frame_0.html_original [new file with mode: 0644]
LayoutTests/mhtml/frame_1.html_original [new file with mode: 0644]
LayoutTests/mhtml/frame_2.html_original [new file with mode: 0644]
LayoutTests/mhtml/frame_4.html_original [new file with mode: 0644]
LayoutTests/mhtml/multi_frames.html_original [new file with mode: 0644]
LayoutTests/mhtml/multi_frames_ie.mht [new file with mode: 0755]
LayoutTests/mhtml/multi_frames_unmht.mht [new file with mode: 0755]
LayoutTests/mhtml/page_with_css_and_js.html_original [new file with mode: 0755]
LayoutTests/mhtml/page_with_css_and_js_ie.mht [new file with mode: 0755]
LayoutTests/mhtml/page_with_css_and_js_unmht.mht [new file with mode: 0755]
LayoutTests/mhtml/page_with_image.html_original [new file with mode: 0644]
LayoutTests/mhtml/page_with_image_ie.mht [new file with mode: 0755]
LayoutTests/mhtml/page_with_image_unmht.mht [new file with mode: 0755]
LayoutTests/mhtml/resources/red_square.png [new file with mode: 0644]
LayoutTests/mhtml/simple_page.html_original [new file with mode: 0644]
LayoutTests/mhtml/simple_page_ie.mht [new file with mode: 0755]
LayoutTests/mhtml/simple_page_unmht.mht [new file with mode: 0755]
LayoutTests/platform/chromium/mhtml/multi_frames_ie-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/multi_frames_unmht-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/page_with_css_and_js_ie-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/page_with_css_and_js_unmht-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/page_with_image_ie-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/page_with_image_unmht-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/simple_page_ie-expected.txt [new file with mode: 0644]
LayoutTests/platform/chromium/mhtml/simple_page_unmht-expected.txt [new file with mode: 0644]
Source/WebCore/CMakeLists.txt
Source/WebCore/ChangeLog
Source/WebCore/Configurations/FeatureDefines.xcconfig
Source/WebCore/GNUmakefile.am
Source/WebCore/GNUmakefile.list.am
Source/WebCore/WebCore.gyp/WebCore.gyp
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.pro
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/features.pri
Source/WebCore/loader/DocumentLoader.cpp
Source/WebCore/loader/DocumentLoader.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/MainResourceLoader.cpp
Source/WebCore/loader/ResourceLoader.cpp
Source/WebCore/loader/archive/Archive.cpp [new file with mode: 0644]
Source/WebCore/loader/archive/Archive.h
Source/WebCore/loader/archive/ArchiveFactory.cpp
Source/WebCore/loader/archive/ArchiveFactory.h
Source/WebCore/loader/archive/ArchiveResourceCollection.cpp
Source/WebCore/loader/archive/ArchiveResourceCollection.h
Source/WebCore/loader/archive/cf/LegacyWebArchive.cpp
Source/WebCore/loader/archive/cf/LegacyWebArchive.h
Source/WebCore/loader/archive/mhtml/MHTMLArchive.cpp [new file with mode: 0644]
Source/WebCore/loader/archive/mhtml/MHTMLArchive.h [new file with mode: 0644]
Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp [new file with mode: 0644]
Source/WebCore/loader/archive/mhtml/MHTMLParser.h [new file with mode: 0644]
Source/WebCore/platform/MIMETypeRegistry.cpp
Source/WebCore/platform/mac/PasteboardMac.mm
Source/WebCore/platform/network/MIMEHeader.cpp [new file with mode: 0644]
Source/WebCore/platform/network/MIMEHeader.h [new file with mode: 0644]
Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/features.gypi
Tools/ChangeLog
Tools/Scripts/build-webkit
Tools/Scripts/old-run-webkit-tests
Tools/Scripts/webkitperl/features.pm
Tools/Scripts/webkitpy/layout_tests/port/test_files.py
configure.ac

index 2df9fdb..a50894e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2011-05-24  Jay Civelli  <jcivelli@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Adding MHTML reading support.
+        https://bugs.webkit.org/show_bug.cgi?id=7168
+
+        * configure.ac:
+
 2011-05-23  Ryuan Choi  <ryuan.choi@samsung.com>
 
         Rubber stamped by Eric Seidel.
index 11d0c77..7b628a4 100644 (file)
@@ -1,3 +1,36 @@
+2011-05-24  Jay Civelli  <jcivelli@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Adding MHTML reading support to WebCore.
+        https://bugs.webkit.org/show_bug.cgi?id=7168
+
+        * mhtml/frame_0.html_original: Added.
+        * mhtml/frame_1.html_original: Added.
+        * mhtml/frame_2.html_original: Added.
+        * mhtml/frame_4.html_original: Added.
+        * mhtml/multi_frames.html_original: Added.
+        * mhtml/multi_frames_ie.mht: Added.
+        * mhtml/multi_frames_unmht.mht: Added.
+        * mhtml/page_with_css_and_js.html_original: Added.
+        * mhtml/page_with_css_and_js_ie.mht: Added.
+        * mhtml/page_with_css_and_js_unmht.mht: Added.
+        * mhtml/page_with_image.html_original: Added.
+        * mhtml/page_with_image_ie.mht: Added.
+        * mhtml/page_with_image_unmht.mht: Added.
+        * mhtml/resources/red_square.png: Added.
+        * mhtml/simple_page.html_original: Added.
+        * mhtml/simple_page_ie.mht: Added.
+        * mhtml/simple_page_unmht.mht: Added.
+        * platform/chromium/mhtml/multi_frames_ie-expected.txt: Added.
+        * platform/chromium/mhtml/multi_frames_unmht-expected.txt: Added.
+        * platform/chromium/mhtml/page_with_css_and_js_ie-expected.txt: Added.
+        * platform/chromium/mhtml/page_with_css_and_js_unmht-expected.txt: Added.
+        * platform/chromium/mhtml/page_with_image_ie-expected.txt: Added.
+        * platform/chromium/mhtml/page_with_image_unmht-expected.txt: Added.
+        * platform/chromium/mhtml/simple_page_ie-expected.txt: Added.
+        * platform/chromium/mhtml/simple_page_unmht-expected.txt: Added.
+
 2011-05-24  Sam Weinig  <sam@webkit.org>
 
         Reviewed by Beth Dakin.
diff --git a/LayoutTests/mhtml/frame_0.html_original b/LayoutTests/mhtml/frame_0.html_original
new file mode 100644 (file)
index 0000000..ad7bb95
--- /dev/null
@@ -0,0 +1,7 @@
+<html>
+
+<body>
+The first frame!
+</body>
+
+</html>
diff --git a/LayoutTests/mhtml/frame_1.html_original b/LayoutTests/mhtml/frame_1.html_original
new file mode 100644 (file)
index 0000000..a8b6c63
--- /dev/null
@@ -0,0 +1,7 @@
+<html>
+
+<body>
+The second frame!
+</body>
+
+</html>
diff --git a/LayoutTests/mhtml/frame_2.html_original b/LayoutTests/mhtml/frame_2.html_original
new file mode 100644 (file)
index 0000000..313fd62
--- /dev/null
@@ -0,0 +1,11 @@
+<html>
+
+<body>
+The third frame!<br>
+This one contains yet another frame. What a twist!</br>
+<iframe src="frame_4.html"></iframe>
+
+
+</body>
+
+</html>
diff --git a/LayoutTests/mhtml/frame_4.html_original b/LayoutTests/mhtml/frame_4.html_original
new file mode 100644 (file)
index 0000000..886908a
--- /dev/null
@@ -0,0 +1,8 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+</head><body>
+This is frame 4!<br>
+<img src="frame_4_files/red_square.png" onerror="document.getElementById('error').innerHTML+='Failed to load image!'">
+<div id="error">Failed to load image!</div>
+</body></html>
\ No newline at end of file
diff --git a/LayoutTests/mhtml/multi_frames.html_original b/LayoutTests/mhtml/multi_frames.html_original
new file mode 100644 (file)
index 0000000..cccf8be
--- /dev/null
@@ -0,0 +1,20 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+
+<title>A page that contains multiple nested frames</title>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+  layoutTestController.dumpChildFramesAsText();
+}
+</script>
+</head><body>
+This page contains several frames.<br>
+<iframe src="multi_frames_files/frame_0.html"></iframe><br>
+<iframe src="multi_frames_files/frame_1.html"></iframe><br>
+<iframe src="multi_frames_files/frame_2.html"></iframe><br>
+And a red square:<br>
+<img src="frame_4_data/red_square.png" onerror="document.getElementById('error').innerHTML+='Failed to load image!'">
+<div id="error"></div>
+</body></html>
\ No newline at end of file
diff --git a/LayoutTests/mhtml/multi_frames_ie.mht b/LayoutTests/mhtml/multi_frames_ie.mht
new file mode 100755 (executable)
index 0000000..cd4e25b
--- /dev/null
@@ -0,0 +1,113 @@
+From: "Saved by Windows Internet Explorer 9"\r
+Subject: A page that contains multiple nested frames\r
+Date: Wed, 18 May 2011 16:50:17 -0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       type="multipart/alternative";\r
+       boundary="----=_NextPart_000_0020_01CC157B.AAC3EF70"\r
+X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7600.16776\r
+\r
+This is a multi-part message in MIME format.\r
+\r
+------=_NextPart_000_0020_01CC157B.AAC3EF70\r
+Content-Type: image/png\r
+Content-Transfer-Encoding: base64\r
+Content-Location: http://localhost/resources/red_square.png\r
+\r
+iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\r
+jwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACESURBVEhL7ZYxDoAwCEXB2LGTo46ewXj/zXgV\r
+PQKgexP/Ai6l889/6Stp4HtZjYKOiRCpEpfSEIYgJqxNMFTkFUjVXiZhT6qGirwCqdrLJOxJ1VCR\r
+V6A/1XxNc9jqQ6JkpjTU2rwQR+5c4769YCM5zn/BX4PY33Dljb0+JtiTqqEir8ADWEIY6dz7d1cA\r
+AAAASUVORK5CYII=\r
+\r
+------=_NextPart_000_0020_01CC157B.AAC3EF70\r
+Content-Type: multipart/alternative;\r
+       boundary="----=_NextPart_001_0023_01CC157B.AAC41680"\r
+\r
+\r
+------=_NextPart_001_0023_01CC157B.AAC41680\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/top_frame.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD><TITLE>A page that contains multiple nested frames</TITLE>\r
+<META content=3D"text/html; charset=3Dwindows-1252" =\r
+http-equiv=3DContent-Type>\r
+<SCRIPT>=0A=\r
+if (window.layoutTestController) {=0A=\r
+  layoutTestController.dumpAsText();=0A=\r
+  layoutTestController.dumpChildFramesAsText();=0A=\r
+}=0A=\r
+</SCRIPT>\r
+\r
+<META name=3DGENERATOR content=3D"MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>This page contains several frames.<BR><IFRAME=20\r
+src=3D"http://localhost/frame_0.html"></IFRAME><BR><IFRAME=20\r
+src=3D"http://localhost/frame_1.html"></IFRAME><BR><IFRAME=20\r
+src=3D"http://localhost/frame_2.html"></IFRAME><BR>And a red =\r
+square:<BR><IMG=20\r
+onerror=3D"document.getElementById('error').innerHTML+=3D'Failed to load =\r
+image!'"=20\r
+src=3D"http://localhost/resources/red_square.png">=20\r
+<DIV id=3Derror></DIV></BODY></HTML>\r
+\r
+------=_NextPart_001_0023_01CC157B.AAC41680\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: 7bit\r
+Content-Location: http://localhost/frame_0.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD>\r
+<META content="text/html; charset=windows-1252" http-equiv=Content-Type>\r
+<META name=GENERATOR content="MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>The first frame! </BODY></HTML>\r
+\r
+------=_NextPart_001_0023_01CC157B.AAC41680--\r
+\r
+------=_NextPart_000_0020_01CC157B.AAC3EF70\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: 7bit\r
+Content-Location: http://localhost/frame_1.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD>\r
+<META content="text/html; charset=windows-1252" http-equiv=Content-Type>\r
+<META name=GENERATOR content="MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>The second frame! </BODY></HTML>\r
+\r
+------=_NextPart_000_0020_01CC157B.AAC3EF70\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/frame_4.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD>\r
+<META content=3D"text/html; charset=3Dwindows-1252" =\r
+http-equiv=3DContent-Type>\r
+<META name=3DGENERATOR content=3D"MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>This is frame 4!<BR><IMG=20\r
+onerror=3D"document.getElementById('error').innerHTML+=3D'Failed to load =\r
+image!'"=20\r
+src=3D"http://localhost/resources/red_square.png">=20\r
+<DIV id=3Derror></DIV></BODY></HTML>\r
+\r
+------=_NextPart_000_0020_01CC157B.AAC3EF70\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: 7bit\r
+Content-Location: http://localhost/frame_2.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD>\r
+<META content="text/html; charset=windows-1252" http-equiv=Content-Type>\r
+<META name=GENERATOR content="MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>The third frame!<BR>This one contains yet another frame. What a \r
+twist!<BR><IFRAME \r
+src="http://localhost/frame_4.html"></IFRAME></BODY></HTML>\r
+\r
+------=_NextPart_000_0020_01CC157B.AAC3EF70--\r
diff --git a/LayoutTests/mhtml/multi_frames_unmht.mht b/LayoutTests/mhtml/multi_frames_unmht.mht
new file mode 100755 (executable)
index 0000000..c69246e
--- /dev/null
@@ -0,0 +1,96 @@
+From: <Saved by UnMHT>\r
+Subject: =?iso-2022-jp?B?QSBwYWdlIHRoYXQgY29udGFpbnMgbXVsdGlwbGUgbmVzdGVkIGZyYW1lcw==?=\r
+Date: Wed, May 18 2011 15:20:34 GMT-0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       boundary="----=_NextPart_000_0000_58874EE0.2096A571";\r
+       type="text/html"\r
+\r
+------=_NextPart_000_0000_58874EE0.2096A571\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/top_frame.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+\r
+<title>A page that contains multiple nested frames</title>\r
+<script>\r
+if (window.layoutTestController) {\r
+  layoutTestController.dumpAsText();\r
+  layoutTestController.dumpChildFramesAsText();\r
+}\r
+</script>\r
+<base href=3D"http://localhost/"></base></head><body>\r
+This page contains several frames.<br>\r
+<iframe src=3D"http://localhost/frame_0.html"></iframe><br>\r
+<iframe src=3D"http://localhost/frame_1.html"></iframe><br>\r
+<iframe src=3D"http://localhost/frame_2.html"></iframe><br>\r
+And a red square:<br>\r
+<img onerror=3D"document.getElementById(&#x27;error&#x27;).innerHTML+=3D&#x=\r
+27;Failed to load image!&#x27;" src=3D"resources/red_square.png">\r
+<div id=3D"error"></div>\r
+</body></html>\r
+------=_NextPart_000_0000_58874EE0.2096A571\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/frame_0.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+<base href=3D"http://localhost/"></base></head><body>\r
+The first frame!\r
+</body></html>\r
+------=_NextPart_000_0000_58874EE0.2096A571\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/frame_1.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+<base href=3D"http://localhost/"></base></head><body>\r
+The second frame!\r
+</body></html>\r
+------=_NextPart_000_0000_58874EE0.2096A571\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/frame_2.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+<base href=3D"http://localhost/"></base></head><body>\r
+The third frame!<br>\r
+This one contains yet another frame. What a twist!<br>\r
+<iframe src=3D"http://localhost/frame_4.html"></iframe>\r
+\r
+\r
+</body></html>\r
+------=_NextPart_000_0000_58874EE0.2096A571\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/frame_4.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+<base href=3D"http://localhost/"></base></head><body>\r
+This is frame 4!<br>\r
+<img onerror=3D"document.getElementById(&#x27;error&#x27;).innerHTML+=3D&#x=\r
+27;Failed to load image!&#x27;" src=3D"resources/red_square.png">\r
+<div id=3D"error"></div>\r
+</body></html>\r
+------=_NextPart_000_0000_58874EE0.2096A571\r
+Content-Type: image/png\r
+Content-Transfer-Encoding: base64\r
+Content-Location: http://localhost/resources/red_square.png\r
+\r
+iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\r
+jwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACESURBVEhL7ZYxDoAwCEXB2LGTo46ewXj/zXgV\r
+PQKgexP/Ai6l889/6Stp4HtZjYKOiRCpEpfSEIYgJqxNMFTkFUjVXiZhT6qGirwCqdrLJOxJ1VCR\r
+V6A/1XxNc9jqQ6JkpjTU2rwQR+5c4769YCM5zn/BX4PY33Dljb0+JtiTqqEir8ADWEIY6dz7d1cA\r
+AAAASUVORK5CYII=\r
+------=_NextPart_000_0000_58874EE0.2096A571--\r
diff --git a/LayoutTests/mhtml/page_with_css_and_js.html_original b/LayoutTests/mhtml/page_with_css_and_js.html_original
new file mode 100755 (executable)
index 0000000..1ed3de0
--- /dev/null
@@ -0,0 +1,27 @@
+<html>\r
+\r
+<head>\r
+  <link href="resources/hide_image.css" rel="stylesheet" type="text/css">\r
+   \r
+  <script type="text/javascript" src="resources/remove_image_script.js"></script>\r
+</head>\r
+\r
+<body onload="onLoad()">\r
+This page tests that CSS and JavaScript resources are retrieved correctly for MHTML files.<br><br>\r
+There should be only one red square below:\r
+<div id="firstDiv">\r
+<img src="resources/red_square.png"><br><br>\r
+</div>\r
+<div id="secondDiv">\r
+The red square below should be hidden by way of CSS.<br>\r
+<img src="resources/red_square.png"><br><br>\r
+</div>\r
+<div id="thirdDiv">\r
+The red square below should be hidden by way of JavaScript.<br>\r
+<img src="resources/red_square.png"><br><br>\r
+</div>\r
+  \r
+</body>\r
+\r
+\r
+</html>\r
diff --git a/LayoutTests/mhtml/page_with_css_and_js_ie.mht b/LayoutTests/mhtml/page_with_css_and_js_ie.mht
new file mode 100755 (executable)
index 0000000..71b7284
--- /dev/null
@@ -0,0 +1,82 @@
+From: "Saved by Windows Internet Explorer 9"\r
+Subject: \r
+Date: Wed, 18 May 2011 16:49:23 -0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       type="text/html";\r
+       boundary="----=_NextPart_000_0012_01CC157B.8AA06570"\r
+X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7600.16776\r
+\r
+This is a multi-part message in MIME format.\r
+\r
+------=_NextPart_000_0012_01CC157B.8AA06570\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/page_with_css_and_js.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD>\r
+<META content=3D"text/html; charset=3Dwindows-1252" =\r
+http-equiv=3DContent-Type><LINK=20\r
+rel=3Dstylesheet type=3Dtext/css =\r
+href=3D"http://localhost/resources/hide_image.css">\r
+<SCRIPT type=3Dtext/javascript=20\r
+src=3D"http://localhost/resources/remove_image_script.js"></SCRIPT>\r
+\r
+<SCRIPT>=0A=\r
+    if (window.layoutTestController) {=0A=\r
+      layoutTestController.dumpAsText();=0A=\r
+      layoutTestController.waitUntilDone();=0A=\r
+    }=0A=\r
+  </SCRIPT>\r
+\r
+<META name=3DGENERATOR content=3D"MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY onload=3DonLoad()>This page tests that CSS and JavaScript =\r
+resources are=20\r
+retrieved correctly for MHTML files.<BR><BR>There should be only one red =\r
+square=20\r
+below:=20\r
+<DIV id=3DfirstDiv><IMG=20\r
+src=3D"http://localhost/resources/red_square.png"><BR><BR></DIV>\r
+<DIV id=3DsecondDiv>The red square below should be hidden by way of =\r
+CSS.<BR><IMG=20\r
+src=3D"http://localhost/resources/red_square.png"><BR><BR></DIV>\r
+<DIV id=3DthirdDiv>The red square below should be hidden by way of=20\r
+JavaScript.<BR><IMG=20\r
+src=3D"http://localhost/resources/red_square.png"><BR><BR></DIV></BODY><=\r
+/HTML>\r
+\r
+------=_NextPart_000_0012_01CC157B.8AA06570\r
+Content-Type: image/png\r
+Content-Transfer-Encoding: base64\r
+Content-Location: http://localhost/resources/red_square.png\r
+\r
+iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\r
+jwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACESURBVEhL7ZYxDoAwCEXB2LGTo46ewXj/zXgV\r
+PQKgexP/Ai6l889/6Stp4HtZjYKOiRCpEpfSEIYgJqxNMFTkFUjVXiZhT6qGirwCqdrLJOxJ1VCR\r
+V6A/1XxNc9jqQ6JkpjTU2rwQR+5c4769YCM5zn/BX4PY33Dljb0+JtiTqqEir8ADWEIY6dz7d1cA\r
+AAAASUVORK5CYII=\r
+\r
+------=_NextPart_000_0012_01CC157B.8AA06570\r
+Content-Type: text/css;\r
+       charset="iso-8859-1"\r
+Content-Transfer-Encoding: 7bit\r
+Content-Location: http://localhost/resources/hide_image.css\r
+\r
+#secondDiv {\r
+       DISPLAY: none\r
+}\r
+\r
+------=_NextPart_000_0012_01CC157B.8AA06570\r
+Content-Type: application/octet-stream\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/resources/remove_image_script.js\r
+\r
+function onLoad() {=0A=\r
+    divToRemove =3D document.getElementById("thirdDiv");=0A=\r
+    divToRemove.parentNode.removeChild(divToRemove);=0A=\r
+    if (window.layoutTestController)=0A=\r
+      layoutTestController.notifyDone();=0A=\r
+}\r
+------=_NextPart_000_0012_01CC157B.8AA06570--\r
diff --git a/LayoutTests/mhtml/page_with_css_and_js_unmht.mht b/LayoutTests/mhtml/page_with_css_and_js_unmht.mht
new file mode 100755 (executable)
index 0000000..d7c3361
--- /dev/null
@@ -0,0 +1,75 @@
+From: <Saved by UnMHT>\r
+Subject: =?iso-2022-jp?B??=\r
+Date: Wed, May 18 2011 15:21:05 GMT-0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       boundary="----=_NextPart_000_0000_C2ECC76E.5EC79255";\r
+       type="text/html"\r
+\r
+------=_NextPart_000_0000_C2ECC76E.5EC79255\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/page_with_css_and_js.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+\r
+  <link type=3D"text/css" rel=3D"stylesheet" href=3D"resources/hide_image.c=\r
+ss"></link>\r
+  =20\r
+  <script src=3D"resources/remove_image_script.js" type=3D"text/javascript"=\r
+></script>\r
+  <script>\r
+    if (window.layoutTestController) {\r
+      layoutTestController.dumpAsText();\r
+      layoutTestController.waitUntilDone();\r
+    }\r
+  </script>\r
+<base href=3D"http://localhost/"></base></head><body onload=3D"onLoad()">\r
+This page tests that CSS and JavaScript resources are retrieved correctly=\r
+ for MHTML files.<br><br>\r
+There should be only one red square below:\r
+<div id=3D"firstDiv">\r
+<img src=3D"resources/red_square.png"><br><br>\r
+</div>\r
+<div id=3D"secondDiv">\r
+The red square below should be hidden by way of CSS.<br>\r
+<img src=3D"resources/red_square.png"><br><br>\r
+</div>\r
+<div id=3D"thirdDiv">\r
+The red square below should be hidden by way of JavaScript.<br>\r
+<img src=3D"resources/red_square.png"><br><br>\r
+</div>\r
+\r
+ =20\r
+</body></html>\r
+------=_NextPart_000_0000_C2ECC76E.5EC79255\r
+Content-Type: text/css\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/resources/hide_image.css\r
+\r
+#secondDiv { display: none; }\r
+\r
+------=_NextPart_000_0000_C2ECC76E.5EC79255\r
+Content-Type: text/javascript\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/resources/remove_image_script.js\r
+\r
+function onLoad() {\r
+    divToRemove =3D document.getElementById("thirdDiv");\r
+    divToRemove.parentNode.removeChild(divToRemove);\r
+    if (window.layoutTestController)\r
+      layoutTestController.notifyDone();\r
+}\r
+------=_NextPart_000_0000_C2ECC76E.5EC79255\r
+Content-Type: image/png\r
+Content-Transfer-Encoding: base64\r
+Content-Location: http://localhost/resources/red_square.png\r
+\r
+iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\r
+jwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACESURBVEhL7ZYxDoAwCEXB2LGTo46ewXj/zXgV\r
+PQKgexP/Ai6l889/6Stp4HtZjYKOiRCpEpfSEIYgJqxNMFTkFUjVXiZhT6qGirwCqdrLJOxJ1VCR\r
+V6A/1XxNc9jqQ6JkpjTU2rwQR+5c4769YCM5zn/BX4PY33Dljb0+JtiTqqEir8ADWEIY6dz7d1cA\r
+AAAASUVORK5CYII=\r
+------=_NextPart_000_0000_C2ECC76E.5EC79255--\r
diff --git a/LayoutTests/mhtml/page_with_image.html_original b/LayoutTests/mhtml/page_with_image.html_original
new file mode 100644 (file)
index 0000000..a0bc0dd
--- /dev/null
@@ -0,0 +1,16 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+
+<title>Page with square</title>
+<script>
+if (window.layoutTestController) {
+  layoutTestController.dumpAsText();
+}
+
+</script>
+</head><body>
+This is a red square:<br>
+<img src="page_with_image_files/red_square.png" onerror="document.getElementById('error').innerHTML+='Failed to load image!'">
+<div id="error"></div>
+</body></html>
\ No newline at end of file
diff --git a/LayoutTests/mhtml/page_with_image_ie.mht b/LayoutTests/mhtml/page_with_image_ie.mht
new file mode 100755 (executable)
index 0000000..1c241ee
--- /dev/null
@@ -0,0 +1,47 @@
+From: "Saved by Windows Internet Explorer 9"\r
+Subject: Page with square\r
+Date: Wed, 18 May 2011 16:49:44 -0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       type="text/html";\r
+       boundary="----=_NextPart_000_001B_01CC157B.96F808A0"\r
+X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7600.16776\r
+\r
+This is a multi-part message in MIME format.\r
+\r
+------=_NextPart_000_001B_01CC157B.96F808A0\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/page_with_image.html\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD><TITLE>Page with square</TITLE>\r
+<META content=3D"text/html; charset=3Dwindows-1252" =\r
+http-equiv=3DContent-Type>\r
+<SCRIPT>=0A=\r
+if (window.layoutTestController) {=0A=\r
+  layoutTestController.dumpAsText();=0A=\r
+}=0A=\r
+=0A=\r
+</SCRIPT>\r
+\r
+<META name=3DGENERATOR content=3D"MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>This is a red square:<BR><IMG=20\r
+onerror=3D"document.getElementById('error').innerHTML+=3D'Failed to load =\r
+image!'"=20\r
+src=3D"http://localhost/resources/red_square.png">=20\r
+<DIV id=3Derror></DIV></BODY></HTML>\r
+\r
+------=_NextPart_000_001B_01CC157B.96F808A0\r
+Content-Type: image/png\r
+Content-Transfer-Encoding: base64\r
+Content-Location: http://localhost/resources/red_square.png\r
+\r
+iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\r
+jwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACESURBVEhL7ZYxDoAwCEXB2LGTo46ewXj/zXgV\r
+PQKgexP/Ai6l889/6Stp4HtZjYKOiRCpEpfSEIYgJqxNMFTkFUjVXiZhT6qGirwCqdrLJOxJ1VCR\r
+V6A/1XxNc9jqQ6JkpjTU2rwQR+5c4769YCM5zn/BX4PY33Dljb0+JtiTqqEir8ADWEIY6dz7d1cA\r
+AAAASUVORK5CYII=\r
+\r
+------=_NextPart_000_001B_01CC157B.96F808A0--\r
diff --git a/LayoutTests/mhtml/page_with_image_unmht.mht b/LayoutTests/mhtml/page_with_image_unmht.mht
new file mode 100755 (executable)
index 0000000..8af1b21
--- /dev/null
@@ -0,0 +1,41 @@
+From: <Saved by UnMHT>\r
+Subject: =?iso-2022-jp?B?UGFnZSB3aXRoIHNxdWFyZQ==?=\r
+Date: Wed, May 18 2011 16:38:33 GMT-0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       boundary="----=_NextPart_000_0000_02C8A5EE.D896CA6B";\r
+       type="text/html"\r
+\r
+------=_NextPart_000_0000_02C8A5EE.D896CA6B\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/page_with_image.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+\r
+<title>Page with square</title>\r
+<script>\r
+if (window.layoutTestController) {\r
+  layoutTestController.dumpAsText();\r
+}\r
+\r
+</script>\r
+<base href=3D"http://localhost/"></base></head><body>\r
+This is a red square:<br>\r
+<img onerror=3D"document.getElementById(&#x27;error&#x27;).innerHTML+=3D&#x=\r
+27;Failed to load image!&#x27;" src=3D"resources/red_square.png">\r
+<div id=3D"error"></div>\r
+</body></html>\r
+------=_NextPart_000_0000_02C8A5EE.D896CA6B\r
+Content-Type: image/png\r
+Content-Transfer-Encoding: base64\r
+Content-Location: http://localhost/resources/red_square.png\r
+\r
+iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAAAXNSR0IArs4c6QAAAARnQU1BAACx\r
+jwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAACESURBVEhL7ZYxDoAwCEXB2LGTo46ewXj/zXgV\r
+PQKgexP/Ai6l889/6Stp4HtZjYKOiRCpEpfSEIYgJqxNMFTkFUjVXiZhT6qGirwCqdrLJOxJ1VCR\r
+V6A/1XxNc9jqQ6JkpjTU2rwQR+5c4769YCM5zn/BX4PY33Dljb0+JtiTqqEir8ADWEIY6dz7d1cA\r
+AAAASUVORK5CYII=\r
+------=_NextPart_000_0000_02C8A5EE.D896CA6B--\r
diff --git a/LayoutTests/mhtml/resources/red_square.png b/LayoutTests/mhtml/resources/red_square.png
new file mode 100644 (file)
index 0000000..d8c599c
Binary files /dev/null and b/LayoutTests/mhtml/resources/red_square.png differ
diff --git a/LayoutTests/mhtml/simple_page.html_original b/LayoutTests/mhtml/simple_page.html_original
new file mode 100644 (file)
index 0000000..7d0020d
--- /dev/null
@@ -0,0 +1,13 @@
+<html><head>
+<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
+
+
+<title>A simple page</title>
+<script>
+if (window.layoutTestController)
+  layoutTestController.dumpAsText();
+</script>
+</head><body>
+<h1>This is a very simple page</h1>
+Very <b>basic</b> page.
+</body></html>
\ No newline at end of file
diff --git a/LayoutTests/mhtml/simple_page_ie.mht b/LayoutTests/mhtml/simple_page_ie.mht
new file mode 100755 (executable)
index 0000000..8c0f897
--- /dev/null
@@ -0,0 +1,23 @@
+From: "Saved by Windows Internet Explorer 9"\r
+Subject: A simple page\r
+Date: Wed, 18 May 2011 16:50:01 -0700\r
+MIME-Version: 1.0\r
+Content-Type: text/html;\r
+       charset="Windows-1252"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/simple_page.html\r
+X-MimeOLE: Produced By Microsoft MimeOLE V6.1.7600.16776\r
+\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<HTML><HEAD><TITLE>A simple page</TITLE>\r
+<META content=3D"text/html; charset=3Dwindows-1252" =\r
+http-equiv=3DContent-Type>\r
+<SCRIPT>=0A=\r
+if (window.layoutTestController)=0A=\r
+  layoutTestController.dumpAsText();=0A=\r
+</SCRIPT>\r
+\r
+<META name=3DGENERATOR content=3D"MSHTML 9.00.8112.16421"></HEAD>\r
+<BODY>\r
+<H1>This is a very simple page</H1>Very <B>basic</B> page. =\r
+</BODY></HTML>\r
diff --git a/LayoutTests/mhtml/simple_page_unmht.mht b/LayoutTests/mhtml/simple_page_unmht.mht
new file mode 100755 (executable)
index 0000000..cebedf2
--- /dev/null
@@ -0,0 +1,27 @@
+From: <Saved by UnMHT>\r
+Subject: =?iso-2022-jp?B?QSBzaW1wbGUgcGFnZQ==?=\r
+Date: Wed, May 11 2011 15:36:36 GMT-0700\r
+MIME-Version: 1.0\r
+Content-Type: multipart/related;\r
+       boundary="----=_NextPart_000_0000_87206557.D2C008B0";\r
+       type="text/html"\r
+\r
+------=_NextPart_000_0000_87206557.D2C008B0\r
+Content-Type: text/html; charset="ISO-8859-1"\r
+Content-Transfer-Encoding: quoted-printable\r
+Content-Location: http://localhost/simple_page.html\r
+\r
+<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html; charset=\r
+=3Diso-8859-1">\r
+\r
+\r
+<title>A simple page</title>\r
+<script>\r
+if (window.layoutTestController)\r
+  layoutTestController.dumpAsText();\r
+</script>\r
+<base href=3D"http://localhost/"></base></head><body>\r
+<h1>This is a very simple page</h1>\r
+Very <b>basic</b> page.\r
+</body></html>\r
+------=_NextPart_000_0000_87206557.D2C008B0--\r
diff --git a/LayoutTests/platform/chromium/mhtml/multi_frames_ie-expected.txt b/LayoutTests/platform/chromium/mhtml/multi_frames_ie-expected.txt
new file mode 100644 (file)
index 0000000..09ba461
--- /dev/null
@@ -0,0 +1,31 @@
+This page contains several frames.
+
+
+
+And a red square:
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+The first frame!
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+The second frame!
+
+--------
+Frame: '<!--framePath //<!--frame2-->-->'
+--------
+The third frame!
+This one contains yet another frame. What a twist!
+
+
+--------
+Frame: '<!--framePath //<!--frame2-->/<!--frame0-->-->'
+--------
+This is frame 4!
+
+
diff --git a/LayoutTests/platform/chromium/mhtml/multi_frames_unmht-expected.txt b/LayoutTests/platform/chromium/mhtml/multi_frames_unmht-expected.txt
new file mode 100644 (file)
index 0000000..09ba461
--- /dev/null
@@ -0,0 +1,31 @@
+This page contains several frames.
+
+
+
+And a red square:
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+The first frame!
+
+--------
+Frame: '<!--framePath //<!--frame1-->-->'
+--------
+The second frame!
+
+--------
+Frame: '<!--framePath //<!--frame2-->-->'
+--------
+The third frame!
+This one contains yet another frame. What a twist!
+
+
+--------
+Frame: '<!--framePath //<!--frame2-->/<!--frame0-->-->'
+--------
+This is frame 4!
+
+
diff --git a/LayoutTests/platform/chromium/mhtml/page_with_css_and_js_ie-expected.txt b/LayoutTests/platform/chromium/mhtml/page_with_css_and_js_ie-expected.txt
new file mode 100644 (file)
index 0000000..e790698
--- /dev/null
@@ -0,0 +1,6 @@
+This page tests that CSS and JavaScript resources are retrieved correctly for MHTML files.
+
+There should be only one red square below:
+
+
+
diff --git a/LayoutTests/platform/chromium/mhtml/page_with_css_and_js_unmht-expected.txt b/LayoutTests/platform/chromium/mhtml/page_with_css_and_js_unmht-expected.txt
new file mode 100644 (file)
index 0000000..e790698
--- /dev/null
@@ -0,0 +1,6 @@
+This page tests that CSS and JavaScript resources are retrieved correctly for MHTML files.
+
+There should be only one red square below:
+
+
+
diff --git a/LayoutTests/platform/chromium/mhtml/page_with_image_ie-expected.txt b/LayoutTests/platform/chromium/mhtml/page_with_image_ie-expected.txt
new file mode 100644 (file)
index 0000000..b28959b
--- /dev/null
@@ -0,0 +1,3 @@
+This is a red square:
+
+
diff --git a/LayoutTests/platform/chromium/mhtml/page_with_image_unmht-expected.txt b/LayoutTests/platform/chromium/mhtml/page_with_image_unmht-expected.txt
new file mode 100644 (file)
index 0000000..b28959b
--- /dev/null
@@ -0,0 +1,3 @@
+This is a red square:
+
+
diff --git a/LayoutTests/platform/chromium/mhtml/simple_page_ie-expected.txt b/LayoutTests/platform/chromium/mhtml/simple_page_ie-expected.txt
new file mode 100644 (file)
index 0000000..74169e6
--- /dev/null
@@ -0,0 +1,3 @@
+This is a very simple page
+
+Very basic page.
diff --git a/LayoutTests/platform/chromium/mhtml/simple_page_unmht-expected.txt b/LayoutTests/platform/chromium/mhtml/simple_page_unmht-expected.txt
new file mode 100644 (file)
index 0000000..74169e6
--- /dev/null
@@ -0,0 +1,3 @@
+This is a very simple page
+
+Very basic page.
index ea2a555..87a3767 100644 (file)
@@ -19,6 +19,7 @@ SET(WebCore_INCLUDE_DIRECTORIES
     "${WEBCORE_DIR}/loader"
     "${WEBCORE_DIR}/loader/appcache"
     "${WEBCORE_DIR}/loader/archive"
+    "${WEBCORE_DIR}/loader/archive/mhtml"
     "${WEBCORE_DIR}/loader/cache"
     "${WEBCORE_DIR}/loader/icon"
     "${WEBCORE_DIR}/mathml"
@@ -961,6 +962,7 @@ SET(WebCore_SOURCES
     loader/appcache/DOMApplicationCache.cpp
     loader/appcache/ManifestParser.cpp
 
+    loader/archive/Archive.cpp
     loader/archive/ArchiveFactory.cpp
     loader/archive/ArchiveResource.cpp
     loader/archive/ArchiveResourceCollection.cpp
@@ -1163,6 +1165,7 @@ SET(WebCore_SOURCES
     platform/network/FormData.cpp
     platform/network/HTTPHeaderMap.cpp
     platform/network/HTTPParsers.cpp
+    platform/network/MIMEHeader.cpp
     platform/network/NetworkStateNotifier.cpp
     platform/network/ProtectionSpace.cpp
     platform/network/ProxyServer.cpp
@@ -1953,6 +1956,12 @@ IF (ENABLE_MEDIA_STREAM)
     )
 ENDIF ()
 
+IF (ENABLE_MHTML)
+    LIST(APPEND WebCore_SOURCES
+        loader/archive/mhtml/MHTMLArchive.cpp
+        loader/archive/mhtml/MHTMLParser.cpp
+   )
+ENDIF ()
 
 # Modules that the bindings generator scripts may use
 SET(SCRIPTS_BINDINGS
index 38883a8..9bce260 100644 (file)
@@ -1,3 +1,68 @@
+2011-05-24  Jay Civelli  <jcivelli@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Adding MHTML reading support. That required some basic MIME header parsing.
+        Modified DocumentLoader to keep a reference to the currently Archive loaded,
+        so we can have different policies for loading subresources depending on the
+        archive type.
+        https://bugs.webkit.org/show_bug.cgi?id=7168
+
+        * CMakeLists.txt:
+        * Configurations/FeatureDefines.xcconfig:
+        * GNUmakefile.am:
+        * GNUmakefile.list.am:
+        * WebCore.gyp/WebCore.gyp:
+        * WebCore.gypi:
+        * WebCore.pro:
+        * WebCore.vcproj/WebCore.vcproj:
+        * WebCore.xcodeproj/project.pbxproj:
+        * features.pri:
+        * loader/DocumentLoader.cpp:
+        (WebCore::DocumentLoader::commitLoad):
+        (WebCore::DocumentLoader::setupForReplaceByMIMEType):
+        (WebCore::DocumentLoader::popArchiveForSubframe):
+        (WebCore::DocumentLoader::scheduleArchiveLoad):
+        * loader/DocumentLoader.h:
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::loadURLIntoChildFrame):
+        (WebCore::FrameLoader::loadArchive):
+        (WebCore::FrameLoader::stopAllLoaders):
+        (WebCore::FrameLoader::finishedLoadingDocument):
+        * loader/FrameLoader.h:
+        (WebCore::FrameLoader::archive):
+        * loader/MainResourceLoader.cpp:
+        (WebCore::MainResourceLoader::continueAfterContentPolicy):
+        * loader/ResourceLoader.cpp:
+        (WebCore::ResourceLoader::start):
+        * loader/archive/Archive.cpp: Added.
+        * loader/archive/Archive.h:
+        (WebCore::Archive::mainResource):
+        * loader/archive/ArchiveFactory.cpp:
+        (WebCore::archiveFactoryCreate):
+        (WebCore::archiveMIMETypes):
+        (WebCore::ArchiveFactory::create):
+        (WebCore::ArchiveFactory::registerKnownArchiveMIMETypes):
+        * loader/archive/ArchiveFactory.h:
+        * loader/archive/ArchiveResourceCollection.cpp:
+        (WebCore::ArchiveResourceCollection::addAllResources):
+        (WebCore::ArchiveResourceCollection::popSubframeArchive):
+        * loader/archive/ArchiveResourceCollection.h:
+        * loader/archive/cf/LegacyWebArchive.cpp:
+        (WebCore::LegacyWebArchive::create):
+        (WebCore::LegacyWebArchive::type):
+        * loader/archive/cf/LegacyWebArchive.h:
+        * loader/archive/mhtml/MHTMLArchive.cpp: Added.
+        * loader/archive/mhtml/MHTMLArchive.h: Added.
+        * loader/archive/mhtml/MHTMLParser.cpp: Added.
+        * loader/archive/mhtml/MHTMLParser.h: Added.
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::initializeSupportedNonImageMimeTypes):
+        * platform/mac/PasteboardMac.mm:
+        (WebCore::Pasteboard::documentFragment):
+        * platform/network/MIMEHeader.cpp: Added.
+        * platform/network/MIMEHeader.h: Added.
+
 2011-05-24  Geoffrey Garen  <ggaren@apple.com>
 
         Try to fix some builds: #include Weak.h for Weak<T>.
index 911dbe6..a869d6e 100644 (file)
@@ -90,6 +90,7 @@ ENABLE_JAVASCRIPT_DEBUGGER = ENABLE_JAVASCRIPT_DEBUGGER;
 ENABLE_MATHML = ENABLE_MATHML;
 ENABLE_DETAILS = ENABLE_DETAILS;
 ENABLE_METER_TAG = ENABLE_METER_TAG;
+ENABLE_MHTML = ;
 ENABLE_NOTIFICATIONS = ;
 ENABLE_OFFLINE_WEB_APPLICATIONS = ENABLE_OFFLINE_WEB_APPLICATIONS;
 ENABLE_PAGE_VISIBILITY_API = ;
@@ -133,4 +134,4 @@ ENABLE_XHTMLMP = ;
 ENABLE_XPATH = ENABLE_XPATH;
 ENABLE_XSLT = ENABLE_XSLT;
 
-FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_WEBGL) $(ENABLE_3D_RENDERING) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_SYSTEM) $(ENABLE_FULLSCREEN_API) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_QUOTA) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
+FEATURE_DEFINES = $(ENABLE_LINK_PREFETCH) $(ENABLE_ACCELERATED_2D_CANVAS) $(ENABLE_WEBGL) $(ENABLE_3D_RENDERING) $(ENABLE_ANIMATION_API) $(ENABLE_BLOB) $(ENABLE_CHANNEL_MESSAGING) $(ENABLE_CLIENT_BASED_GEOLOCATION) $(ENABLE_DATABASE) $(ENABLE_DATALIST) $(ENABLE_DATA_TRANSFER_ITEMS) $(ENABLE_DETAILS) $(ENABLE_DEVICE_ORIENTATION) $(ENABLE_DIRECTORY_UPLOAD) $(ENABLE_DOM_STORAGE) $(ENABLE_EVENTSOURCE) $(ENABLE_FILTERS) $(ENABLE_FILE_SYSTEM) $(ENABLE_FULLSCREEN_API) $(ENABLE_GEOLOCATION) $(ENABLE_ICONDATABASE) $(ENABLE_INDEXED_DATABASE) $(ENABLE_INPUT_SPEECH) $(ENABLE_JAVASCRIPT_DEBUGGER) $(ENABLE_MATHML) $(ENABLE_METER_TAG) $(ENABLE_MHTML) $(ENABLE_NOTIFICATIONS) $(ENABLE_OFFLINE_WEB_APPLICATIONS) $(ENABLE_PAGE_VISIBILITY_API) $(ENABLE_PROGRESS_TAG) $(ENABLE_REGISTER_PROTOCOL_HANDLER) $(ENABLE_QUOTA) $(ENABLE_SHARED_WORKERS) $(ENABLE_SVG) $(ENABLE_SVG_ANIMATION) $(ENABLE_SVG_AS_IMAGE) $(ENABLE_SVG_DOM_OBJC_BINDINGS) $(ENABLE_SVG_FONTS) $(ENABLE_SVG_FOREIGN_OBJECT) $(ENABLE_SVG_USE) $(ENABLE_TOUCH_ICON_LOADING) $(ENABLE_VIDEO) $(ENABLE_VIDEO_TRACK) $(ENABLE_MEDIA_STATISTICS) $(ENABLE_WEB_AUDIO) $(ENABLE_WEB_SOCKETS) $(ENABLE_WEB_TIMING) $(ENABLE_WORKERS) $(ENABLE_XHTMLMP) $(ENABLE_XPATH) $(ENABLE_XSLT);
index 63994a2..a74877c 100644 (file)
@@ -555,6 +555,14 @@ FEATURE_DEFINES += ENABLE_WEBGL=1
 webcore_cppflags += -DENABLE_WEBGL=1
 endif  # END ENABLE_WEBGL
 
+# ---
+# MHTML support
+# ---
+if ENABLE_MHTML
+FEATURE_DEFINES += ENABLE_MHTML=1
+webcore_cppflags += -DENABLE_MHTML=1
+endif  # END ENABLE_MHTML
+
 
 DerivedSources/WebCore/CSSPropertyNames.cpp: DerivedSources/WebCore/CSSPropertyNames.h
 DerivedSources/WebCore/CSSPropertyNames.h: $(WEBCORE_CSS_PROPERTY_NAMES) $(WebCore)/css/makeprop.pl
index c75796c..8831378 100644 (file)
@@ -2008,6 +2008,7 @@ webcore_sources += \
        Source/WebCore/loader/appcache/ManifestParser.h \
        Source/WebCore/loader/archive/ArchiveFactory.cpp \
        Source/WebCore/loader/archive/ArchiveFactory.h \
+       Source/WebCore/loader/archive/Archive.cpp \
        Source/WebCore/loader/archive/Archive.h \
        Source/WebCore/loader/archive/ArchiveResourceCollection.cpp \
        Source/WebCore/loader/archive/ArchiveResourceCollection.h \
@@ -2552,6 +2553,8 @@ webcore_sources += \
        Source/WebCore/platform/network/BlobResourceHandle.cpp \
        Source/WebCore/platform/network/BlobResourceHandle.h \
        Source/WebCore/platform/network/BlobStorageData.h \
+       Source/WebCore/platform/network/ContentTypeParser.cpp \
+       Source/WebCore/platform/network/ContentTypeParser.h \
        Source/WebCore/platform/network/CookieStorage.h \
        Source/WebCore/platform/network/Credential.cpp \
        Source/WebCore/platform/network/Credential.h \
@@ -2564,6 +2567,8 @@ webcore_sources += \
        Source/WebCore/platform/network/HTTPHeaderMap.h \
        Source/WebCore/platform/network/HTTPParsers.cpp \
        Source/WebCore/platform/network/HTTPParsers.h \
+       Source/WebCore/platform/network/MIMEHeader.cpp \
+       Source/WebCore/platform/network/MIMEHeader.h \
        Source/WebCore/platform/network/NetworkingContext.h \
        Source/WebCore/platform/network/ProxyServer.cpp \
        Source/WebCore/platform/network/ProxyServer.h \
@@ -4625,3 +4630,18 @@ webcore_sources += \
        Source/WebCore/platform/graphics/opengl/Extensions3DOpenGL.h \
        Source/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
 endif  # END ENABLE_WEBGL
+
+# ---
+# MHTML support
+# ---
+if ENABLE_MHTML
+webcore_sources += \
+       Source/WebCore/loader/archive/Archive.cpp \
+       Source/WebCore/loader/archive/Archive.h \
+       Source/WebCore/loader/archive/ArchiveFactory.cpp \
+       Source/WebCore/loader/archive/ArchiveFactory.h \
+       Source/WebCore/loader/archive/mhtml/MHTMLArchive.cpp \
+       Source/WebCore/loader/archive/mhtml/MHTMLArchive.h \
+       Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp \
+       Source/WebCore/loader/archive/mhtml/MHTMLParser.h
+endif  # END ENABLE_MHTML
index 8ee1ae0..013f044 100644 (file)
       '../loader',
       '../loader/appcache',
       '../loader/archive',
+      '../loader/archive/cf',
+      '../loader/archive/mhtml',
       '../loader/cache',
       '../loader/icon',
       '../mathml',
         ['exclude', 'inspector/JavaScript[^/]*\\.cpp$'],
         ['exclude', 'loader/UserStyleSheetLoader\\.cpp$'],
         ['exclude', 'loader/appcache/'],
-        ['exclude', 'loader/archive/ArchiveFactory\\.cpp$'],
         ['exclude', 'loader/archive/cf/LegacyWebArchiveMac\\.mm$'],
         ['exclude', 'loader/archive/cf/LegacyWebArchive\\.cpp$'],
         ['exclude', 'loader/icon/IconDatabase\\.cpp$'],
index 0c3f915..ba6ce31 100644 (file)
             'loader/archive/Archive.h',
             'loader/archive/ArchiveResource.h',
             'loader/archive/cf/LegacyWebArchive.h',
+            'loader/archive/mhtml/MHTMLArchive.h',
+            'loader/archive/mhtml/MHTMLParser.h',
             'loader/cache/CachePolicy.h',
             'loader/cache/CachedImage.h',
             'loader/cache/CachedResource.h',
             'platform/network/CredentialStorage.h',
             'platform/network/FormData.h',
             'platform/network/HTTPHeaderMap.h',
+            'platform/network/MIMEHeader.h',
             'platform/network/NetworkingContext.h',
             'platform/network/ProtectionSpace.h',
             'platform/network/ProtectionSpaceHash.h',
             'platform/text/BidiResolver.h',
             'platform/text/LineEnding.h',
             'platform/text/PlatformString.h',
+            'platform/text/QuotedPrintable.h',
             'platform/text/RegularExpression.h',
             'platform/text/SegmentedString.h',
             'platform/text/TextBoundaries.h',
             'loader/appcache/DOMApplicationCache.h',
             'loader/appcache/ManifestParser.cpp',
             'loader/appcache/ManifestParser.h',
+            'loader/archive/Archive.cpp',
             'loader/archive/ArchiveFactory.cpp',
             'loader/archive/ArchiveFactory.h',
             'loader/archive/ArchiveResource.cpp',
             'loader/archive/ArchiveResourceCollection.h',
             'loader/archive/cf/LegacyWebArchive.cpp',
             'loader/archive/cf/LegacyWebArchiveMac.mm',
+            'loader/archive/mhtml/MHTMLArchive.cpp',
+            'loader/archive/mhtml/MHTMLParser.cpp',
             'loader/cache/CachedCSSStyleSheet.cpp',
             'loader/cache/CachedCSSStyleSheet.h',
             'loader/cache/CachedFont.cpp',
             'platform/network/HTTPHeaderMap.cpp',
             'platform/network/HTTPParsers.cpp',
             'platform/network/HTTPParsers.h',
+            'platform/network/MIMEHeader.cpp',
             'platform/network/NetworkStateNotifier.cpp',
             'platform/network/NetworkStateNotifier.h',
             'platform/network/ProtectionSpace.cpp',
index 814d1a5..c1ab91b 100644 (file)
@@ -1032,6 +1032,7 @@ SOURCES += \
     platform/network/FormDataBuilder.cpp \
     platform/network/HTTPHeaderMap.cpp \
     platform/network/HTTPParsers.cpp \
+    platform/network/MIMEHeader.cpp \
     platform/network/NetworkStateNotifier.cpp \
     platform/network/ProtectionSpace.cpp \
     platform/network/ProxyServer.cpp \
@@ -3480,6 +3481,17 @@ contains(DEFINES, ENABLE_WEBGL=1) {
         INCLUDEPATH += $$PWD/platform/graphics/gpu
 }
 
+contains(DEFINES, ENABLE_MHTML=1) {
+    HEADERS += \
+        loader/archive/Archive.h
+
+    SOURCES += \
+        loader/archive/Archive.cpp \
+        loader/archive/ArchiveFactory.cpp \
+        loader/archive/mhtml/MHTMLArchive.cpp \
+        loader/archive/mhtml/MHTMLParser.cpp
+}
+
 win32:!win32-g++*:contains(QMAKE_HOST.arch, x86_64):{
     asm_compiler.commands = ml64 /c
     asm_compiler.commands +=  /Fo ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN}
index 4ba34f6..3f058b0 100755 (executable)
                                Name="archive"
                                >
                                <File
+                                       RelativePath="..\loader\archive\Archive.cpp"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\loader\archive\Archive.h"
                                        >
                                </File>
                                                >
                                        </File>
                                </Filter>
+                               <Filter
+                                       Name="mhtml"
+                                       >
+                                       <File
+                                               RelativePath="..\loader\archive\mhtml\MHTMLArchive.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\loader\archive\mhtml\MHTMLArchive.h"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\loader\archive\mhtml\MHTMLParser.cpp"
+                                               >
+                                       </File>
+                                       <File
+                                               RelativePath="..\loader\archive\mhtml\MHTMLParser.h"
+                                               >
+                                       </File>
+                               </Filter>
                        </Filter>
                        <Filter
                                Name="cache"
                                        >
                                </File>
                                <File
+                                       RelativePath="..\platform\network\MIMEHeader.cpp"
+                                       >
+                               </File>
+                               <File
+                                       RelativePath="..\platform\network\MIMEHeader.h"
+                                       >
+                               </File>
+                               <File
                                        RelativePath="..\platform\network\NetworkingContext.h"
                                        >
                                </File>
index 247cb21..81ce047 100644 (file)
                33C0CCD4112C5E6200CE057D /* SecureTextInput.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 33C0CCD2112C5E6200CE057D /* SecureTextInput.cpp */; };
                33C0CCD5112C5E6200CE057D /* SecureTextInput.h in Headers */ = {isa = PBXBuildFile; fileRef = 33C0CCD3112C5E6200CE057D /* SecureTextInput.h */; };
                33D0212D131DB37B004091A8 /* CookieStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = E13F01EA1270E10D00DFBA71 /* CookieStorage.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               370D6EDA138454550044103E /* ContentTypeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 370D6ED8138454550044103E /* ContentTypeParser.cpp */; };
+               370D6EDB138454550044103E /* ContentTypeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 370D6ED9138454550044103E /* ContentTypeParser.h */; };
                371A67CB11C6C7DB00047B8B /* HyphenationCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 371A67CA11C6C7DB00047B8B /* HyphenationCF.cpp */; };
                371E65CC13661EDC00BEEDB0 /* PageSerializer.h in Headers */ = {isa = PBXBuildFile; fileRef = 371E65CB13661EDC00BEEDB0 /* PageSerializer.h */; };
                371E65CE13661EED00BEEDB0 /* PageSerializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 371E65CD13661EED00BEEDB0 /* PageSerializer.cpp */; };
                37C238221098C84200EF9F72 /* ComplexTextControllerCoreText.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.cpp */; };
                37C28A6810F659CC008C7813 /* TypesettingFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C28A6710F659CC008C7813 /* TypesettingFeatures.h */; settings = {ATTRIBUTES = (Private, ); }; };
                37C61F0112095C87007A3C67 /* AtomicStringKeyedMRUCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C61F0012095C87007A3C67 /* AtomicStringKeyedMRUCache.h */; };
+               37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */; };
+               37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCD9313844FD50008B793 /* MIMEHeader.h */; };
+               37DDCD9E13844FFA0008B793 /* Archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9D13844FFA0008B793 /* Archive.cpp */; };
+               37DDCDA41384501C0008B793 /* MHTMLArchive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCDA01384501C0008B793 /* MHTMLArchive.cpp */; };
+               37DDCDA51384501C0008B793 /* MHTMLArchive.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCDA11384501C0008B793 /* MHTMLArchive.h */; };
+               37DDCDA61384501C0008B793 /* MHTMLParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCDA21384501C0008B793 /* MHTMLParser.cpp */; };
+               37DDCDA71384501C0008B793 /* MHTMLParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCDA31384501C0008B793 /* MHTMLParser.h */; };
                37E3524B12450C5200BAF5D9 /* InputType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37E3524A12450C5200BAF5D9 /* InputType.cpp */; };
                37E3524D12450C6600BAF5D9 /* InputType.h in Headers */ = {isa = PBXBuildFile; fileRef = 37E3524C12450C6600BAF5D9 /* InputType.h */; settings = {ATTRIBUTES = (Private, ); }; };
                37F818FD0D657606005E1F05 /* WebCoreURLResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 37F818FB0D657606005E1F05 /* WebCoreURLResponse.h */; settings = {ATTRIBUTES = (Private, ); }; };
                ADDF1AD71257CD9A0003A759 /* RenderSVGPath.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */; };
                B1827493134CA4C100B98C2D /* CallbackFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1827492134CA4C100B98C2D /* CallbackFunction.cpp */; };
                B1D5ECB5134B58DA0087C78F /* CallbackFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = B1D5ECB4134B58DA0087C78F /* CallbackFunction.h */; };
+               B1E5457A1346291F0092A545 /* GeneratedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545711346291F0092A545 /* GeneratedStream.cpp */; };
+               B1E5457B1346291F0092A545 /* GeneratedStream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545721346291F0092A545 /* GeneratedStream.h */; };
+               B1E5457D1346291F0092A545 /* Stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545741346291F0092A545 /* Stream.cpp */; };
+               B1E5457E1346291F0092A545 /* Stream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545751346291F0092A545 /* Stream.h */; };
                B1E54593134629C10092A545 /* CallbackTask.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E54587134629C10092A545 /* CallbackTask.h */; };
                B1E54594134629C10092A545 /* MediaStreamClient.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E54588134629C10092A545 /* MediaStreamClient.h */; };
                B1E54595134629C10092A545 /* MediaStreamFrameController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E54589134629C10092A545 /* MediaStreamFrameController.cpp */; };
                B1E54599134629C10092A545 /* NavigatorUserMediaError.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E5458D134629C10092A545 /* NavigatorUserMediaError.h */; };
                B1E5459B134629C10092A545 /* NavigatorUserMediaErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E5458F134629C10092A545 /* NavigatorUserMediaErrorCallback.h */; };
                B1E5459D134629C10092A545 /* NavigatorUserMediaSuccessCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E54591134629C10092A545 /* NavigatorUserMediaSuccessCallback.h */; };
-               B1E5457A1346291F0092A545 /* GeneratedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545711346291F0092A545 /* GeneratedStream.cpp */; };
-               B1E5457B1346291F0092A545 /* GeneratedStream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545721346291F0092A545 /* GeneratedStream.h */; };
-               B1E5457D1346291F0092A545 /* Stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545741346291F0092A545 /* Stream.cpp */; };
-               B1E5457E1346291F0092A545 /* Stream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545751346291F0092A545 /* Stream.h */; };
+               B1E545DD13462B0B0092A545 /* JSGeneratedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545CF13462B0B0092A545 /* JSGeneratedStream.cpp */; };
+               B1E545DE13462B0B0092A545 /* JSGeneratedStream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545D013462B0B0092A545 /* JSGeneratedStream.h */; };
                B1E545DF13462B0B0092A545 /* JSNavigatorUserMediaError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545D113462B0B0092A545 /* JSNavigatorUserMediaError.cpp */; };
                B1E545E013462B0B0092A545 /* JSNavigatorUserMediaError.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545D213462B0B0092A545 /* JSNavigatorUserMediaError.h */; };
                B1E545E113462B0B0092A545 /* JSNavigatorUserMediaErrorCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545D313462B0B0092A545 /* JSNavigatorUserMediaErrorCallback.cpp */; };
                B1E545E213462B0B0092A545 /* JSNavigatorUserMediaErrorCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545D413462B0B0092A545 /* JSNavigatorUserMediaErrorCallback.h */; };
                B1E545E313462B0B0092A545 /* JSNavigatorUserMediaSuccessCallback.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545D513462B0B0092A545 /* JSNavigatorUserMediaSuccessCallback.cpp */; };
                B1E545E413462B0B0092A545 /* JSNavigatorUserMediaSuccessCallback.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545D613462B0B0092A545 /* JSNavigatorUserMediaSuccessCallback.h */; };
-               B1E545DD13462B0B0092A545 /* JSGeneratedStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545CF13462B0B0092A545 /* JSGeneratedStream.cpp */; };
-               B1E545DE13462B0B0092A545 /* JSGeneratedStream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545D013462B0B0092A545 /* JSGeneratedStream.h */; };
                B1E545E513462B0B0092A545 /* JSStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B1E545D713462B0B0092A545 /* JSStream.cpp */; };
                B1E545E613462B0B0092A545 /* JSStream.h in Headers */ = {isa = PBXBuildFile; fileRef = B1E545D813462B0B0092A545 /* JSStream.h */; };
                B20111070AB7740500DB0E68 /* JSSVGAElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B20111050AB7740500DB0E68 /* JSSVGAElement.cpp */; };
                339B5B62131DAA3200F48D02 /* CookiesStrategy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CookiesStrategy.h; sourceTree = "<group>"; };
                33C0CCD2112C5E6200CE057D /* SecureTextInput.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SecureTextInput.cpp; sourceTree = "<group>"; };
                33C0CCD3112C5E6200CE057D /* SecureTextInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecureTextInput.h; sourceTree = "<group>"; };
+               370D6ED8138454550044103E /* ContentTypeParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ContentTypeParser.cpp; sourceTree = "<group>"; };
+               370D6ED9138454550044103E /* ContentTypeParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContentTypeParser.h; sourceTree = "<group>"; };
                371A67CA11C6C7DB00047B8B /* HyphenationCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HyphenationCF.cpp; sourceTree = "<group>"; };
                371E65CB13661EDC00BEEDB0 /* PageSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PageSerializer.h; sourceTree = "<group>"; };
                371E65CD13661EED00BEEDB0 /* PageSerializer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PageSerializer.cpp; sourceTree = "<group>"; };
                37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComplexTextControllerCoreText.cpp; sourceTree = "<group>"; };
                37C28A6710F659CC008C7813 /* TypesettingFeatures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypesettingFeatures.h; sourceTree = "<group>"; };
                37C61F0012095C87007A3C67 /* AtomicStringKeyedMRUCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicStringKeyedMRUCache.h; sourceTree = "<group>"; };
+               37DDCD9213844FD50008B793 /* MIMEHeader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MIMEHeader.cpp; sourceTree = "<group>"; };
+               37DDCD9313844FD50008B793 /* MIMEHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMEHeader.h; sourceTree = "<group>"; };
+               37DDCD9D13844FFA0008B793 /* Archive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Archive.cpp; sourceTree = "<group>"; };
+               37DDCDA01384501C0008B793 /* MHTMLArchive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MHTMLArchive.cpp; sourceTree = "<group>"; };
+               37DDCDA11384501C0008B793 /* MHTMLArchive.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTMLArchive.h; sourceTree = "<group>"; };
+               37DDCDA21384501C0008B793 /* MHTMLParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MHTMLParser.cpp; sourceTree = "<group>"; };
+               37DDCDA31384501C0008B793 /* MHTMLParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MHTMLParser.h; sourceTree = "<group>"; };
                37E3524A12450C5200BAF5D9 /* InputType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InputType.cpp; sourceTree = "<group>"; };
                37E3524C12450C6600BAF5D9 /* InputType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InputType.h; sourceTree = "<group>"; };
                37F818FB0D657606005E1F05 /* WebCoreURLResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebCoreURLResponse.h; sourceTree = "<group>"; };
                ADDF1AD51257CD9A0003A759 /* RenderSVGPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGPath.h; sourceTree = "<group>"; };
                B1827492134CA4C100B98C2D /* CallbackFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CallbackFunction.cpp; sourceTree = "<group>"; };
                B1D5ECB4134B58DA0087C78F /* CallbackFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackFunction.h; sourceTree = "<group>"; };
-               B1E54587134629C10092A545 /* CallbackTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackTask.h; sourceTree = "<group>"; };
-               B1E54588134629C10092A545 /* MediaStreamClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamClient.h; sourceTree = "<group>"; };
-               B1E54589134629C10092A545 /* MediaStreamFrameController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamFrameController.cpp; sourceTree = "<group>"; };
-               B1E5458A134629C10092A545 /* MediaStreamFrameController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamFrameController.h; sourceTree = "<group>"; };
-               B1E5458B134629C10092A545 /* MediaStreamController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamController.cpp; sourceTree = "<group>"; };
-               B1E5458C134629C10092A545 /* MediaStreamController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamController.h; sourceTree = "<group>"; };
                B1E545711346291F0092A545 /* GeneratedStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GeneratedStream.cpp; sourceTree = "<group>"; };
                B1E545721346291F0092A545 /* GeneratedStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GeneratedStream.h; sourceTree = "<group>"; };
                B1E545731346291F0092A545 /* GeneratedStream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = GeneratedStream.idl; sourceTree = "<group>"; };
                B1E545741346291F0092A545 /* Stream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Stream.cpp; sourceTree = "<group>"; };
                B1E545751346291F0092A545 /* Stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Stream.h; sourceTree = "<group>"; };
                B1E545761346291F0092A545 /* Stream.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Stream.idl; sourceTree = "<group>"; };
+               B1E54587134629C10092A545 /* CallbackTask.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackTask.h; sourceTree = "<group>"; };
+               B1E54588134629C10092A545 /* MediaStreamClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamClient.h; sourceTree = "<group>"; };
+               B1E54589134629C10092A545 /* MediaStreamFrameController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamFrameController.cpp; sourceTree = "<group>"; };
+               B1E5458A134629C10092A545 /* MediaStreamFrameController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamFrameController.h; sourceTree = "<group>"; };
+               B1E5458B134629C10092A545 /* MediaStreamController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MediaStreamController.cpp; sourceTree = "<group>"; };
+               B1E5458C134629C10092A545 /* MediaStreamController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MediaStreamController.h; sourceTree = "<group>"; };
                B1E5458D134629C10092A545 /* NavigatorUserMediaError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigatorUserMediaError.h; sourceTree = "<group>"; };
                B1E5458E134629C10092A545 /* NavigatorUserMediaError.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorUserMediaError.idl; sourceTree = "<group>"; };
                B1E5458F134629C10092A545 /* NavigatorUserMediaErrorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigatorUserMediaErrorCallback.h; sourceTree = "<group>"; };
                B1E54592134629C10092A545 /* NavigatorUserMediaSuccessCallback.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NavigatorUserMediaSuccessCallback.idl; sourceTree = "<group>"; };
                B1E545CF13462B0B0092A545 /* JSGeneratedStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGeneratedStream.cpp; sourceTree = "<group>"; };
                B1E545D013462B0B0092A545 /* JSGeneratedStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGeneratedStream.h; sourceTree = "<group>"; };
-               B1E545D713462B0B0092A545 /* JSStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStream.cpp; sourceTree = "<group>"; };
-               B1E545D813462B0B0092A545 /* JSStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStream.h; sourceTree = "<group>"; };
                B1E545D113462B0B0092A545 /* JSNavigatorUserMediaError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNavigatorUserMediaError.cpp; sourceTree = "<group>"; };
                B1E545D213462B0B0092A545 /* JSNavigatorUserMediaError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNavigatorUserMediaError.h; sourceTree = "<group>"; };
                B1E545D313462B0B0092A545 /* JSNavigatorUserMediaErrorCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNavigatorUserMediaErrorCallback.cpp; sourceTree = "<group>"; };
                B1E545D413462B0B0092A545 /* JSNavigatorUserMediaErrorCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNavigatorUserMediaErrorCallback.h; sourceTree = "<group>"; };
                B1E545D513462B0B0092A545 /* JSNavigatorUserMediaSuccessCallback.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSNavigatorUserMediaSuccessCallback.cpp; sourceTree = "<group>"; };
                B1E545D613462B0B0092A545 /* JSNavigatorUserMediaSuccessCallback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSNavigatorUserMediaSuccessCallback.h; sourceTree = "<group>"; };
+               B1E545D713462B0B0092A545 /* JSStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSStream.cpp; sourceTree = "<group>"; };
+               B1E545D813462B0B0092A545 /* JSStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStream.h; sourceTree = "<group>"; };
                B20111050AB7740500DB0E68 /* JSSVGAElement.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSSVGAElement.cpp; sourceTree = "<group>"; };
                B20111060AB7740500DB0E68 /* JSSVGAElement.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSSVGAElement.h; sourceTree = "<group>"; };
                B22277CB0D00BF1F0071B782 /* ColorDistance.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ColorDistance.cpp; sourceTree = "<group>"; };
                        name = Notifications;
                        sourceTree = "<group>";
                };
+               37DDCD9F1384501C0008B793 /* mhtml */ = {
+                       isa = PBXGroup;
+                       children = (
+                               37DDCDA01384501C0008B793 /* MHTMLArchive.cpp */,
+                               37DDCDA11384501C0008B793 /* MHTMLArchive.h */,
+                               37DDCDA21384501C0008B793 /* MHTMLParser.cpp */,
+                               37DDCDA31384501C0008B793 /* MHTMLParser.h */,
+                       );
+                       path = mhtml;
+                       sourceTree = "<group>";
+               };
                4150F9ED12B6E0990008C860 /* shadow */ = {
                        isa = PBXGroup;
                        children = (
                        isa = PBXGroup;
                        children = (
                                512DD8E90D91E6AF000F89EE /* cf */,
+                               37DDCD9F1384501C0008B793 /* mhtml */,
+                               37DDCD9D13844FFA0008B793 /* Archive.cpp */,
                                512DD8EC0D91E6AF000F89EE /* Archive.h */,
                                512DD8F00D91E6AF000F89EE /* ArchiveFactory.cpp */,
                                512DD8F30D91E6AF000F89EE /* ArchiveFactory.h */,
                                2EB4BCD0121F03E300EC4885 /* BlobResourceHandle.cpp */,
                                2EB4BCD1121F03E300EC4885 /* BlobResourceHandle.h */,
                                2EDEF1F2121B0EFC00726DB2 /* BlobStorageData.h */,
+                               370D6ED8138454550044103E /* ContentTypeParser.cpp */,
+                               370D6ED9138454550044103E /* ContentTypeParser.h */,
                                E13F01EA1270E10D00DFBA71 /* CookieStorage.h */,
                                514C76580CE923A1007EF3CD /* Credential.cpp */,
                                514C76590CE923A1007EF3CD /* Credential.h */,
                                514C765C0CE923A1007EF3CD /* HTTPHeaderMap.h */,
                                514C765D0CE923A1007EF3CD /* HTTPParsers.cpp */,
                                514C765E0CE923A1007EF3CD /* HTTPParsers.h */,
+                               37DDCD9213844FD50008B793 /* MIMEHeader.cpp */,
+                               37DDCD9313844FD50008B793 /* MIMEHeader.h */,
                                628D214B12131ED10055DCFC /* NetworkingContext.h */,
                                1A7FA61A0DDA3BBE0028F8A5 /* NetworkStateNotifier.cpp */,
                                1A7FA6180DDA3B3A0028F8A5 /* NetworkStateNotifier.h */,
                                B1E5457E1346291F0092A545 /* Stream.h in Headers */,
                                B1E545DE13462B0B0092A545 /* JSGeneratedStream.h in Headers */,
                                B1E545E613462B0B0092A545 /* JSStream.h in Headers */,
+                               37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */,
+                               37DDCDA51384501C0008B793 /* MHTMLArchive.h in Headers */,
+                               37DDCDA71384501C0008B793 /* MHTMLParser.h in Headers */,
+                               370D6EDB138454550044103E /* ContentTypeParser.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                B1E5457D1346291F0092A545 /* Stream.cpp in Sources */,
                                B1E545DD13462B0B0092A545 /* JSGeneratedStream.cpp in Sources */,
                                B1E545E513462B0B0092A545 /* JSStream.cpp in Sources */,
+                               37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */,
+                               37DDCD9E13844FFA0008B793 /* Archive.cpp in Sources */,
+                               37DDCDA41384501C0008B793 /* MHTMLArchive.cpp in Sources */,
+                               37DDCDA61384501C0008B793 /* MHTMLParser.cpp in Sources */,
+                               370D6EDA138454550044103E /* ContentTypeParser.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index e148cf0..eaba6b7 100644 (file)
@@ -65,6 +65,7 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) {
 !contains(DEFINES, ENABLE_XHTMLMP=.): DEFINES += ENABLE_XHTMLMP=0
 !contains(DEFINES, ENABLE_DETAILS=.): DEFINES += ENABLE_DETAILS=1
 !contains(DEFINES, ENABLE_METER_TAG=.): DEFINES += ENABLE_METER_TAG=1
+#!contains(DEFINES, ENABLE_MHTML=.): DEFINES += ENABLE_MHTML=1
 !contains(DEFINES, ENABLE_PROGRESS_TAG=.): DEFINES += ENABLE_PROGRESS_TAG=1
 !contains(DEFINES, ENABLE_BLOB=.): DEFINES += ENABLE_BLOB=1
 !contains(DEFINES, ENABLE_NOTIFICATIONS=.): DEFINES += ENABLE_NOTIFICATIONS=1
index d9b51c7..2bd4fdb 100644 (file)
@@ -54,7 +54,7 @@
 #include <wtf/text/CString.h>
 #include <wtf/unicode/Unicode.h>
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 #include "ArchiveFactory.h"
 #endif
 
@@ -300,7 +300,7 @@ void DocumentLoader::commitLoad(const char* data, int length)
     FrameLoader* frameLoader = DocumentLoader::frameLoader();
     if (!frameLoader)
         return;
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     if (ArchiveFactory::isArchiveMimeType(response().mimeType()))
         return;
 #endif
@@ -360,7 +360,7 @@ void DocumentLoader::setupForReplaceByMIMEType(const String& newMIMEType)
     
     stopLoadingSubresources();
     stopLoadingPlugIns();
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     clearArchiveResources();
 #endif
 }
@@ -450,7 +450,7 @@ bool DocumentLoader::isLoadingInAPISense() const
     return frameLoader()->subframeIsLoading();
 }
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 void DocumentLoader::addAllArchiveResources(Archive* archive)
 {
     if (!m_archiveResourceCollection)
@@ -477,9 +477,9 @@ void DocumentLoader::addArchiveResource(PassRefPtr<ArchiveResource> resource)
     m_archiveResourceCollection->addResource(resource);
 }
 
-PassRefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName)
+PassRefPtr<Archive> DocumentLoader::popArchiveForSubframe(const String& frameName, const KURL& url)
 {
-    return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName) : PassRefPtr<Archive>(0);
+    return m_archiveResourceCollection ? m_archiveResourceCollection->popSubframeArchive(frameName, url) : PassRefPtr<Archive>(0);
 }
 
 void DocumentLoader::clearArchiveResources()
@@ -497,7 +497,7 @@ SharedBuffer* DocumentLoader::parsedArchiveData() const
 {
     return m_parsedArchiveData.get();
 }
-#endif // ENABLE(WEB_ARCHIVE)
+#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 
 ArchiveResource* DocumentLoader::archiveResourceForURL(const KURL& url) const
 {
@@ -627,26 +627,34 @@ void DocumentLoader::cancelPendingSubstituteLoad(ResourceLoader* loader)
         m_substituteResourceDeliveryTimer.stop();
 }
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 bool DocumentLoader::scheduleArchiveLoad(ResourceLoader* loader, const ResourceRequest& request, const KURL& originalURL)
 {
-    ArchiveResource* resource = 0;
-    
-    if (request.url() == originalURL)
-        resource = archiveResourceForURL(originalURL);
+    if (request.url() == originalURL) {
+        if (ArchiveResource* resource = archiveResourceForURL(originalURL)) {
+            m_pendingSubstituteResources.set(loader, resource);
+            deliverSubstituteResourcesAfterDelay();
+            return true;
+        }
+    }
 
-    if (!resource) {
-        // WebArchiveDebugMode means we fail loads instead of trying to fetch them from the network if they're not in the archive.
-        bool shouldFailLoad = m_frame->settings()->webArchiveDebugModeEnabled() && ArchiveFactory::isArchiveMimeType(responseMIMEType());
+    Archive* archive = frameLoader()->archive();
+    if (!archive)
+        return false;
 
-        if (!shouldFailLoad)
-            return false;
+    switch (archive->type()) {
+#if ENABLE(WEB_ARCHIVE)
+    case Archive::WebArchive:
+        // WebArchiveDebugMode means we fail loads instead of trying to fetch them from the network if they're not in the archive.
+        return m_frame->settings()->webArchiveDebugModeEnabled() && ArchiveFactory::isArchiveMimeType(responseMIMEType());
+#endif
+#if ENABLE(MHTML)
+    case Archive::MHTML:
+        return true; // Always fail the load for resources not included in the MHTML.
+#endif
+    default:
+        return false;
     }
-    
-    m_pendingSubstituteResources.set(loader, resource);
-    deliverSubstituteResourcesAfterDelay();
-    
-    return true;
 }
 #endif // ENABLE(WEB_ARCHIVE)
 
index 14cecc6..f1b01cf 100644 (file)
@@ -47,7 +47,7 @@
 namespace WebCore {
 
     class ApplicationCacheHost;
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     class Archive;
 #endif
     class ArchiveResource;
@@ -132,17 +132,17 @@ namespace WebCore {
         void unschedule(SchedulePair*);
 #endif
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
         void addAllArchiveResources(Archive*);
         void addArchiveResource(PassRefPtr<ArchiveResource>);
         
-        PassRefPtr<Archive> popArchiveForSubframe(const String& frameName);
+        PassRefPtr<Archive> popArchiveForSubframe(const String& frameName, const KURL&);
         void clearArchiveResources();
         void setParsedArchiveData(PassRefPtr<SharedBuffer>);
         SharedBuffer* parsedArchiveData() const;
         
         bool scheduleArchiveLoad(ResourceLoader*, const ResourceRequest&, const KURL&);
-#endif // ENABLE(WEB_ARCHIVE)
+#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 
         // Return the ArchiveResource for the URL only when loading an Archive
         ArchiveResource* archiveResourceForURL(const KURL&) const;
@@ -324,7 +324,7 @@ namespace WebCore {
         Timer<DocumentLoader> m_substituteResourceDeliveryTimer;
 
         OwnPtr<ArchiveResourceCollection> m_archiveResourceCollection;
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
         RefPtr<SharedBuffer> m_parsedArchiveData;
 #endif
 
index a6e6a95..94fe952 100644 (file)
 #include "SVGViewSpec.h"
 #endif
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 #include "Archive.h"
 #include "ArchiveFactory.h"
 #endif
@@ -996,8 +996,8 @@ void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer,
 {
     ASSERT(childFrame);
 
-#if ENABLE(WEB_ARCHIVE)
-    RefPtr<Archive> subframeArchive = activeDocumentLoader()->popArchiveForSubframe(childFrame->tree()->uniqueName());    
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
+    RefPtr<Archive> subframeArchive = activeDocumentLoader()->popArchiveForSubframe(childFrame->tree()->uniqueName(), url);    
     if (subframeArchive) {
         childFrame->loader()->loadArchive(subframeArchive.release());
         return;
@@ -1018,12 +1018,12 @@ void FrameLoader::loadURLIntoChildFrame(const KURL& url, const String& referer,
     childFrame->loader()->loadURL(url, referer, String(), false, FrameLoadTypeRedirectWithLockedBackForwardList, 0, 0);
 }
 
-#if ENABLE(WEB_ARCHIVE)
-void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
+void FrameLoader::loadArchive(PassRefPtr<Archive> archive)
 {
-    RefPtr<Archive> archive = prpArchive;
+    m_archive = archive;
     
-    ArchiveResource* mainResource = archive->mainResource();
+    ArchiveResource* mainResource = m_archive->mainResource();
     ASSERT(mainResource);
     if (!mainResource)
         return;
@@ -1036,10 +1036,10 @@ void FrameLoader::loadArchive(PassRefPtr<Archive> prpArchive)
 #endif
 
     RefPtr<DocumentLoader> documentLoader = m_client->createDocumentLoader(request, substituteData);
-    documentLoader->addAllArchiveResources(archive.get());
+    documentLoader->addAllArchiveResources(m_archive.get());
     load(documentLoader.get());
 }
-#endif // ENABLE(WEB_ARCHIVE)
+#endif // ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 
 ObjectContentType FrameLoader::defaultObjectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
 {
@@ -1807,7 +1807,7 @@ void FrameLoader::stopAllLoaders(ClearProvisionalItemPolicy clearProvisionalItem
 
     setProvisionalDocumentLoader(0);
     
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     if (m_documentLoader)
         m_documentLoader->clearArchiveResources();
 #endif
@@ -2321,21 +2321,21 @@ void FrameLoader::finishedLoadingDocument(DocumentLoader* loader)
         return;
 #endif
 
-#if !ENABLE(WEB_ARCHIVE)
+#if !ENABLE(WEB_ARCHIVE) && !ENABLE(MHTML)
     m_client->finishedLoading(loader);
 #else
     // Give archive machinery a crack at this document. If the MIME type is not an archive type, it will return 0.
-    RefPtr<Archive> archive = ArchiveFactory::create(loader->mainResourceData().get(), loader->responseMIMEType());
-    if (!archive) {
+    m_archive = ArchiveFactory::create(loader->response().url(), loader->mainResourceData().get(), loader->responseMIMEType());
+    if (!m_archive) {
         m_client->finishedLoading(loader);
         return;
     }
 
     // FIXME: The remainder of this function should be moved to DocumentLoader.
 
-    loader->addAllArchiveResources(archive.get());
+    loader->addAllArchiveResources(m_archive.get());
 
-    ArchiveResource* mainResource = archive->mainResource();
+    ArchiveResource* mainResource = m_archive->mainResource();
     loader->setParsedArchiveData(mainResource->data());
 
     loader->writer()->setMIMEType(mainResource->mimeType());
index f2b16d9..9e2b838 100644 (file)
@@ -120,7 +120,7 @@ public:
     void load(const ResourceRequest&, const SubstituteData&, bool lockHistory);                 // Called both by WebFrame and internally, calls load(DocumentLoader*).
     void load(const ResourceRequest&, const String& frameName, bool lockHistory);               // Called by WebPluginController.
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     void loadArchive(PassRefPtr<Archive>);
 #endif
 
@@ -343,6 +343,10 @@ public:
 
     NetworkingContext* networkingContext() const;
 
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
+    Archive* archive() const { return m_archive.get(); }
+#endif
+
 private:
     void checkTimerFired(Timer<FrameLoader>*);
     
@@ -499,6 +503,10 @@ private:
 
     RefPtr<FrameNetworkingContext> m_networkingContext;
 
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
+    RefPtr<Archive> m_archive;
+#endif
+
     KURL m_previousUrl;
 };
 
index 5478708..feafa76 100644 (file)
@@ -256,7 +256,8 @@ void MainResourceLoader::continueAfterContentPolicy(PolicyAction contentPolicy,
     switch (contentPolicy) {
     case PolicyUse: {
         // Prevent remote web archives from loading because they can claim to be from any domain and thus avoid cross-domain security checks (4120255).
-        bool isRemoteWebArchive = equalIgnoringCase("application/x-webarchive", mimeType) && !m_substituteData.isValid() && !url.isLocalFile();
+        bool isRemoteWebArchive = (equalIgnoringCase("application/x-webarchive", mimeType) || equalIgnoringCase("multipart/related", mimeType))
+            && !m_substituteData.isValid() && !url.isLocalFile();
         if (!frameLoader()->canShowMIMEType(mimeType) || isRemoteWebArchive) {
             frameLoader()->policyChecker()->cannotShowMIMEType(r);
             // Check reachedTerminalState since the load may have already been cancelled inside of _handleUnimplementablePolicyWithErrorCode::.
index ce2e446..5c3d39a 100644 (file)
@@ -146,7 +146,7 @@ void ResourceLoader::start()
     ASSERT(!m_request.isNull());
     ASSERT(m_deferredRequest.isNull());
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     if (m_documentLoader->scheduleArchiveLoad(this, m_request, m_request.url()))
         return;
 #endif
diff --git a/Source/WebCore/loader/archive/Archive.cpp b/Source/WebCore/loader/archive/Archive.cpp
new file mode 100644 (file)
index 0000000..8f45fbd
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Archive.h"
+
+namespace WebCore {
+
+Archive::~Archive()
+{
+}
+
+}
index af3d8b1..d41c608 100644 (file)
 namespace WebCore {
 
 class Archive : public RefCounted<Archive> {
-public:    
-    ArchiveResource* mainResource() { return m_mainResource.get(); }    
+public:
+    enum Type {
+      WebArchive,
+      MHTML
+    };
+    virtual ~Archive();
+    virtual Type type() const = 0;
+    ArchiveResource* mainResource() { return m_mainResource.get(); }
     const Vector<RefPtr<ArchiveResource> >& subresources() const { return m_subresources; }
     const Vector<RefPtr<Archive> >& subframeArchives() const { return m_subframeArchives; }
 
index 19dc357..521deb1 100644 (file)
 #include "MIMETypeRegistry.h"
 #include "PlatformString.h"
 
-#if USE(CF) && !PLATFORM(QT)
+#if USE(CF) && !PLATFORM(QT) && ENABLE(WEB_ARCHIVE)
 #include "LegacyWebArchive.h"
 #endif
+#if ENABLE(MHTML)
+#include "MHTMLArchive.h"
+#endif
 
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 
 namespace WebCore {
 
-typedef PassRefPtr<Archive> RawDataCreationFunction(SharedBuffer*);
+typedef PassRefPtr<Archive> RawDataCreationFunction(const KURL&, SharedBuffer*);
 typedef HashMap<String, RawDataCreationFunction*, CaseFoldingHash> ArchiveMIMETypesMap;
 
 // The create functions in the archive classes return PassRefPtr to concrete subclasses
 // of Archive. This adaptor makes the functions have a uniform return type.
-template <typename ArchiveClass> static PassRefPtr<Archive> archiveFactoryCreate(SharedBuffer* buffer)
+template <typename ArchiveClass> static PassRefPtr<Archive> archiveFactoryCreate(const KURL& url, SharedBuffer* buffer)
 {
-    return ArchiveClass::create(buffer);
+    return ArchiveClass::create(url, buffer);
 }
 
 static ArchiveMIMETypesMap& archiveMIMETypes()
@@ -60,9 +63,12 @@ static ArchiveMIMETypesMap& archiveMIMETypes()
     if (initialized)
         return mimeTypes;
 
-#if USE(CF)
+#if ENABLE(WEB_ARCHIVE) && USE(CF)
     mimeTypes.set("application/x-webarchive", archiveFactoryCreate<LegacyWebArchive>);
 #endif
+#if ENABLE(MHTML)
+    mimeTypes.set("multipart/related", archiveFactoryCreate<MHTMLArchive>);
+#endif
 
     initialized = true;
     return mimeTypes;
@@ -73,10 +79,10 @@ bool ArchiveFactory::isArchiveMimeType(const String& mimeType)
     return !mimeType.isEmpty() && archiveMIMETypes().contains(mimeType);
 }
 
-PassRefPtr<Archive> ArchiveFactory::create(SharedBuffer* data, const String& mimeType)
+PassRefPtr<Archive> ArchiveFactory::create(const KURL& url, SharedBuffer* data, const String& mimeType)
 {
     RawDataCreationFunction* function = mimeType.isEmpty() ? 0 : archiveMIMETypes().get(mimeType);
-    return function ? function(data) : PassRefPtr<Archive>(0);
+    return function ? function(url, data) : PassRefPtr<Archive>(0);
 }
 
 void ArchiveFactory::registerKnownArchiveMIMETypes()
@@ -84,7 +90,7 @@ void ArchiveFactory::registerKnownArchiveMIMETypes()
     HashSet<String>& mimeTypes = MIMETypeRegistry::getSupportedNonImageMIMETypes();
     ArchiveMIMETypesMap::iterator i = archiveMIMETypes().begin();
     ArchiveMIMETypesMap::iterator end = archiveMIMETypes().end();
-    
+
     for (; i != end; ++i)
         mimeTypes.add(i->first);
 }
index c3b9464..d0405ca 100644 (file)
@@ -41,7 +41,7 @@ class SharedBuffer;
 class ArchiveFactory {
 public:
     static bool isArchiveMimeType(const String&);
-    static PassRefPtr<Archive> create(SharedBuffer* data, const String& mimeType);
+    static PassRefPtr<Archive> create(const KURL&, SharedBuffer* data, const String& mimeType);
     static void registerKnownArchiveMIMETypes();
 };
 
index 6eb1237..cdd8358 100644 (file)
@@ -40,26 +40,26 @@ void ArchiveResourceCollection::addAllResources(Archive* archive)
     ASSERT(archive);
     if (!archive)
         return;
-    
+
     const Vector<RefPtr<ArchiveResource> >& subresources = archive->subresources();
-    Vector<RefPtr<ArchiveResource> >::const_iterator iRes = subresources.begin();
-    Vector<RefPtr<ArchiveResource> >::const_iterator endRes = subresources.end();
-    
-    for (; iRes != endRes; ++iRes)
-        m_subresources.set((*iRes)->url(), iRes->get());
+    for (Vector<RefPtr<ArchiveResource> >::const_iterator iterator = subresources.begin(); iterator != subresources.end(); ++iterator)
+        m_subresources.set((*iterator)->url(), iterator->get());
 
     const Vector<RefPtr<Archive> >& subframes = archive->subframeArchives();
-    Vector<RefPtr<Archive> >::const_iterator iFrame = subframes.begin();
-    Vector<RefPtr<Archive> >::const_iterator endFrame = subframes.end();
-        
-    for (; iFrame != endFrame; ++iFrame) {        
-        ASSERT((*iFrame)->mainResource());
-        const String& frameName = (*iFrame)->mainResource()->frameName();
+    for (Vector<RefPtr<Archive> >::const_iterator iterator = subframes.begin(); iterator != subframes.end(); ++iterator) {
+        RefPtr<Archive> archive = *iterator;
+        ASSERT(archive->mainResource());
+
+        const String& frameName = archive->mainResource()->frameName();
         if (!frameName.isNull())
-            m_subframes.set(frameName, iFrame->get());
+            m_subframes.set(frameName, archive.get());
+        else {
+            // In the MHTML case, frames don't have a name so we use the URL instead.
+            m_subframes.set(archive->mainResource()->url().string(), archive.get());
+        }
     }
 }
-    
+
 // FIXME: Adding a resource directly to a DocumentLoader/ArchiveResourceCollection seems like bad design, but is API some apps rely on.
 // Can we change the design in a manner that will let us deprecate that API without reducing functionality of those apps?
 void ArchiveResourceCollection::addResource(PassRefPtr<ArchiveResource> resource)
@@ -81,9 +81,13 @@ ArchiveResource* ArchiveResourceCollection::archiveResourceForURL(const KURL& ur
     return resource;
 }
 
-PassRefPtr<Archive> ArchiveResourceCollection::popSubframeArchive(const String& frameName)
+PassRefPtr<Archive> ArchiveResourceCollection::popSubframeArchive(const String& frameName, const KURL& url)
 {
-    return m_subframes.take(frameName);
+    RefPtr<Archive> archive = m_subframes.take(frameName);
+    if (archive)
+        return archive.release();
+
+    return m_subframes.take(url.string());
 }
 
 }
index fd2ddbf..b4912b5 100644 (file)
@@ -48,7 +48,7 @@ public:
     void addAllResources(Archive*);
     
     ArchiveResource* archiveResourceForURL(const KURL&);
-    PassRefPtr<Archive> popSubframeArchive(const String& frameName);
+    PassRefPtr<Archive> popSubframeArchive(const String& frameName, const KURL&);
     
 private:    
     HashMap<String, RefPtr<ArchiveResource> > m_subresources;
index 5897cf4..6145dae 100644 (file)
@@ -262,6 +262,11 @@ PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(PassRefPtr<ArchiveResource
 
 PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(SharedBuffer* data)
 {
+    return create(KURL(), data);
+}
+
+PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(const KURL&, SharedBuffer* data)
+{
     LOG(Archives, "LegacyWebArchive - Creating from raw data");
     
     RefPtr<LegacyWebArchive> archive = create();
@@ -366,6 +371,11 @@ bool LegacyWebArchive::extract(CFDictionaryRef dictionary)
     return true;
 }
 
+Archive::Type LegacyWebArchive::type() const
+{
+    return Archive::WebArchive;
+}
+    
 RetainPtr<CFDataRef> LegacyWebArchive::rawDataRepresentation()
 {
     RetainPtr<CFDictionaryRef> propertyList = createPropertyListRepresentation(this);
index 8c8f2e4..ee19ea6 100644 (file)
@@ -41,12 +41,15 @@ class LegacyWebArchive : public Archive {
 public:
     static PassRefPtr<LegacyWebArchive> create();
     static PassRefPtr<LegacyWebArchive> create(SharedBuffer*);
+    static PassRefPtr<LegacyWebArchive> create(const KURL&, SharedBuffer*);
     static PassRefPtr<LegacyWebArchive> create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives);
     static PassRefPtr<LegacyWebArchive> create(Node*);
     static PassRefPtr<LegacyWebArchive> create(Frame*);
     static PassRefPtr<LegacyWebArchive> createFromSelection(Frame*);
     static PassRefPtr<LegacyWebArchive> create(Range*);
 
+    virtual Type type() const;
+
     RetainPtr<CFDataRef> rawDataRepresentation();
 
 private:
diff --git a/Source/WebCore/loader/archive/mhtml/MHTMLArchive.cpp b/Source/WebCore/loader/archive/mhtml/MHTMLArchive.cpp
new file mode 100644 (file)
index 0000000..8dce639
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MHTML)
+#include "MHTMLArchive.h"
+
+#include "MHTMLParser.h"
+#include "MIMEHeader.h"
+
+namespace WebCore {
+
+MHTMLArchive::MHTMLArchive()
+{
+}
+
+PassRefPtr<MHTMLArchive> MHTMLArchive::create()
+{
+    return adoptRef(new MHTMLArchive);
+}
+
+PassRefPtr<MHTMLArchive> MHTMLArchive::create(const KURL& url, SharedBuffer* data)
+{
+    // For security reasons we only load MHTML pages from the local file system.
+    if (!url.isLocalFile())
+        return false;
+
+    MHTMLParser parser(data);
+    RefPtr<MHTMLArchive> mainArchive = parser.parseArchive();
+    if (!mainArchive)
+        return 0; // Invalid MHTML file.
+
+    // Since MHTML is a flat format, we need to make all frames aware of all resources.
+    for (size_t i = 0; i < parser.frameCount(); ++i) {
+        RefPtr<MHTMLArchive> archive = parser.frameAt(i);
+        for (size_t j = 0; j < parser.frameCount(); ++j) {
+            if (i != j)
+                archive->addSubframeArchive(parser.frameAt(j));
+        }
+        for (size_t j = 0; j < parser.subResourceCount(); ++j)
+            archive->addSubresource(parser.subResourceAt(j));
+    }
+    return mainArchive.release();
+}
+
+}
+#endif
diff --git a/Source/WebCore/loader/archive/mhtml/MHTMLArchive.h b/Source/WebCore/loader/archive/mhtml/MHTMLArchive.h
new file mode 100644 (file)
index 0000000..1b31dc3
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MHTMLArchive_h
+#define MHTMLArchive_h
+
+#if ENABLE(MHTML)
+
+#include "Archive.h"
+
+namespace WebCore {
+
+class MHTMLParser;
+
+class MHTMLArchive : public Archive {
+public:
+    virtual Type type() const { return MHTML; }
+
+    static PassRefPtr<MHTMLArchive> create();
+    static PassRefPtr<MHTMLArchive> create(const KURL&, SharedBuffer*);
+
+private:
+    friend class MHTMLParser;
+    MHTMLArchive();
+};
+
+}
+
+#endif
+#endif
diff --git a/Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp b/Source/WebCore/loader/archive/mhtml/MHTMLParser.cpp
new file mode 100644 (file)
index 0000000..83102cb
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(MHTML)
+#include "MHTMLParser.h"
+
+#include "Base64.h"
+#include "MHTMLArchive.h"
+#include "MIMEHeader.h"
+#include "MIMETypeRegistry.h"
+#include "QuotedPrintable.h"
+#include <wtf/HashMap.h>
+#include <wtf/NotFound.h>
+
+namespace WebCore {
+
+static bool skipLinesUntilBoundaryFound(SharedBufferCRLFLineReader& lineReader, const String& boundary)
+{
+    String line;
+    while (!(line = lineReader.nextLine()).isNull()) {
+        if (line == boundary)
+            return true;
+    }
+    return false;
+}
+
+MHTMLParser::MHTMLParser(SharedBuffer* data)
+    : m_lineReader(data)
+{
+}
+
+PassRefPtr<MHTMLArchive> MHTMLParser::parseArchive()
+{
+    RefPtr<MIMEHeader> header = MIMEHeader::parseHeader(&m_lineReader);
+    return parseArchiveWithHeader(header.get());
+}
+
+PassRefPtr<MHTMLArchive> MHTMLParser::parseArchiveWithHeader(MIMEHeader* header)
+{
+    if (!header) {
+        LOG_ERROR("Failed to parse MHTML part: no header.");
+        return 0;
+    }
+
+    RefPtr<MHTMLArchive> archive = MHTMLArchive::create();
+    if (!header->isMultipart()) {
+        // With IE a page with no resource is not multi-part.
+        bool endOfArchiveReached = false;
+        RefPtr<ArchiveResource> resource = parseNextPart(*header, String(), String(), endOfArchiveReached);
+        if (!resource)
+            return 0;
+        archive->setMainResource(resource);
+        return archive;
+    }
+
+    // Skip the message content (it's a generic browser specific message).
+    skipLinesUntilBoundaryFound(m_lineReader, header->endOfPartBoundary());
+
+    bool endOfArchive = false;
+    while (!endOfArchive) {
+        RefPtr<MIMEHeader> resourceHeader = MIMEHeader::parseHeader(&m_lineReader);
+        if (!resourceHeader) {
+            LOG_ERROR("Failed to parse MHTML, invalid MIME header.");
+            return 0;
+        }
+        if (resourceHeader->contentType() == "multipart/alternative") {
+            // Ignore IE nesting which makes little sense (IE seems to nest only some of the frames).
+            RefPtr<MHTMLArchive> subframeArchive = parseArchiveWithHeader(resourceHeader.get());
+            if (!subframeArchive) {
+                LOG_ERROR("Failed to parse MHTML subframe.");
+                return 0;
+            }
+            bool endOfPartReached = skipLinesUntilBoundaryFound(m_lineReader, header->endOfPartBoundary());
+            ASSERT_UNUSED(endOfPartReached, endOfPartReached);
+            // The top-frame is the first frame found, regardless of the nesting level.
+            if (subframeArchive->mainResource())
+                addResourceToArchive(subframeArchive->mainResource(), archive.get());
+            archive->addSubframeArchive(subframeArchive);
+            continue;
+        }
+
+        RefPtr<ArchiveResource> resource = parseNextPart(*resourceHeader, header->endOfPartBoundary(), header->endOfDocumentBoundary(), endOfArchive);
+        if (!resource) {
+            LOG_ERROR("Failed to parse MHTML part.");
+            return 0;
+        }
+        addResourceToArchive(resource.get(), archive.get());
+    }
+
+    return archive.release();
+}
+
+void MHTMLParser::addResourceToArchive(ArchiveResource* resource, MHTMLArchive* archive)
+{
+    const String& mimeType = resource->mimeType();
+    if (!MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType) || MIMETypeRegistry::isSupportedJavaScriptMIMEType(mimeType) || mimeType == "text/css") {
+        m_resources.append(resource);
+        return;
+    }
+
+    // The first document suitable resource is the main frame.
+    if (!archive->mainResource()) {
+        archive->setMainResource(resource);
+        m_frames.append(archive);
+        return;
+    }
+
+    RefPtr<MHTMLArchive> subframe = MHTMLArchive::create();
+    subframe->setMainResource(resource);
+    m_frames.append(subframe);
+}
+
+PassRefPtr<ArchiveResource> MHTMLParser::parseNextPart(const MIMEHeader& mimeHeader, const String& endOfPartBoundary, const String& endOfDocumentBoundary, bool& endOfArchiveReached)
+{
+    ASSERT(endOfPartBoundary.isEmpty() == endOfDocumentBoundary.isEmpty());
+
+    RefPtr<SharedBuffer> content = SharedBuffer::create();
+    const bool checkBoundary = !endOfPartBoundary.isEmpty();
+    bool endOfPartReached = false;
+    String line;
+    while (!(line = m_lineReader.nextLine()).isNull()) {
+        if (checkBoundary && (line == endOfPartBoundary || line == endOfDocumentBoundary)) {
+            endOfArchiveReached = (line == endOfDocumentBoundary);
+            endOfPartReached = true;
+            break;
+        }
+        // Note that we use line.utf8() and not line.ascii() as ascii turns special characters (such as tab, line-feed...) into '?'.
+        content->append(line.utf8().data(), line.length());
+        if (mimeHeader.contentTransferEncoding() == MIMEHeader::QuotedPrintable) {
+            // The line reader removes the \r\n, but we need them for the content in this case as the QuotedPrintable decoder expects CR-LF terminated lines.
+            content->append("\r\n", 2);
+        }
+    }
+    if (!endOfPartReached && checkBoundary) {
+        LOG_ERROR("No bounday found for MHTML part.");
+        return 0;
+    }
+
+    Vector<char> data;
+    switch (mimeHeader.contentTransferEncoding()) {
+    case MIMEHeader::Base64:
+        if (!base64Decode(content->data(), content->size(), data)) {
+            LOG_ERROR("Invalid base64 content for MHTML part.");
+            return 0;
+        }
+        break;
+    case MIMEHeader::QuotedPrintable:
+        quotedPrintableDecode(content->data(), content->size(), data);
+        break;
+    case MIMEHeader::SevenBit:
+        data.append(content->data(), content->size());
+        break;
+    default:
+        LOG_ERROR("Invalid encoding for MHTML part.");
+        return 0;
+    }
+    RefPtr<SharedBuffer> contentBuffer = SharedBuffer::adoptVector(data);
+    // FIXME: the URL in the MIME header could be relative, we should resolve it if it is.
+    // The specs mentions 5 ways to resolve a URL: http://tools.ietf.org/html/rfc2557#section-5
+    // IE and Firefox (UNMht) seem to generate only absolute URLs.
+    KURL location = KURL(KURL(), mimeHeader.contentLocation());
+    return ArchiveResource::create(contentBuffer, location, mimeHeader.contentType(), mimeHeader.charset(), String());
+}
+
+size_t MHTMLParser::frameCount() const
+{
+    return m_frames.size();
+}
+
+MHTMLArchive* MHTMLParser::frameAt(size_t index) const
+{
+    return m_frames[index].get();
+}
+
+size_t MHTMLParser::subResourceCount() const
+{
+    return m_resources.size();
+}
+
+ArchiveResource* MHTMLParser::subResourceAt(size_t index) const
+{
+    return m_resources[index].get();
+}
+
+}
+#endif
diff --git a/Source/WebCore/loader/archive/mhtml/MHTMLParser.h b/Source/WebCore/loader/archive/mhtml/MHTMLParser.h
new file mode 100644 (file)
index 0000000..5026029
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MHTMLParser_h
+#define MHTMLParser_h
+
+#if ENABLE(MHTML)
+#include "SharedBufferCRLFLineReader.h"
+#include <wtf/RefPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class ArchiveResource;
+class MHTMLArchive;
+class MIMEHeader;
+class SharedBuffer;
+
+class MHTMLParser {
+public:
+    explicit MHTMLParser(SharedBuffer*);
+
+    PassRefPtr<MHTMLArchive> parseArchive();
+
+    size_t frameCount() const;
+    MHTMLArchive* frameAt(size_t) const;
+
+    size_t subResourceCount() const;
+    ArchiveResource* subResourceAt(size_t) const;
+
+private:
+    PassRefPtr<MHTMLArchive> parseArchiveWithHeader(MIMEHeader*);
+    PassRefPtr<ArchiveResource> parseNextPart(const MIMEHeader&, const String& endOfPartBoundary, const String& endOfDocumentBoundary, bool& endOfArchiveReached);
+
+    void addResourceToArchive(ArchiveResource*, MHTMLArchive*);
+
+    SharedBufferCRLFLineReader m_lineReader;
+    Vector<RefPtr<ArchiveResource> > m_resources;
+    Vector<RefPtr<MHTMLArchive> > m_frames;
+};
+
+}
+
+#endif
+#endif
+
index c8fee4f..c3bbe82 100644 (file)
@@ -43,7 +43,7 @@
 #include <qimagewriter.h>
 #endif
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
 #include "ArchiveFactory.h"
 #endif
 
@@ -225,7 +225,7 @@ static void initializeSupportedNonImageMimeTypes()
     for (size_t i = 0; i < WTF_ARRAY_LENGTH(types); ++i)
         supportedNonImageMIMETypes->add(types[i]);
 
-#if ENABLE(WEB_ARCHIVE)
+#if ENABLE(WEB_ARCHIVE) || ENABLE(MHTML)
     ArchiveFactory::registerKnownArchiveMIMETypes();
 #endif
 }
index 191efd5..216acf0 100644 (file)
@@ -479,7 +479,7 @@ PassRefPtr<DocumentFragment> Pasteboard::documentFragment(Frame* frame, PassRefP
     chosePlainText = false;
 
     if ([types containsObject:WebArchivePboardType]) {
-        RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData([m_pasteboard.get() dataForType:WebArchivePboardType]).get());
+        RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(KURL(), SharedBuffer::wrapNSData([m_pasteboard.get() dataForType:WebArchivePboardType]).get());
         if (coreArchive) {
             RefPtr<ArchiveResource> mainResource = coreArchive->mainResource();
             if (mainResource) {
diff --git a/Source/WebCore/platform/network/MIMEHeader.cpp b/Source/WebCore/platform/network/MIMEHeader.cpp
new file mode 100644 (file)
index 0000000..88bfaaa
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "MIMEHeader.h"
+
+#include "ContentTypeParser.h"
+#include "SharedBufferCRLFLineReader.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
+#include <wtf/text/StringConcatenate.h>
+#include <wtf/text/StringHash.h>
+
+namespace WebCore {
+
+typedef HashMap<String, String> KeyValueMap;
+
+static KeyValueMap retrieveKeyValuePairs(WebCore::SharedBufferCRLFLineReader* buffer)
+{
+    KeyValueMap keyValuePairs;
+    String line;
+    String key;
+    StringBuilder value;
+    while (!(line = buffer->nextLine()).isNull()) {
+        if (line.isEmpty())
+            break; // Empty line means end of key/value section.
+        if (line[0] == '\t') {
+            ASSERT(!key.isEmpty());
+            value.append(line.substring(1));
+            continue;
+        }
+        // New key/value, store the previous one if any.
+        if (!key.isEmpty()) {
+            if (keyValuePairs.find(key) != keyValuePairs.end())
+                LOG_ERROR("Key duplicate found in MIME header. Key is '%s', previous value replaced.", key.ascii().data());
+            keyValuePairs.add(key, value.toString().stripWhiteSpace());
+            key = String();
+            value.clear();
+        }
+        size_t semiColonIndex = line.find(':');
+        if (semiColonIndex == notFound) {
+            // This is not a key value pair, ignore.
+            continue;
+        }
+        key = line.substring(0, semiColonIndex).lower().stripWhiteSpace();
+        value.append(line.substring(semiColonIndex + 1));
+    }
+    // Store the last property if there is one.
+    if (!key.isEmpty())
+        keyValuePairs.set(key, value.toString().stripWhiteSpace());
+    return keyValuePairs;
+}
+
+PassRefPtr<MIMEHeader> MIMEHeader::parseHeader(SharedBufferCRLFLineReader* buffer)
+{
+    RefPtr<MIMEHeader> mimeHeader = adoptRef(new MIMEHeader);
+    KeyValueMap keyValuePairs = retrieveKeyValuePairs(buffer);
+    KeyValueMap::iterator mimeParametersIterator = keyValuePairs.find("content-type");
+    if (mimeParametersIterator != keyValuePairs.end()) {
+        // FIXME: make ContentTypeParser more flexible so we don't have to synthesize the "Content-Type:".
+        ContentTypeParser contentTypeParser(makeString("Content-Type:", mimeParametersIterator->second));
+        mimeHeader->m_contentType = contentTypeParser.mimeType();
+        if (!mimeHeader->isMultipart())
+            mimeHeader->m_charset = contentTypeParser.charset().stripWhiteSpace();
+        else {
+            mimeHeader->m_multipartType = contentTypeParser.parameterValueForName("type");
+            mimeHeader->m_endOfPartBoundary = contentTypeParser.parameterValueForName("boundary");
+            if (mimeHeader->m_endOfPartBoundary.isNull()) {
+                LOG_ERROR("No boundary found in multipart MIME header.");
+                return 0;
+            }
+            mimeHeader->m_endOfPartBoundary.insert("--", 0);
+            mimeHeader->m_endOfDocumentBoundary = mimeHeader->m_endOfPartBoundary;
+            mimeHeader->m_endOfDocumentBoundary.append("--");
+        }
+    }
+
+    mimeParametersIterator = keyValuePairs.find("content-transfer-encoding");
+    if (mimeParametersIterator != keyValuePairs.end())
+        mimeHeader->m_contentTransferEncoding = parseContentTransferEncoding(mimeParametersIterator->second);
+
+    mimeParametersIterator = keyValuePairs.find("content-location");
+    if (mimeParametersIterator != keyValuePairs.end())
+        mimeHeader->m_contentLocation = mimeParametersIterator->second;
+
+    return mimeHeader.release();
+}
+
+MIMEHeader::Encoding MIMEHeader::parseContentTransferEncoding(const String& text)
+{
+    String encoding = text.stripWhiteSpace().lower();
+    if (encoding == "base64")
+        return Base64;
+    if (encoding == "quoted-printable")
+        return QuotedPrintable;
+    if (encoding == "7bit")
+        return SevenBit;
+    LOG_ERROR("Unknown encoding '%s' found in MIME header.", text.ascii().data());
+    return Unknown;
+}
+
+MIMEHeader::MIMEHeader()
+    : m_contentTransferEncoding(Unknown)
+{
+}
+
+}
diff --git a/Source/WebCore/platform/network/MIMEHeader.h b/Source/WebCore/platform/network/MIMEHeader.h
new file mode 100644 (file)
index 0000000..668bc1a
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MIMEHeader_h
+#define MIMEHeader_h
+
+#include <wtf/HashMap.h>
+#include <wtf/RefPtr.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+class SharedBufferCRLFLineReader;
+
+// FIXME: This class is a limited MIME parser used to parse the MIME headers of MHTML files.
+class MIMEHeader : public RefCounted<MIMEHeader> {
+public:
+    enum Encoding {
+        QuotedPrintable,
+        Base64,
+        SevenBit,
+        Unknown
+    };
+
+    static PassRefPtr<MIMEHeader> parseHeader(SharedBufferCRLFLineReader*);
+
+    bool isMultipart() const { return m_contentType.startsWith("multipart/"); }
+
+    String contentType() const { return m_contentType; }
+    String charset() const { return m_charset; }
+    Encoding contentTransferEncoding() const { return m_contentTransferEncoding; }
+    String contentLocation() const { return m_contentLocation; }
+
+    // Multi-part type and boundaries are only valid for multipart MIME headers.
+    String multiPartType() const { return m_multipartType; }
+    String endOfPartBoundary() const { return m_endOfPartBoundary; }
+    String endOfDocumentBoundary() const { return m_endOfDocumentBoundary; }
+
+private:
+    MIMEHeader();
+
+    static Encoding parseContentTransferEncoding(const String&);
+
+    String m_contentType;
+    String m_charset;
+    Encoding m_contentTransferEncoding;
+    String m_contentLocation;
+    String m_multipartType;
+    String m_endOfPartBoundary;
+    String m_endOfDocumentBoundary;
+};
+
+}
+
+#endif
index 10f8a44..c34de19 100644 (file)
@@ -1,3 +1,12 @@
+2011-05-24  Jay Civelli  <jcivelli@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Adding MHTML reading support to WebCore.
+        https://bugs.webkit.org/show_bug.cgi?id=7168
+
+       * features.gypi:
+
 2011-05-24  Alok Priyadarshi  <alokp@chromium.org>
 
         Reviewed by James Robinson.
index d231ea8..70218d0 100644 (file)
@@ -71,6 +71,7 @@
         'ENABLE_MEDIA_STATISTICS=1',
         'ENABLE_MEDIA_STREAM=1',
         'ENABLE_METER_TAG=1',
+        'ENABLE_MHTML=1',
         'ENABLE_NOTIFICATIONS=1',
         'ENABLE_OFFLINE_WEB_APPLICATIONS=1',
         'ENABLE_OPENTYPE_SANITIZER=1',
index e470a4c..e89bbfb 100644 (file)
@@ -1,3 +1,16 @@
+2011-05-24  Jay Civelli  <jcivelli@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        Adding MHTML reading support.
+        https://bugs.webkit.org/show_bug.cgi?id=7168
+
+        * Scripts/build-webkit:
+        * Scripts/old-run-webkit-tests:
+        * Scripts/webkitperl/features.pm:
+        * Scripts/webkitpy/layout_tests/port/test_files.py:
+        * Scripts/webkitpy/layout_tests/port/webkit.py:
+
 2011-05-24  Stephen White  <senorblanco@chromium.org>
 
         Reviewed by Kenneth Russell.
index b1b2c59..4237b97 100755 (executable)
@@ -94,6 +94,7 @@ my (
     $mediaStatisticsSupport,
     $mediaStreamSupport,
     $meterTagSupport,
+    $mhtmlSupport,
     $netscapePluginSupport,
     $notificationsSupport,
     $offlineWebApplicationSupport,
@@ -217,6 +218,9 @@ my @features = (
     { option => "meter-tag", desc => "Meter Tag support",
       define => "ENABLE_METER_TAG", default => !isAppleWinWebKit(), value => \$meterTagSupport },
 
+    { option => "mhtml", desc => "Toggle MHTML support",
+      define => "ENABLE_MHTML", default => 0, value => \$mhtmlSupport },
+
     { option => "netscape-plugin", desc => "Netscape Plugin support",
       define => "ENABLE_NETSCAPE_PLUGIN_API", default => !isEfl(), value => \$netscapePluginSupport },
 
index cfe6d61..7abaa68 100755 (executable)
@@ -499,12 +499,16 @@ system "ln", "-s", $testDirectory, "/tmp/LayoutTests" unless -x "/tmp/LayoutTest
 my %ignoredFiles = ( "results.html" => 1 );
 my %ignoredDirectories = map { $_ => 1 } qw(platform);
 my %ignoredLocalDirectories = map { $_ => 1 } qw(.svn _svn resources script-tests);
-my %supportedFileExtensions = map { $_ => 1 } qw(html shtml xml xhtml xhtmlmp pl php);
+my %supportedFileExtensions = map { $_ => 1 } qw(html shtml xml xhtml xhtmlmp pl php mht);
 
 if (!checkWebCoreFeatureSupport("MathML", 0)) {
     $ignoredDirectories{'mathml'} = 1;
 }
 
+if (!checkWebCoreFeatureSupport("MHTML", 0)) {
+    $ignoredDirectories{'mhtml'} = 1;
+}
+
 # FIXME: We should fix webkitperl/features.pm:hasFeature() to do the correct feature detection for Cygwin.
 if (checkWebCoreFeatureSupport("SVG", 0)) {
     $supportedFileExtensions{'svg'} = 1;
index 3110280..fceda38 100644 (file)
@@ -73,6 +73,7 @@ sub hasFeature($$)
         "3D Canvas" => "WebGLShader",
         "WCSS" => "parseWCSSInputProperty",
         "XHTMLMP" => "isXHTMLMPDocument",
+        "MHTML" => "MHTMLArchive"
     );
     my $symbolName = $symbolForFeature{$featureName};
     die "Unknown feature: $featureName" unless $symbolName;
index fbbbea5..a2d28f3 100644 (file)
@@ -44,7 +44,7 @@ _log = logutils.get_logger(__file__)
 
 # When collecting test cases, we include any file with these extensions.
 _supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.xhtmlmp', '.pl',
-                                  '.php', '.svg'])
+                                  '.php', '.svg', '.mht'])
 # When collecting test cases, skip these directories
 _skipped_directories = set(['.svn', '_svn', 'resources', 'script-tests'])
 
index 81c669b..51f30df 100644 (file)
@@ -1116,6 +1116,7 @@ AM_CONDITIONAL([ENABLE_FILTERS],[test "$enable_filters" = "yes"])
 AM_CONDITIONAL([ENABLE_GEOLOCATION], [test "$enable_geolocation" = "yes"])
 AM_CONDITIONAL([ENABLE_CLIENT_BASED_GEOLOCATION], [test "$enable_client_based_geolocation" = "yes"])
 AM_CONDITIONAL([ENABLE_MATHML], [test "$enable_mathml" = "yes"])
+AM_CONDITIONAL([ENABLE_MHTML], [test "$enable_mhtml" = "yes"])
 AM_CONDITIONAL([ENABLE_VIDEO],[test "$enable_video" = "yes"])
 AM_CONDITIONAL([ENABLE_MEDIA_STATISTICS],[test "$enable_media_statistics" = "yes"])
 AM_CONDITIONAL([ENABLE_VIDEO_TRACK],[test "$enable_video_track" = "yes"])