1 /* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "HistoryDelegate.h" 28 29 #include "DumpRenderTree.h" 30 #include "DumpRenderTreeWin.h" 31 #include "LayoutTestController.h" 32 #include <string> 33 #include <WebKit/WebKit.h> 34 35 using std::wstring; 36 37 static inline wstring wstringFromBSTR(BSTR str) 38 { 39 return wstring(str, ::SysStringLen(str)); 40 } 41 42 HistoryDelegate::HistoryDelegate() 43 : m_refCount(1) 44 { 45 } 46 47 HistoryDelegate::~HistoryDelegate() 48 { 49 } 50 51 // IUnknown 52 HRESULT HistoryDelegate::QueryInterface(REFIID riid, void** ppvObject) 53 { 54 *ppvObject = 0; 55 if (IsEqualGUID(riid, IID_IUnknown)) 56 *ppvObject = static_cast<IWebHistoryDelegate*>(this); 57 else if (IsEqualGUID(riid, IID_IWebHistoryDelegate)) 58 *ppvObject = static_cast<IWebHistoryDelegate*>(this); 59 else 60 return E_NOINTERFACE; 61 62 AddRef(); 63 return S_OK; 64 } 65 66 ULONG HistoryDelegate::AddRef(void) 67 { 68 return ++m_refCount; 69 } 70 71 ULONG HistoryDelegate::Release(void) 72 { 73 ULONG newRef = --m_refCount; 74 if (!newRef) 75 delete(this); 76 77 return newRef; 78 } 79 80 // IWebHistoryDelegate 81 HRESULT HistoryDelegate::didNavigateWithNavigationData(IWebView* webView, IWebNavigationData* navigationData, IWebFrame* webFrame) 82 { 83 if (!gLayoutTestController->dumpHistoryDelegateCallbacks()) 84 return S_OK; 85 86 BSTR urlBSTR; 87 if (FAILED(navigationData->url(&urlBSTR))) 88 return E_FAIL; 89 wstring url; 90 if (urlBSTR) 91 url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR)); 92 SysFreeString(urlBSTR); 93 94 BSTR titleBSTR; 95 if (FAILED(navigationData->title(&titleBSTR))) 96 return E_FAIL; 97 wstring title; 98 if (titleBSTR) 99 title = wstringFromBSTR(titleBSTR); 100 SysFreeString(titleBSTR); 101 102 COMPtr<IWebURLRequest> request; 103 if (FAILED(navigationData->originalRequest(&request))) 104 return E_FAIL; 105 106 BSTR httpMethodBSTR; 107 if (FAILED(request->HTTPMethod(&httpMethodBSTR))) 108 return E_FAIL; 109 wstring httpMethod; 110 if (httpMethodBSTR) 111 httpMethod = wstringFromBSTR(httpMethodBSTR); 112 SysFreeString(httpMethodBSTR); 113 114 COMPtr<IWebURLResponse> response; 115 if (FAILED(navigationData->response(&response))) 116 return E_FAIL; 117 118 COMPtr<IWebHTTPURLResponse> httpResponse; 119 if (FAILED(response->QueryInterface(&httpResponse))) 120 return E_FAIL; 121 122 int statusCode = 0; 123 if (FAILED(httpResponse->statusCode(&statusCode))) 124 return E_FAIL; 125 126 BOOL hasSubstituteData; 127 if (FAILED(navigationData->hasSubstituteData(&hasSubstituteData))) 128 return E_FAIL; 129 130 BSTR clientRedirectSourceBSTR; 131 if (FAILED(navigationData->clientRedirectSource(&clientRedirectSourceBSTR))) 132 return E_FAIL; 133 bool hasClientRedirect = clientRedirectSourceBSTR && SysStringLen(clientRedirectSourceBSTR); 134 wstring redirectSource; 135 if (clientRedirectSourceBSTR) 136 redirectSource = urlSuitableForTestResult(wstringFromBSTR(clientRedirectSourceBSTR)); 137 SysFreeString(clientRedirectSourceBSTR); 138 139 bool wasFailure = hasSubstituteData || (httpResponse && statusCode >= 400); 140 141 printf("WebView navigated to url \"%S\" with title \"%S\" with HTTP equivalent method \"%S\". The navigation was %s and was %s%S.\n", 142 url.c_str(), 143 title.c_str(), 144 httpMethod.c_str(), 145 wasFailure ? "a failure" : "successful", 146 hasClientRedirect ? "a client redirect from " : "not a client redirect", 147 redirectSource.c_str()); 148 149 return S_OK; 150 } 151 152 HRESULT HistoryDelegate::didPerformClientRedirectFromURL(IWebView*, BSTR sourceURL, BSTR destinationURL, IWebFrame*) 153 { 154 if (!gLayoutTestController->dumpHistoryDelegateCallbacks()) 155 return S_OK; 156 157 wstring source; 158 if (sourceURL) 159 source = urlSuitableForTestResult(wstringFromBSTR(sourceURL)); 160 161 wstring destination; 162 if (destinationURL) 163 destination = urlSuitableForTestResult(wstringFromBSTR(destinationURL)); 164 165 printf("WebView performed a client redirect from \"%S\" to \"%S\".\n", source.c_str(), destination.c_str()); 166 return S_OK; 167 } 168 169 HRESULT HistoryDelegate::didPerformServerRedirectFromURL(IWebView* webView, BSTR sourceURL, BSTR destinationURL, IWebFrame* webFrame) 170 { 171 if (!gLayoutTestController->dumpHistoryDelegateCallbacks()) 172 return S_OK; 173 174 wstring source; 175 if (sourceURL) 176 source = urlSuitableForTestResult(wstringFromBSTR(sourceURL)); 177 178 wstring destination; 179 if (destinationURL) 180 destination = urlSuitableForTestResult(wstringFromBSTR(destinationURL)); 181 182 printf("WebView performed a server redirect from \"%S\" to \"%S\".\n", source.c_str(), destination.c_str()); 183 return S_OK; 184 } 185 186 HRESULT HistoryDelegate::updateHistoryTitle(IWebView* webView, BSTR titleBSTR, BSTR urlBSTR) 187 { 188 if (!gLayoutTestController->dumpHistoryDelegateCallbacks()) 189 return S_OK; 190 191 wstring url; 192 if (urlBSTR) 193 url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR)); 194 195 wstring title; 196 if (titleBSTR) 197 title = wstringFromBSTR(titleBSTR); 198 199 printf("WebView updated the title for history URL \"%S\" to \"%S\".\n", url.c_str(), title.c_str()); 200 return S_OK; 201 } 202 203 HRESULT HistoryDelegate::populateVisitedLinksForWebView(IWebView* webView) 204 { 205 if (!gLayoutTestController->dumpHistoryDelegateCallbacks()) 206 return S_OK; 207 208 BSTR urlBSTR; 209 if (FAILED(webView->mainFrameURL(&urlBSTR))) 210 return E_FAIL; 211 212 wstring url; 213 if (urlBSTR) 214 url = urlSuitableForTestResult(wstringFromBSTR(urlBSTR)); 215 SysFreeString(urlBSTR); 216 217 if (gLayoutTestController->dumpVisitedLinksCallback()) 218 printf("Asked to populate visited links for WebView \"%S\"\n", url.c_str()); 219 220 return S_OK; 221 } 222