1/* 2 * Copyright (C) 2005, 2008 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 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 14 * its contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#import "WebPluginContainerCheck.h" 30 31#import "WebFrameInternal.h" 32#import "WebPluginContainerPrivate.h" 33#import "WebPluginController.h" 34#import "WebPolicyDelegatePrivate.h" 35#import "WebView.h" 36#import "WebViewInternal.h" 37#import <Foundation/NSDictionary.h> 38#import <Foundation/NSURL.h> 39#import <Foundation/NSURLRequest.h> 40#import <WebCore/Frame.h> 41#import <WebCore/FrameLoader.h> 42#import <WebCore/FrameLoaderTypes.h> 43#import <WebCore/SecurityOrigin.h> 44#import <wtf/Assertions.h> 45#import <objc/objc-runtime.h> 46 47using namespace WebCore; 48 49@implementation WebPluginContainerCheck 50 51- (id)initWithRequest:(NSURLRequest *)request target:(NSString *)target resultObject:(id)obj selector:(SEL)selector controller:(id <WebPluginContainerCheckController>)controller contextInfo:(id)contextInfo /*optional*/ 52{ 53 if (!(self = [super init])) 54 return nil; 55 56 _request = [request copy]; 57 _target = [target copy]; 58 _resultObject = [obj retain]; 59 _resultSelector = selector; 60 _contextInfo = [contextInfo retain]; 61 62 // controller owns us so don't retain, to avoid cycle 63 _controller = controller; 64 65 return self; 66} 67 68+ (id)checkWithRequest:(NSURLRequest *)request target:(NSString *)target resultObject:(id)obj selector:(SEL)selector controller:(id <WebPluginContainerCheckController>)controller contextInfo:(id)contextInfo /*optional*/ 69{ 70 return [[[self alloc] initWithRequest:request target:target resultObject:obj selector:selector controller:controller contextInfo:contextInfo] autorelease]; 71} 72 73- (void)finalize 74{ 75 // mandatory to complete or cancel before releasing this object 76 ASSERT(_done); 77 [super finalize]; 78} 79 80- (void)dealloc 81{ 82 // mandatory to complete or cancel before releasing this object 83 ASSERT(_done); 84 [super dealloc]; 85} 86 87- (void)_continueWithPolicy:(PolicyAction)policy 88{ 89 if (_contextInfo) 90 ((void (*)(id, SEL, BOOL, id))objc_msgSend)(_resultObject, _resultSelector, (policy == PolicyUse), _contextInfo); 91 else 92 ((void (*)(id, SEL, BOOL))objc_msgSend)(_resultObject, _resultSelector, (policy == PolicyUse)); 93 94 // this will call indirectly call cancel 95 [_controller _webPluginContainerCancelCheckIfAllowedToLoadRequest:self]; 96} 97 98- (BOOL)_isForbiddenFileLoad 99{ 100 Frame* coreFrame = core([_controller webFrame]); 101 ASSERT(coreFrame); 102 if (!coreFrame->document()->securityOrigin()->canDisplay([_request URL])) { 103 [self _continueWithPolicy:PolicyIgnore]; 104 return YES; 105 } 106 107 return NO; 108} 109 110- (NSDictionary *)_actionInformationWithURL:(NSURL *)URL 111{ 112 return [NSDictionary dictionaryWithObjectsAndKeys: 113 [NSNumber numberWithInt:WebNavigationTypePlugInRequest], WebActionNavigationTypeKey, 114 [NSNumber numberWithInt:0], WebActionModifierFlagsKey, 115 URL, WebActionOriginalURLKey, 116 nil]; 117} 118 119- (void)_askPolicyDelegate 120{ 121 WebView *webView = [_controller webView]; 122 123 WebFrame *targetFrame; 124 if ([_target length] > 0) { 125 targetFrame = [[_controller webFrame] findFrameNamed:_target]; 126 } else { 127 targetFrame = [_controller webFrame]; 128 } 129 130 NSDictionary *action = [self _actionInformationWithURL:[_request URL]]; 131 132 _listener = [[WebPolicyDecisionListener alloc] _initWithTarget:self action:@selector(_continueWithPolicy:)]; 133 134 if (targetFrame == nil) { 135 // would open new window 136 [[webView _policyDelegateForwarder] webView:webView 137 decidePolicyForNewWindowAction:action 138 request:_request 139 newFrameName:_target 140 decisionListener:_listener]; 141 } else { 142 // would target existing frame 143 [[webView _policyDelegateForwarder] webView:webView 144 decidePolicyForNavigationAction:action 145 request:_request 146 frame:targetFrame 147 decisionListener:_listener]; 148 } 149} 150 151- (void)start 152{ 153 ASSERT(!_listener); 154 ASSERT(!_done); 155 156 if ([self _isForbiddenFileLoad]) 157 return; 158 159 [self _askPolicyDelegate]; 160} 161 162- (void)cancel 163{ 164 if (_done) 165 return; 166 167 [_request release]; 168 _request = nil; 169 170 [_target release]; 171 _target = nil; 172 173 [_listener _invalidate]; 174 [_listener release]; 175 _listener = nil; 176 177 [_resultObject autorelease]; 178 _resultObject = nil; 179 180 _controller = nil; 181 182 [_contextInfo release]; 183 _contextInfo = nil; 184 185 _done = YES; 186} 187 188- (id)contextInfo 189{ 190 return _contextInfo; 191} 192 193@end 194