[Cocoa] Expose WebContext::allowSpecificHTTPSCertificateForHost
[WebKit-https.git] / Source / WebKit2 / UIProcess / API / Cocoa / WKProcessGroup.mm
1 /*
2  * Copyright (C) 2011 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 INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "WKProcessGroupInternal.h"
28
29 #if WK_API_ENABLED
30
31 #import "APINavigationData.h"
32 #import "ObjCObjectGraph.h"
33 #import "WKAPICast.h"
34 #import "WKBrowsingContextControllerInternal.h"
35 #import "WKBrowsingContextHistoryDelegate.h"
36 #import "WKConnectionInternal.h"
37 #import "WKContext.h"
38 #import "WKNSString.h"
39 #import "WKNSURL.h"
40 #import "WKNavigationDataInternal.h"
41 #import "WKRetainPtr.h"
42 #import "WKStringCF.h"
43 #import "WeakObjCPtr.h"
44 #import "WebCertificateInfo.h"
45 #import "WebFrameProxy.h"
46 #import <wtf/RetainPtr.h>
47
48 #if PLATFORM(IOS)
49 #import "WKAPICast.h"
50 #import "WKGeolocationProviderIOS.h"
51 #import <WebCore/WebCoreThreadSystemInterface.h>
52 #endif
53
54 using namespace WebKit;
55
56 @implementation WKProcessGroup {
57     API::ObjectStorage<WebContext> _context;
58
59     WeakObjCPtr<id <WKProcessGroupDelegate>> _delegate;
60
61 #if PLATFORM(IOS)
62     RetainPtr<WKGeolocationProviderIOS> _geolocationProvider;
63 #endif // PLATFORM(IOS)
64 }
65
66 - (void)dealloc
67 {
68     _context->~WebContext();
69
70     [super dealloc];
71 }
72
73 static void didCreateConnection(WKContextRef, WKConnectionRef connectionRef, const void* clientInfo)
74 {
75     WKProcessGroup *processGroup = (WKProcessGroup *)clientInfo;
76     auto delegate = processGroup->_delegate.get();
77
78     if ([delegate respondsToSelector:@selector(processGroup:didCreateConnectionToWebProcessPlugIn:)])
79         [delegate processGroup:processGroup didCreateConnectionToWebProcessPlugIn:wrapper(*toImpl(connectionRef))];
80 }
81
82 static void setUpConnectionClient(WKProcessGroup *processGroup, WKContextRef contextRef)
83 {
84     WKContextConnectionClientV0 connectionClient;
85     memset(&connectionClient, 0, sizeof(connectionClient));
86
87     connectionClient.base.version = 0;
88     connectionClient.base.clientInfo = processGroup;
89     connectionClient.didCreateConnection = didCreateConnection;
90
91     WKContextSetConnectionClient(contextRef, &connectionClient.base);
92 }
93
94 static WKTypeRef getInjectedBundleInitializationUserData(WKContextRef, const void* clientInfo)
95 {
96     WKProcessGroup *processGroup = (WKProcessGroup *)clientInfo;
97     auto delegate = processGroup->_delegate.get();
98
99     if ([delegate respondsToSelector:@selector(processGroupWillCreateConnectionToWebProcessPlugIn:)]) {
100         RetainPtr<id> initializationUserData = [delegate processGroupWillCreateConnectionToWebProcessPlugIn:processGroup];
101         RefPtr<WebKit::ObjCObjectGraph> wkMessageBody = WebKit::ObjCObjectGraph::create(initializationUserData.get());
102         return (WKTypeRef)wkMessageBody.release().leakRef();
103     }
104
105     return 0;
106 }
107
108 static void setUpInectedBundleClient(WKProcessGroup *processGroup, WKContextRef contextRef)
109 {
110     WKContextInjectedBundleClientV1 injectedBundleClient;
111     memset(&injectedBundleClient, 0, sizeof(injectedBundleClient));
112
113     injectedBundleClient.base.version = 1;
114     injectedBundleClient.base.clientInfo = processGroup;
115     injectedBundleClient.getInjectedBundleInitializationUserData = getInjectedBundleInitializationUserData;
116
117     WKContextSetInjectedBundleClient(contextRef, &injectedBundleClient.base);
118 }
119
120 static void didNavigateWithNavigationData(WKContextRef, WKPageRef pageRef, WKNavigationDataRef navigationDataRef, WKFrameRef frameRef, const void*)
121 {
122     if (!toImpl(frameRef)->isMainFrame())
123         return;
124
125     WKBrowsingContextController *controller = wrapper(*toImpl(pageRef));
126     auto historyDelegate = controller->_historyDelegate.get();
127
128     if ([historyDelegate respondsToSelector:@selector(browsingContextController:didNavigateWithNavigationData:)])
129         [historyDelegate browsingContextController:controller didNavigateWithNavigationData:wrapper(*toImpl(navigationDataRef))];
130 }
131
132 static void didPerformClientRedirect(WKContextRef, WKPageRef pageRef, WKURLRef sourceURLRef, WKURLRef destinationURLRef, WKFrameRef frameRef, const void*)
133 {
134     if (!toImpl(frameRef)->isMainFrame())
135         return;
136
137     WKBrowsingContextController *controller = wrapper(*toImpl(pageRef));
138     auto historyDelegate = controller->_historyDelegate.get();
139
140     if ([historyDelegate respondsToSelector:@selector(browsingContextController:didPerformClientRedirectFromURL:toURL:)])
141         [historyDelegate browsingContextController:controller didPerformClientRedirectFromURL:wrapper(*toImpl(sourceURLRef)) toURL:wrapper(*toImpl(destinationURLRef))];
142 }
143
144 static void didPerformServerRedirect(WKContextRef, WKPageRef pageRef, WKURLRef sourceURLRef, WKURLRef destinationURLRef, WKFrameRef frameRef, const void*)
145 {
146     if (!toImpl(frameRef)->isMainFrame())
147         return;
148
149     WKBrowsingContextController *controller = wrapper(*toImpl(pageRef));
150     auto historyDelegate = controller->_historyDelegate.get();
151
152     if ([historyDelegate respondsToSelector:@selector(browsingContextController:didPerformServerRedirectFromURL:toURL:)])
153         [historyDelegate browsingContextController:controller didPerformServerRedirectFromURL:wrapper(*toImpl(sourceURLRef)) toURL:wrapper(*toImpl(destinationURLRef))];
154 }
155
156 static void didUpdateHistoryTitle(WKContextRef, WKPageRef pageRef, WKStringRef titleRef, WKURLRef urlRef, WKFrameRef frameRef, const void*)
157 {
158     if (!toImpl(frameRef)->isMainFrame())
159         return;
160
161     WKBrowsingContextController *controller = wrapper(*toImpl(pageRef));
162     auto historyDelegate = controller->_historyDelegate.get();
163
164     if ([historyDelegate respondsToSelector:@selector(browsingContextController:didUpdateHistoryTitle:forURL:)])
165         [historyDelegate browsingContextController:controller didUpdateHistoryTitle:wrapper(*toImpl(titleRef)) forURL:wrapper(*toImpl(urlRef))];
166 }
167
168 static void setUpHistoryClient(WKProcessGroup *processGroup, WKContextRef contextRef)
169 {
170     WKContextHistoryClientV0 historyClient;
171     memset(&historyClient, 0, sizeof(historyClient));
172
173     historyClient.base.version = 0;
174     historyClient.base.clientInfo = processGroup;
175     historyClient.didNavigateWithNavigationData = didNavigateWithNavigationData;
176     historyClient.didPerformClientRedirect = didPerformClientRedirect;
177     historyClient.didPerformServerRedirect = didPerformServerRedirect;
178     historyClient.didUpdateHistoryTitle = didUpdateHistoryTitle;
179
180     WKContextSetHistoryClient(contextRef, &historyClient.base);
181 }
182
183 - (id)init
184 {
185     return [self initWithInjectedBundleURL:nil];
186 }
187
188 - (id)initWithInjectedBundleURL:(NSURL *)bundleURL
189 {
190     self = [super init];
191     if (!self)
192         return nil;
193
194 #if PLATFORM(IOS)
195     // FIXME: Remove once <rdar://problem/15256572> is fixed.
196     InitWebCoreThreadSystemInterface();
197 #endif
198
199     API::Object::constructInWrapper<WebContext>(self, bundleURL ? String([bundleURL path]) : String());
200
201     setUpConnectionClient(self, toAPI(_context.get()));
202     setUpInectedBundleClient(self, toAPI(_context.get()));
203     setUpHistoryClient(self, toAPI(_context.get()));
204 #if PLATFORM(IOS)
205     _context->setUsesNetworkProcess(true);
206 #endif
207
208     return self;
209 }
210
211 - (id <WKProcessGroupDelegate>)delegate
212 {
213     return _delegate.getAutoreleased();
214 }
215
216 - (void)setDelegate:(id <WKProcessGroupDelegate>)delegate
217 {
218     _delegate = delegate;
219 }
220
221 #pragma mark WKObject protocol implementation
222
223 - (API::Object&)_apiObject
224 {
225     return *_context;
226 }
227
228 @end
229
230 @implementation WKProcessGroup (Private)
231
232 - (WKContextRef)_contextRef
233 {
234     return toAPI(_context.get());
235 }
236
237 - (void)_setAllowsSpecificHTTPSCertificate:(NSArray *)certificateChain forHost:(NSString *)host
238 {
239     _context->allowSpecificHTTPSCertificateForHost(WebCertificateInfo::create(WebCore::CertificateInfo((CFArrayRef)certificateChain)).get(), host);
240 }
241
242 #if PLATFORM(IOS)
243 - (WKGeolocationProviderIOS *)_geolocationProvider
244 {
245     if (!_geolocationProvider)
246         _geolocationProvider = adoptNS([[WKGeolocationProviderIOS alloc] initWithContext:_context.get()]);
247     return _geolocationProvider.get();
248 }
249 #endif // PLATFORM(IOS)
250
251 @end
252
253 #endif // WK_API_ENABLED