1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/*
2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without
7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions
8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * are met:
9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 1.  Redistributions of source code must retain the above copyright
11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     notice, this list of conditions and the following disclaimer.
12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 2.  Redistributions in binary form must reproduce the above copyright
13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     notice, this list of conditions and the following disclaimer in the
14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     documentation and/or other materials provided with the distribution.
15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     its contributors may be used to endorse or promote products derived
17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     from this software without specific prior written permission.
18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */
30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "config.h"
32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "PolicyChecker.h"
33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "DocumentLoader.h"
35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FormState.h"
36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "Frame.h"
37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FrameLoader.h"
38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "FrameLoaderClient.h"
39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "HTMLFormElement.h"
40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore {
42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockPolicyChecker::PolicyChecker(Frame* frame)
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    : m_frame(frame)
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_delegateIsDecidingNavigationPolicy(false)
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_delegateIsHandlingUnimplementablePolicy(false)
47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    , m_loadType(FrameLoadTypeStandard)
48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::checkNavigationPolicy(const ResourceRequest& newRequest, NavigationPolicyDecisionFunction function, void* argument)
52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    checkNavigationPolicy(newRequest, m_frame->loader()->activeDocumentLoader(), 0, function, argument);
54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::checkNavigationPolicy(const ResourceRequest& request, DocumentLoader* loader,
57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    PassRefPtr<FormState> formState, NavigationPolicyDecisionFunction function, void* argument)
58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    NavigationAction action = loader->triggeringAction();
60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (action.isEmpty()) {
61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        action = NavigationAction(request.url(), NavigationTypeOther);
62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        loader->setTriggeringAction(action);
63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // Don't ask more than once for the same request or if we are loading an empty URL.
66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // This avoids confusion on the part of the client.
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (equalIgnoringHeaderFields(request, loader->lastCheckedRequest()) || (!request.isNull() && request.url().isEmpty())) {
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function(argument, request, 0, true);
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        loader->setLastCheckedRequest(request);
70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // We are always willing to show alternate content for unreachable URLs;
74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // treat it like a reload so it maintains the right state for b/f list.
75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    if (loader->substituteData().isValid() && !loader->substituteData().failingURL().isEmpty()) {
76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (isBackForwardLoadType(m_loadType))
77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_loadType = FrameLoadTypeReload;
78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function(argument, request, 0, true);
79231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return;
80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    loader->setLastCheckedRequest(request);
83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.set(request, formState.get(), function, argument);
85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_delegateIsDecidingNavigationPolicy = true;
87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_frame->loader()->client()->dispatchDecidePolicyForNavigationAction(&PolicyChecker::continueAfterNavigationPolicy,
88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        action, request, formState);
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_delegateIsDecidingNavigationPolicy = false;
90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::checkNewWindowPolicy(const NavigationAction& action, NewWindowPolicyDecisionFunction function,
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, void* argument)
94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
95e14391e94c850b8bd03680c23b38978db68687a8John Reck    m_callback.set(request, formState, frameName, action, function, argument);
96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_frame->loader()->client()->dispatchDecidePolicyForNewWindowAction(&PolicyChecker::continueAfterNewWindowPolicy,
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        action, request, formState, frameName);
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
10081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid PolicyChecker::checkContentPolicy(const ResourceResponse& response, ContentPolicyDecisionFunction function, void* argument)
101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.set(function, argument);
10381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    m_frame->loader()->client()->dispatchDecidePolicyForResponse(&PolicyChecker::continueAfterContentPolicy,
10481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch        response, m_frame->loader()->activeDocumentLoader()->request());
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::cancelCheck()
108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_frame->loader()->client()->cancelPolicyCheck();
110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.clear();
111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::stopCheck()
114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_frame->loader()->client()->cancelPolicyCheck();
116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    PolicyCallback callback = m_callback;
117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.clear();
118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    callback.cancel();
119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::cannotShowMIMEType(const ResourceResponse& response)
122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    handleUnimplementablePolicy(m_frame->loader()->client()->cannotShowMIMETypeError(response));
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::continueLoadAfterWillSubmitForm(PolicyAction)
127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // See header file for an explaination of why this function
129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    // isn't like the others.
130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_frame->loader()->continueLoadAfterWillSubmitForm();
131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
132231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::continueAfterNavigationPolicy(PolicyAction policy)
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    PolicyCallback callback = m_callback;
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.clear();
137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    bool shouldContinue = policy == PolicyUse;
139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    switch (policy) {
141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case PolicyIgnore:
142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            callback.clearRequest();
143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case PolicyDownload:
145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_frame->loader()->client()->startDownload(callback.request());
146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            callback.clearRequest();
147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case PolicyUse: {
149231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ResourceRequest request(callback.request());
150231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!m_frame->loader()->client()->canHandleRequest(request)) {
152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                handleUnimplementablePolicy(m_frame->loader()->cannotShowURLError(callback.request()));
153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                callback.clearRequest();
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                shouldContinue = false;
155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    callback.call(shouldContinue);
161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::continueAfterNewWindowPolicy(PolicyAction policy)
164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    PolicyCallback callback = m_callback;
166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.clear();
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    switch (policy) {
169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case PolicyIgnore:
170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            callback.clearRequest();
171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case PolicyDownload:
173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            m_frame->loader()->client()->startDownload(callback.request());
174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            callback.clearRequest();
175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        case PolicyUse:
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            break;
178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    callback.call(policy == PolicyUse);
181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::continueAfterContentPolicy(PolicyAction policy)
184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    PolicyCallback callback = m_callback;
186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_callback.clear();
187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    callback.call(policy);
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid PolicyChecker::handleUnimplementablePolicy(const ResourceError& error)
191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_delegateIsHandlingUnimplementablePolicy = true;
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_frame->loader()->client()->dispatchUnableToImplementPolicy(error);
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    m_delegateIsHandlingUnimplementablePolicy = false;
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore
198