Diff
Modified: trunk/Tools/ChangeLog (149691 => 149692)
--- trunk/Tools/ChangeLog 2013-05-07 21:12:58 UTC (rev 149691)
+++ trunk/Tools/ChangeLog 2013-05-07 21:26:56 UTC (rev 149692)
@@ -1,5 +1,45 @@
2013-05-07 Alex Christensen <[email protected]>
+ WebKitTestRunner needs testRunner.dumpDOMAsWebArchive
+ https://bugs.webkit.org/show_bug.cgi?id=42324
+ <rdar://problem/8193633>
+
+ Reviewed by Tim Horton.
+
+ * Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ Added dumpDOMAsWebArchive _javascript_ function to be called by test cases.
+ * Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp:
+ (WTR::InjectedBundlePage::dumpDOMAsWebArchive):
+ Added dumpDOMAsWebArchive code that is called when dumping.
+ (WTR::InjectedBundlePage::dump):
+ Made DOMAsWebArchive case when dumping call dumpDOMAsWebArchive.
+ * Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h:
+ (InjectedBundlePage):
+ Added dumpDOMAsWebArchive declaration.
+ * Tools/WebKitTestRunner/InjectedBundle/TestRunner.h:
+ (WTR::TestRunner::dumpDOMAsWebArchive):
+ Added dumpDOMAsWebArchive JS callback function that sets m_whatToDump to DOMAsWebArchive.
+ * Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj:
+ Added WebArchiveDumpSupport.cpp, WebArchiveDumpSupport.h, WebArchiveDumpSupportMac.mm to project.
+ * Tools/WebKitTestRunner/cf: Added.
+ * Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.cpp: Added.
+ Copied from Tools/DumpRenderTree/cf for createXMLStringFromWebArchiveData and other functions it uses.
+ (convertMIMEType):
+ (convertWebResourceDataToString):
+ (normalizeHTTPResponseHeaderFields):
+ (normalizeWebResourceURL):
+ (convertWebResourceResponseToDictionary):
+ (compareResourceURLs):
+ (createXMLStringFromWebArchiveData):
+ * Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.h: Added.
+ Copied from Tools/DumpRenderTree/cf for used symbol declarations.
+ * Tools/WebKitTestRunner/mac/WebArchiveDumpSupportMac.mm: Added.
+ Copied from Tools/DumpRenderTree/mac for used functions.
+ (createCFURLResponseFromResponseData):
+ (supportedNonImageMIMETypes):
+
+2013-05-07 Alex Christensen <[email protected]>
+
Updated style of WebArchiveDumpSupport before putting it into WebKitTestRunner.
https://bugs.webkit.org/show_bug.cgi?id=115745
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (149691 => 149692)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2013-05-07 21:12:58 UTC (rev 149691)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2013-05-07 21:26:56 UTC (rev 149692)
@@ -47,6 +47,7 @@
void dumpWillCacheResponse();
void dumpApplicationCacheDelegateCallbacks();
void dumpDatabaseCallbacks();
+ void dumpDOMAsWebArchive();
// Special options.
void keepWebHistory();
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp (149691 => 149692)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2013-05-07 21:12:58 UTC (rev 149691)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.cpp 2013-05-07 21:26:56 UTC (rev 149692)
@@ -48,6 +48,10 @@
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
+#if USE(CF)
+#include "WebArchiveDumpSupport.h"
+#endif
+
#if PLATFORM(QT)
#include "DumpRenderTreeSupportQt.h"
#endif
@@ -837,6 +841,17 @@
dumpDescendantFramesText(frame, stringBuilder);
}
+
+void InjectedBundlePage::dumpDOMAsWebArchive(WKBundleFrameRef frame, StringBuilder& stringBuilder)
+{
+#if USE(CF)
+ WKDataRef wkData = WKBundleFrameCopyWebArchive(frame);
+ RetainPtr<CFDataRef> cfData = adoptCF(CFDataCreate(0, WKDataGetBytes(wkData), WKDataGetSize(wkData)));
+ RetainPtr<CFStringRef> cfString = adoptCF(createXMLStringFromWebArchiveData(cfData.get()));
+ stringBuilder.append(cfString.get());
+#endif
+}
+
void InjectedBundlePage::dump()
{
ASSERT(InjectedBundle::shared().isTestRunning());
@@ -868,6 +883,9 @@
break;
case TestRunner::Audio:
break;
+ case TestRunner::DOMAsWebArchive:
+ dumpDOMAsWebArchive(frame, stringBuilder);
+ break;
}
if (InjectedBundle::shared().testRunner()->shouldDumpAllFrameScrollPositions())
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h (149691 => 149692)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h 2013-05-07 21:12:58 UTC (rev 149691)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/InjectedBundlePage.h 2013-05-07 21:26:56 UTC (rev 149692)
@@ -166,6 +166,7 @@
void dumpAllFramesText(WTF::StringBuilder&);
void dumpAllFrameScrollPositions(WTF::StringBuilder&);
+ void dumpDOMAsWebArchive(WKBundleFrameRef, WTF::StringBuilder&);
void platformDidStartProvisionalLoadForFrame(WKBundleFrameRef);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (149691 => 149692)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2013-05-07 21:12:58 UTC (rev 149691)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2013-05-07 21:26:56 UTC (rev 149692)
@@ -88,6 +88,7 @@
void dumpWillCacheResponse() { m_dumpWillCacheResponse = true; }
void dumpApplicationCacheDelegateCallbacks() { m_dumpApplicationCacheDelegateCallbacks = true; }
void dumpDatabaseCallbacks() { m_dumpDatabaseCallbacks = true; }
+ void dumpDOMAsWebArchive() { m_whatToDump = DOMAsWebArchive; }
void setShouldDumpFrameLoadCallbacks(bool value) { m_dumpFrameLoadCallbacks = value; }
void setShouldDumpProgressFinishedCallback(bool value) { m_dumpProgressFinishedCallback = value; }
@@ -163,7 +164,7 @@
// Audio testing.
void setAudioResult(JSContextRef, JSValueRef data);
- enum WhatToDump { RenderTree, MainFrameText, AllFramesText, Audio };
+ enum WhatToDump { RenderTree, MainFrameText, AllFramesText, Audio, DOMAsWebArchive };
WhatToDump whatToDump() const { return m_whatToDump; }
bool shouldDumpAllFrameScrollPositions() const { return m_shouldDumpAllFrameScrollPositions; }
Modified: trunk/Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj (149691 => 149692)
--- trunk/Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj 2013-05-07 21:12:58 UTC (rev 149691)
+++ trunk/Tools/WebKitTestRunner/WebKitTestRunner.xcodeproj/project.pbxproj 2013-05-07 21:26:56 UTC (rev 149692)
@@ -44,6 +44,8 @@
5641E2D014335E95008307E5 /* JSTextInputController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5641E2CE14335E95008307E5 /* JSTextInputController.cpp */; };
5664A49A14326384008881BE /* TextInputController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5664A49814326384008881BE /* TextInputController.cpp */; };
5670B8281386FCA5002EB355 /* EventSenderProxy.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5670B8271386FCA5002EB355 /* EventSenderProxy.mm */; };
+ 5C45C30F17398E290079714E /* WebArchiveDumpSupportMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5C45C30E17398E290079714E /* WebArchiveDumpSupportMac.mm */; };
+ 5C45C31317398E480079714E /* WebArchiveDumpSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5C45C31117398E480079714E /* WebArchiveDumpSupport.cpp */; };
6510A78211EC643800410867 /* AHEM____.TTF in Resources */ = {isa = PBXBuildFile; fileRef = 6510A77711EC643800410867 /* AHEM____.TTF */; };
6510A78411EC643800410867 /* WebKitWeightWatcher100.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6510A77911EC643800410867 /* WebKitWeightWatcher100.ttf */; };
6510A78511EC643800410867 /* WebKitWeightWatcher200.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 6510A77A11EC643800410867 /* WebKitWeightWatcher200.ttf */; };
@@ -149,6 +151,9 @@
5670B8271386FCA5002EB355 /* EventSenderProxy.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EventSenderProxy.mm; sourceTree = "<group>"; };
583913D014335E95008307E5 /* JSAccessibilityController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSAccessibilityController.cpp; path = DerivedSources/WebKitTestRunner/JSAccessibilityController.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
583913D114335E95008307E5 /* JSAccessibilityController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSAccessibilityController.h; path = DerivedSources/WebKitTestRunner/JSAccessibilityController.h; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5C45C30E17398E290079714E /* WebArchiveDumpSupportMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = WebArchiveDumpSupportMac.mm; path = mac/WebArchiveDumpSupportMac.mm; sourceTree = SOURCE_ROOT; };
+ 5C45C31117398E480079714E /* WebArchiveDumpSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebArchiveDumpSupport.cpp; path = cf/WebArchiveDumpSupport.cpp; sourceTree = SOURCE_ROOT; };
+ 5C45C31217398E480079714E /* WebArchiveDumpSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebArchiveDumpSupport.h; path = cf/WebArchiveDumpSupport.h; sourceTree = SOURCE_ROOT; };
6510A77711EC643800410867 /* AHEM____.TTF */ = {isa = PBXFileReference; lastKnownFileType = file; name = "AHEM____.TTF"; path = "fonts/AHEM____.TTF"; sourceTree = "<group>"; };
6510A77911EC643800410867 /* WebKitWeightWatcher100.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher100.ttf; path = fonts/WebKitWeightWatcher100.ttf; sourceTree = "<group>"; };
6510A77A11EC643800410867 /* WebKitWeightWatcher200.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = WebKitWeightWatcher200.ttf; path = fonts/WebKitWeightWatcher200.ttf; sourceTree = "<group>"; };
@@ -327,9 +332,19 @@
name = Accessibility;
sourceTree = "<group>";
};
+ 5C45C31017398E370079714E /* cf */ = {
+ isa = PBXGroup;
+ children = (
+ 5C45C31117398E480079714E /* WebArchiveDumpSupport.cpp */,
+ 5C45C31217398E480079714E /* WebArchiveDumpSupport.h */,
+ );
+ name = cf;
+ sourceTree = "<group>";
+ };
65EB859E11EC67CC0034D300 /* mac */ = {
isa = PBXGroup;
children = (
+ 5C45C30E17398E290079714E /* WebArchiveDumpSupportMac.mm */,
65EB859F11EC67CC0034D300 /* ActivateFonts.mm */,
BC8DAD771316D7B900EC96FC /* InjectedBundleMac.mm */,
0FAF67EE160D6C100077CB2B /* InjectedBundlePageMac.mm */,
@@ -357,6 +372,7 @@
BC25183511D1571D002EBC01 /* InjectedBundle */ = {
isa = PBXGroup;
children = (
+ 5C45C31017398E370079714E /* cf */,
BC952C0A11F3B939003398B4 /* Bindings */,
BC14E4E0120E02F900826C0C /* Controllers */,
BC952D3A11F3BF1F003398B4 /* Derived Sources */,
@@ -515,6 +531,8 @@
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
+ attributes = {
+ };
buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "WebKitTestRunner" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
@@ -626,6 +644,8 @@
5641E2D014335E95008307E5 /* JSTextInputController.cpp in Sources */,
BC952C0D11F3B965003398B4 /* JSWrapper.cpp in Sources */,
BCC9981811D3F51E0017BCA2 /* TestRunner.cpp in Sources */,
+ 5C45C30F17398E290079714E /* WebArchiveDumpSupportMac.mm in Sources */,
+ 5C45C31317398E480079714E /* WebArchiveDumpSupport.cpp in Sources */,
C0CE720B1247C93300BC0EC4 /* TestRunnerMac.mm in Sources */,
5664A49A14326384008881BE /* TextInputController.cpp in Sources */,
);
Added: trunk/Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.cpp (0 => 149692)
--- trunk/Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.cpp (rev 0)
+++ trunk/Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.cpp 2013-05-07 21:26:56 UTC (rev 149692)
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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.
+ *
+ * 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 "WebArchiveDumpSupport.h"
+
+#include <CFNetwork/CFNetwork.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <wtf/RetainPtr.h>
+
+extern "C" {
+
+CFURLRef CFURLResponseGetURL(CFURLResponseRef);
+CFStringRef CFURLResponseGetMIMEType(CFURLResponseRef);
+CFStringRef CFURLResponseGetTextEncodingName(CFURLResponseRef);
+SInt64 CFURLResponseGetExpectedContentLength(CFURLResponseRef);
+CFHTTPMessageRef CFURLResponseGetHTTPResponse(CFURLResponseRef);
+
+CFTypeID CFURLResponseGetTypeID(void);
+
+}
+
+static void convertMIMEType(CFMutableStringRef mimeType)
+{
+#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1050
+ // Workaround for <rdar://problem/5539824> on Leopard
+ if (CFStringCompare(mimeType, CFSTR("text/xml"), kCFCompareAnchored | kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ CFStringReplaceAll(mimeType, CFSTR("application/xml"));
+#endif
+ // Workaround for <rdar://problem/6234318> with Dashcode 2.0
+ if (CFStringCompare(mimeType, CFSTR("application/x-_javascript_"), kCFCompareAnchored | kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+ CFStringReplaceAll(mimeType, CFSTR("text/_javascript_"));
+}
+
+static void convertWebResourceDataToString(CFMutableDictionaryRef resource)
+{
+ CFMutableStringRef mimeType = (CFMutableStringRef)CFDictionaryGetValue(resource, CFSTR("WebResourceMIMEType"));
+ CFStringLowercase(mimeType, CFLocaleGetSystem());
+ convertMIMEType(mimeType);
+
+ CFArrayRef supportedMIMETypes = supportedNonImageMIMETypes();
+ if (CFStringHasPrefix(mimeType, CFSTR("text/")) || CFArrayContainsValue(supportedMIMETypes, CFRangeMake(0, CFArrayGetCount(supportedMIMETypes)), mimeType)) {
+ CFStringRef textEncodingName = static_cast<CFStringRef>(CFDictionaryGetValue(resource, CFSTR("WebResourceTextEncodingName")));
+ CFStringEncoding stringEncoding;
+ if (textEncodingName && CFStringGetLength(textEncodingName))
+ stringEncoding = CFStringConvertIANACharSetNameToEncoding(textEncodingName);
+ else
+ stringEncoding = kCFStringEncodingUTF8;
+
+ CFDataRef data = "" CFSTR("WebResourceData")));
+ RetainPtr<CFStringRef> dataAsString(AdoptCF, CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, data, stringEncoding));
+ if (dataAsString)
+ CFDictionarySetValue(resource, CFSTR("WebResourceData"), dataAsString.get());
+ }
+}
+
+static void normalizeHTTPResponseHeaderFields(CFMutableDictionaryRef fields)
+{
+ // Normalize headers
+ if (CFDictionaryContainsKey(fields, CFSTR("Date")))
+ CFDictionarySetValue(fields, CFSTR("Date"), CFSTR("Sun, 16 Nov 2008 17:00:00 GMT"));
+ if (CFDictionaryContainsKey(fields, CFSTR("Last-Modified")))
+ CFDictionarySetValue(fields, CFSTR("Last-Modified"), CFSTR("Sun, 16 Nov 2008 16:55:00 GMT"));
+ if (CFDictionaryContainsKey(fields, CFSTR("Etag")))
+ CFDictionarySetValue(fields, CFSTR("Etag"), CFSTR("\"301925-21-45c7d72d3e780\""));
+ if (CFDictionaryContainsKey(fields, CFSTR("Server")))
+ CFDictionarySetValue(fields, CFSTR("Server"), CFSTR("Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.7l PHP/5.2.6"));
+
+ // Remove headers
+ CFDictionaryRemoveValue(fields, CFSTR("Connection"));
+ CFDictionaryRemoveValue(fields, CFSTR("Keep-Alive"));
+}
+
+static void normalizeWebResourceURL(CFMutableStringRef webResourceURL)
+{
+ static CFIndex fileUrlLength = CFStringGetLength(CFSTR("file://"));
+ CFRange layoutTestsWebArchivePathRange = CFStringFind(webResourceURL, CFSTR("/LayoutTests/"), kCFCompareBackwards);
+ if (layoutTestsWebArchivePathRange.location == kCFNotFound)
+ return;
+ CFRange currentWorkingDirectoryRange = CFRangeMake(fileUrlLength, layoutTestsWebArchivePathRange.location - fileUrlLength);
+ CFStringReplace(webResourceURL, currentWorkingDirectoryRange, CFSTR(""));
+}
+
+static void convertWebResourceResponseToDictionary(CFMutableDictionaryRef propertyList)
+{
+ CFDataRef responseData = static_cast<CFDataRef>(CFDictionaryGetValue(propertyList, CFSTR("WebResourceResponse"))); // WebResourceResponseKey in WebResource.m
+ if (CFGetTypeID(responseData) != CFDataGetTypeID())
+ return;
+
+ RetainPtr<CFURLResponseRef> response(AdoptCF, createCFURLResponseFromResponseData(responseData));
+ if (!response)
+ return;
+
+ RetainPtr<CFMutableDictionaryRef> responseDictionary(AdoptCF, CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ RetainPtr<CFMutableStringRef> urlString(AdoptCF, CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFURLGetString(CFURLResponseGetURL(response.get()))));
+ normalizeWebResourceURL(urlString.get());
+ CFDictionarySetValue(responseDictionary.get(), CFSTR("URL"), urlString.get());
+
+ RetainPtr<CFMutableStringRef> mimeTypeString(AdoptCF, CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFURLResponseGetMIMEType(response.get())));
+ convertMIMEType(mimeTypeString.get());
+ CFDictionarySetValue(responseDictionary.get(), CFSTR("MIMEType"), mimeTypeString.get());
+
+ CFStringRef textEncodingName = CFURLResponseGetTextEncodingName(response.get());
+ if (textEncodingName)
+ CFDictionarySetValue(responseDictionary.get(), CFSTR("textEncodingName"), textEncodingName);
+
+ SInt64 expectedContentLength = CFURLResponseGetExpectedContentLength(response.get());
+ RetainPtr<CFNumberRef> expectedContentLengthNumber(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &expectedContentLength));
+ CFDictionarySetValue(responseDictionary.get(), CFSTR("expectedContentLength"), expectedContentLengthNumber.get());
+
+ if (CFHTTPMessageRef httpMessage = CFURLResponseGetHTTPResponse(response.get())) {
+ RetainPtr<CFDictionaryRef> allHeaders(AdoptCF, CFHTTPMessageCopyAllHeaderFields(httpMessage));
+ RetainPtr<CFMutableDictionaryRef> allHeaderFields(AdoptCF, CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, allHeaders.get()));
+ normalizeHTTPResponseHeaderFields(allHeaderFields.get());
+ CFDictionarySetValue(responseDictionary.get(), CFSTR("allHeaderFields"), allHeaderFields.get());
+
+ CFIndex statusCode = CFHTTPMessageGetResponseStatusCode(httpMessage);
+ RetainPtr<CFNumberRef> statusCodeNumber(AdoptCF, CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &statusCode));
+ CFDictionarySetValue(responseDictionary.get(), CFSTR("statusCode"), statusCodeNumber.get());
+ }
+
+ CFDictionarySetValue(propertyList, CFSTR("WebResourceResponse"), responseDictionary.get());
+}
+
+static CFComparisonResult compareResourceURLs(const void *val1, const void *val2, void *context)
+{
+ CFStringRef url1 = static_cast<CFStringRef>(CFDictionaryGetValue(static_cast<CFDictionaryRef>(val1), CFSTR("WebResourceURL")));
+ CFStringRef url2 = static_cast<CFStringRef>(CFDictionaryGetValue(static_cast<CFDictionaryRef>(val2), CFSTR("WebResourceURL")));
+
+ return CFStringCompare(url1, url2, kCFCompareAnchored);
+}
+
+CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData)
+{
+ CFErrorRef error = 0;
+ CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1050
+ CFIndex bytesCount = CFDataGetLength(webArchiveData);
+ RetainPtr<CFReadStreamRef> readStream(AdoptCF, CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, CFDataGetBytePtr(webArchiveData), bytesCount, kCFAllocatorNull));
+ CFReadStreamOpen(readStream.get());
+ RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, (CFMutableDictionaryRef)CFPropertyListCreateFromStream(kCFAllocatorDefault, readStream.get(), bytesCount, kCFPropertyListMutableContainersAndLeaves, &format, 0));
+ CFReadStreamClose(readStream.get());
+#else
+ RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, (CFMutableDictionaryRef)CFPropertyListCreateWithData(kCFAllocatorDefault, webArchiveData, kCFPropertyListMutableContainersAndLeaves, &format, &error));
+#endif
+
+ if (!propertyList) {
+ if (error)
+ return CFErrorCopyDescription(error);
+ return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting data to property list.")));
+ }
+
+ RetainPtr<CFMutableArrayRef> resources(AdoptCF, CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
+ CFArrayAppendValue(resources.get(), propertyList.get());
+
+ while (CFArrayGetCount(resources.get())) {
+ RetainPtr<CFMutableDictionaryRef> resourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(resources.get(), 0);
+ CFArrayRemoveValueAtIndex(resources.get(), 0);
+
+ CFMutableDictionaryRef mainResource = (CFMutableDictionaryRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebMainResource"));
+ normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(mainResource, CFSTR("WebResourceURL")));
+ convertWebResourceDataToString(mainResource);
+
+ // Add subframeArchives to list for processing
+ CFMutableArrayRef subframeArchives = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubframeArchives")); // WebSubframeArchivesKey in WebArchive.m
+ if (subframeArchives)
+ CFArrayAppendArray(resources.get(), subframeArchives, CFRangeMake(0, CFArrayGetCount(subframeArchives)));
+
+ CFMutableArrayRef subresources = (CFMutableArrayRef)CFDictionaryGetValue(resourcePropertyList.get(), CFSTR("WebSubresources")); // WebSubresourcesKey in WebArchive.m
+ if (!subresources)
+ continue;
+
+ CFIndex subresourcesCount = CFArrayGetCount(subresources);
+ for (CFIndex i = 0; i < subresourcesCount; ++i) {
+ CFMutableDictionaryRef subresourcePropertyList = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(subresources, i);
+ normalizeWebResourceURL((CFMutableStringRef)CFDictionaryGetValue(subresourcePropertyList, CFSTR("WebResourceURL")));
+ convertWebResourceResponseToDictionary(subresourcePropertyList);
+ convertWebResourceDataToString(subresourcePropertyList);
+ }
+
+ // Sort the subresources so they're always in a predictable order for the dump
+ CFArraySortValues(subresources, CFRangeMake(0, CFArrayGetCount(subresources)), compareResourceURLs, 0);
+ }
+
+ error = 0;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED == 1050
+ RetainPtr<CFDataRef> xmlData(AdoptCF, CFPropertyListCreateXMLData(kCFAllocatorDefault, propertyList.get()));
+#else
+ RetainPtr<CFDataRef> xmlData(AdoptCF, CFPropertyListCreateData(kCFAllocatorDefault, propertyList.get(), kCFPropertyListXMLFormat_v1_0, 0, &error));
+#endif
+
+ if (!xmlData) {
+ if (error)
+ return CFErrorCopyDescription(error);
+ return static_cast<CFStringRef>(CFRetain(CFSTR("An unknown error occurred converting property list to data.")));
+ }
+
+ RetainPtr<CFStringRef> xmlString(AdoptCF, CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, xmlData.get(), kCFStringEncodingUTF8));
+ RetainPtr<CFMutableStringRef> string(AdoptCF, CFStringCreateMutableCopy(kCFAllocatorDefault, 0, xmlString.get()));
+
+ // Replace "Apple Computer" with "Apple" in the DTD declaration.
+ CFStringFindAndReplace(string.get(), CFSTR("-//Apple Computer//"), CFSTR("-//Apple//"), CFRangeMake(0, CFStringGetLength(string.get())), 0);
+
+ return string.leakRef();
+}
Added: trunk/Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.h (0 => 149692)
--- trunk/Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.h (rev 0)
+++ trunk/Tools/WebKitTestRunner/cf/WebArchiveDumpSupport.h 2013-05-07 21:26:56 UTC (rev 149692)
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2007, 2008, 2009, 2010 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.
+ *
+ * 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.
+ */
+
+#ifndef WebArchiveDumpSupport_h
+#define WebArchiveDumpSupport_h
+
+#include <CoreFoundation/CoreFoundation.h>
+
+typedef struct _CFURLResponse* CFURLResponseRef;
+
+CFStringRef createXMLStringFromWebArchiveData(CFDataRef webArchiveData);
+
+// MARK: -
+// MARK: Platform-specific methods
+
+CFURLResponseRef createCFURLResponseFromResponseData(CFDataRef responseData);
+CFArrayRef supportedNonImageMIMETypes();
+
+#endif /* WebArchiveDumpSupport_h */
Added: trunk/Tools/WebKitTestRunner/mac/WebArchiveDumpSupportMac.mm (0 => 149692)
--- trunk/Tools/WebKitTestRunner/mac/WebArchiveDumpSupportMac.mm (rev 0)
+++ trunk/Tools/WebKitTestRunner/mac/WebArchiveDumpSupportMac.mm 2013-05-07 21:26:56 UTC (rev 149692)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010 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.
+ *
+ * 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.
+ */
+
+#import "config.h"
+#import "WebArchiveDumpSupport.h"
+
+#import <CFNetwork/CFHTTPMessage.h>
+#import <Foundation/Foundation.h>
+#import <WebKit/WebHTMLRepresentation.h>
+#import <wtf/RetainPtr.h>
+
+extern "C" {
+
+enum CFURLCacheStoragePolicy {
+ kCFURLCacheStorageAllowed = 0,
+ kCFURLCacheStorageAllowedInMemoryOnly = 1,
+ kCFURLCacheStorageNotAllowed = 2
+};
+typedef enum CFURLCacheStoragePolicy CFURLCacheStoragePolicy;
+
+extern const CFStringRef kCFHTTPVersion1_1;
+
+CFURLResponseRef CFURLResponseCreate(CFAllocatorRef alloc, CFURLRef URL, CFStringRef mimeType, SInt64 expectedContentLength, CFStringRef textEncodingName, CFURLCacheStoragePolicy recommendedPolicy);
+CFURLResponseRef CFURLResponseCreateWithHTTPResponse(CFAllocatorRef alloc, CFURLRef URL, CFHTTPMessageRef httpResponse, CFURLCacheStoragePolicy recommendedPolicy);
+void CFURLResponseSetExpectedContentLength(CFURLResponseRef response, SInt64 length);
+void CFURLResponseSetMIMEType(CFURLResponseRef response, CFStringRef mimeType);
+
+}
+
+CFURLResponseRef createCFURLResponseFromResponseData(CFDataRef responseData)
+{
+ // Decode NSURLResponse
+ RetainPtr<NSKeyedUnarchiver> unarchiver(AdoptNS, [[NSKeyedUnarchiver alloc] initForReadingWithData:(NSData *)responseData]);
+ NSURLResponse *response = [unarchiver.get() decodeObjectForKey:@"WebResourceResponse"]; // WebResourceResponseKey in WebResource.m
+ [unarchiver.get() finishDecoding];
+
+ if (![response isKindOfClass:[NSHTTPURLResponse class]])
+ return CFURLResponseCreate(kCFAllocatorDefault, (CFURLRef)[response URL], (CFStringRef)[response MIMEType], [response expectedContentLength], (CFStringRef)[response textEncodingName], kCFURLCacheStorageAllowed);
+
+ NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
+
+ // NSURLResponse is not toll-free bridged to CFURLResponse.
+ RetainPtr<CFHTTPMessageRef> httpMessage(AdoptCF, CFHTTPMessageCreateResponse(kCFAllocatorDefault, [httpResponse statusCode], 0, kCFHTTPVersion1_1));
+
+ NSDictionary *headerFields = [httpResponse allHeaderFields];
+ for (NSString *headerField in [headerFields keyEnumerator])
+ CFHTTPMessageSetHeaderFieldValue(httpMessage.get(), (CFStringRef)headerField, (CFStringRef)[headerFields objectForKey:headerField]);
+
+ return CFURLResponseCreateWithHTTPResponse(kCFAllocatorDefault, (CFURLRef)[response URL], httpMessage.get(), kCFURLCacheStorageAllowed);
+}
+
+CFArrayRef supportedNonImageMIMETypes()
+{
+ return (CFArrayRef)[WebHTMLRepresentation supportedNonImageMIMETypes];
+}