2 * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include "PolicyChecker.h"
34 #include "DocumentLoader.h"
35 #include "FormState.h"
37 #include "FrameLoader.h"
38 #include "FrameLoaderClient.h"
39 #include "HTMLFormElement.h"
40 #include "SecurityOrigin.h"
44 PolicyChecker::PolicyChecker(Frame* frame)
46 , m_delegateIsDecidingNavigationPolicy(false)
47 , m_delegateIsHandlingUnimplementablePolicy(false)
48 , m_loadType(FrameLoadTypeStandard)
52 void PolicyChecker::checkNavigationPolicy(const ResourceRequest& newRequest, NavigationPolicyDecisionFunction function, void* argument)
54 checkNavigationPolicy(newRequest, m_frame->loader()->activeDocumentLoader(), 0, function, argument);
57 void PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, DocumentLoader* loader,
58 PassRefPtr<FormState> formState, NavigationPolicyDecisionFunction function, void* argument)
60 NavigationAction action = loader->triggeringAction();
61 if (action.isEmpty()) {
62 action = NavigationAction(request, NavigationTypeOther);
63 loader->setTriggeringAction(action);
66 // Don't ask more than once for the same request or if we are loading an empty URL.
67 // This avoids confusion on the part of the client.
68 if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) {
69 function(argument, request, 0, true);
70 loader->setLastCheckedRequest(request);
74 // We are always willing to show alternate content for unreachable URLs;
75 // treat it like a reload so it maintains the right state for b/f list.
76 if (loader->substituteData().isValid() && !loader->substituteData().failingURL().isEmpty()) {
77 if (isBackForwardLoadType(m_loadType))
78 m_loadType = FrameLoadTypeReload;
79 function(argument, request, 0, true);
83 loader->setLastCheckedRequest(request);
85 m_callback.set(request, formState.get(), function, argument);
87 m_delegateIsDecidingNavigationPolicy = true;
88 m_frame->loader()->client()->dispatchDecidePolicyForNavigationAction(&PolicyChecker::continueAfterNavigationPolicy,
89 action, request, formState);
90 m_delegateIsDecidingNavigationPolicy = false;
93 void PolicyChecker::checkNewWindowPolicy(const NavigationAction& action, NewWindowPolicyDecisionFunction function,
94 const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, void* argument)
96 if (m_frame->document() && m_frame->document()->isSandboxed(SandboxPopups))
97 return continueAfterNavigationPolicy(PolicyIgnore);
99 m_callback.set(request, formState, frameName, action, function, argument);
100 m_frame->loader()->client()->dispatchDecidePolicyForNewWindowAction(&PolicyChecker::continueAfterNewWindowPolicy,
101 action, request, formState, frameName);
104 void PolicyChecker::checkContentPolicy(const ResourceResponse& response, ContentPolicyDecisionFunction function, void* argument)
106 m_callback.set(function, argument);
107 m_frame->loader()->client()->dispatchDecidePolicyForResponse(&PolicyChecker::continueAfterContentPolicy,
108 response, m_frame->loader()->activeDocumentLoader()->request());
111 void PolicyChecker::cancelCheck()
113 m_frame->loader()->client()->cancelPolicyCheck();
117 void PolicyChecker::stopCheck()
119 m_frame->loader()->client()->cancelPolicyCheck();
120 PolicyCallback callback = m_callback;
125 void PolicyChecker::cannotShowMIMEType(const ResourceResponse& response)
127 handleUnimplementablePolicy(m_frame->loader()->client()->cannotShowMIMETypeError(response));
130 void PolicyChecker::continueLoadAfterWillSubmitForm(PolicyAction)
132 // See header file for an explaination of why this function
133 // isn't like the others.
134 m_frame->loader()->continueLoadAfterWillSubmitForm();
137 void PolicyChecker::continueAfterNavigationPolicy(PolicyAction policy)
139 PolicyCallback callback = m_callback;
142 bool shouldContinue = policy == PolicyUse;
146 callback.clearRequest();
148 case PolicyDownload: {
149 ResourceRequest request = callback.request();
150 m_frame->loader()->setOriginalURLForDownloadRequest(request);
151 m_frame->loader()->client()->startDownload(request);
152 callback.clearRequest();
156 ResourceRequest request(callback.request());
158 if (!m_frame->loader()->client()->canHandleRequest(request)) {
159 handleUnimplementablePolicy(m_frame->loader()->client()->cannotShowURLError(callback.request()));
160 callback.clearRequest();
161 shouldContinue = false;
167 callback.call(shouldContinue);
170 void PolicyChecker::continueAfterNewWindowPolicy(PolicyAction policy)
172 PolicyCallback callback = m_callback;
177 callback.clearRequest();
180 m_frame->loader()->client()->startDownload(callback.request());
181 callback.clearRequest();
187 callback.call(policy == PolicyUse);
190 void PolicyChecker::continueAfterContentPolicy(PolicyAction policy)
192 PolicyCallback callback = m_callback;
194 callback.call(policy);
197 void PolicyChecker::handleUnimplementablePolicy(const ResourceError& error)
199 m_delegateIsHandlingUnimplementablePolicy = true;
200 m_frame->loader()->client()->dispatchUnableToImplementPolicy(error);
201 m_delegateIsHandlingUnimplementablePolicy = false;
204 } // namespace WebCore