1 /*
2 * Copyright (C) 2007 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 "WebKitDLL.h"
28 #include "DefaultPolicyDelegate.h"
29
30 #include <WebCore/COMPtr.h>
31 #include <WebCore/PlatformString.h>
32
33 using namespace WebCore;
34
35 // FIXME: move this enum to a separate header file when other code begins to use it.
36 typedef enum WebExtraNavigationType {
37 WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1
38 } WebExtraNavigationType;
39
40 // DefaultPolicyDelegate ----------------------------------------------------------------
41
DefaultPolicyDelegate()42 DefaultPolicyDelegate::DefaultPolicyDelegate()
43 : m_refCount(0)
44 {
45 gClassCount++;
46 gClassNameCount.add("DefaultPolicyDelegate");
47 }
48
~DefaultPolicyDelegate()49 DefaultPolicyDelegate::~DefaultPolicyDelegate()
50 {
51 gClassCount--;
52 gClassNameCount.remove("DefaultPolicyDelegate");
53 }
54
sharedInstance()55 DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance()
56 {
57 static COMPtr<DefaultPolicyDelegate> shared;
58 if (!shared)
59 shared.adoptRef(DefaultPolicyDelegate::createInstance());
60 return shared.get();
61 }
62
createInstance()63 DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance()
64 {
65 DefaultPolicyDelegate* instance = new DefaultPolicyDelegate();
66 instance->AddRef();
67 return instance;
68 }
69
70 // IUnknown -------------------------------------------------------------------
71
QueryInterface(REFIID riid,void ** ppvObject)72 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::QueryInterface(REFIID riid, void** ppvObject)
73 {
74 *ppvObject = 0;
75 if (IsEqualGUID(riid, IID_IUnknown))
76 *ppvObject = static_cast<IUnknown*>(this);
77 else if (IsEqualGUID(riid, IID_IWebPolicyDelegate))
78 *ppvObject = static_cast<IWebPolicyDelegate*>(this);
79 else
80 return E_NOINTERFACE;
81
82 AddRef();
83 return S_OK;
84 }
85
AddRef()86 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef()
87 {
88 return ++m_refCount;
89 }
90
Release()91 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release()
92 {
93 ULONG newRef = --m_refCount;
94 if (!newRef)
95 delete(this);
96
97 return newRef;
98 }
99
decidePolicyForNavigationAction(IWebView * webView,IPropertyBag * actionInformation,IWebURLRequest * request,IWebFrame *,IWebPolicyDecisionListener * listener)100 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNavigationAction(
101 /*[in]*/ IWebView* webView,
102 /*[in]*/ IPropertyBag* actionInformation,
103 /*[in]*/ IWebURLRequest* request,
104 /*[in]*/ IWebFrame* /*frame*/,
105 /*[in]*/ IWebPolicyDecisionListener* listener)
106 {
107 int navType = 0;
108 VARIANT var;
109 if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) {
110 V_VT(&var) = VT_I4;
111 navType = V_I4(&var);
112 }
113 COMPtr<IWebViewPrivate> wvPrivate(Query, webView);
114 if (wvPrivate) {
115 BOOL canHandleRequest = FALSE;
116 if (SUCCEEDED(wvPrivate->canHandleRequest(request, &canHandleRequest)) && canHandleRequest)
117 listener->use();
118 else if (navType == WebNavigationTypePlugInRequest)
119 listener->use();
120 else {
121 BSTR url;
122 // A file URL shouldn't fall through to here, but if it did,
123 // it would be a security risk to open it.
124 if (SUCCEEDED(request->URL(&url)) && !String(url, SysStringLen(url)).startsWith("file:")) {
125 // FIXME: Open the URL not by means of a webframe, but by handing it over to the system and letting it determine how to open that particular URL scheme. See documentation for [NSWorkspace openURL]
126 ;
127 }
128 listener->ignore();
129 SysFreeString(url);
130 }
131 }
132 return S_OK;
133 }
134
decidePolicyForNewWindowAction(IWebView *,IPropertyBag *,IWebURLRequest *,BSTR,IWebPolicyDecisionListener * listener)135 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNewWindowAction(
136 /*[in]*/ IWebView* /*webView*/,
137 /*[in]*/ IPropertyBag* /*actionInformation*/,
138 /*[in]*/ IWebURLRequest* /*request*/,
139 /*[in]*/ BSTR /*frameName*/,
140 /*[in]*/ IWebPolicyDecisionListener* listener)
141 {
142 listener->use();
143 return S_OK;
144 }
145
decidePolicyForMIMEType(IWebView * webView,BSTR type,IWebURLRequest * request,IWebFrame *,IWebPolicyDecisionListener * listener)146 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForMIMEType(
147 /*[in]*/ IWebView* webView,
148 /*[in]*/ BSTR type,
149 /*[in]*/ IWebURLRequest* request,
150 /*[in]*/ IWebFrame* /*frame*/,
151 /*[in]*/ IWebPolicyDecisionListener* listener)
152 {
153 BOOL canShowMIMEType;
154 if (FAILED(webView->canShowMIMEType(type, &canShowMIMEType)))
155 canShowMIMEType = FALSE;
156
157 BSTR url;
158 request->URL(&url);
159
160 if (String(url, SysStringLen(url)).startsWith("file:")) {
161 BOOL isDirectory = FALSE;
162 WIN32_FILE_ATTRIBUTE_DATA attrs;
163 if (GetFileAttributesEx(url, GetFileExInfoStandard, &attrs))
164 isDirectory = !!(attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
165
166 if (isDirectory)
167 listener->ignore();
168 else if(canShowMIMEType)
169 listener->use();
170 else
171 listener->ignore();
172 } else if (canShowMIMEType)
173 listener->use();
174 else
175 listener->ignore();
176 SysFreeString(url);
177 return S_OK;
178 }
179
unableToImplementPolicyWithError(IWebView *,IWebError * error,IWebFrame * frame)180 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::unableToImplementPolicyWithError(
181 /*[in]*/ IWebView* /*webView*/,
182 /*[in]*/ IWebError* error,
183 /*[in]*/ IWebFrame* frame)
184 {
185 BSTR errorStr;
186 error->localizedDescription(&errorStr);
187
188 BSTR frameName;
189 frame->name(&frameName);
190
191 LOG_ERROR("called unableToImplementPolicyWithError:%S inFrame:%S", errorStr ? errorStr : TEXT(""), frameName ? frameName : TEXT(""));
192 SysFreeString(errorStr);
193 SysFreeString(frameName);
194
195 return S_OK;
196 }
197