WebKit2: Use CFNetwork Sessions API.
[WebKit-https.git] / Source / WebCore / platform / network / cf / CookieStorageCFNet.cpp
1 /*
2  * Copyright (C) 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  * 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 "CookieStorageCFNet.h"
28
29 #if USE(CFNETWORK)
30
31 #include "LoaderRunLoopCF.h"
32 #include "ResourceHandle.h"
33 #include <CFNetwork/CFHTTPCookiesPriv.h>
34 #include <WebKitSystemInterface/WebKitSystemInterface.h>
35 #include <wtf/MainThread.h>
36 #include <wtf/RetainPtr.h>
37
38 #if USE(PLATFORM_STRATEGIES)
39 #include "CookiesStrategy.h"
40 #include "PlatformStrategies.h"
41 #endif
42
43 namespace WebCore {
44
45 static RetainPtr<CFHTTPCookieStorageRef>& privateBrowsingCookieStorage()
46 {
47     DEFINE_STATIC_LOCAL(RetainPtr<CFHTTPCookieStorageRef>, cookieStorage, ());
48     return cookieStorage;
49 }
50
51 CFHTTPCookieStorageRef currentCookieStorage()
52 {
53     ASSERT(isMainThread());
54
55     if (CFHTTPCookieStorageRef privateCookieStorage = privateBrowsingCookieStorage().get())
56         return privateCookieStorage;
57     return wkGetDefaultHTTPCookieStorage();
58 }
59
60 void setCurrentCookieStorage(CFHTTPCookieStorageRef cookieStorage)
61 {
62     ASSERT(isMainThread());
63
64     privateBrowsingCookieStorage().adoptCF(cookieStorage);
65 }
66
67 void setCookieStoragePrivateBrowsingEnabled(bool enabled)
68 {
69     ASSERT(isMainThread());
70
71     if (!enabled) {
72         privateBrowsingCookieStorage() = nullptr;
73         return;
74     }
75
76 #if USE(CFURLSTORAGESESSIONS)
77     privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(ResourceHandle::privateBrowsingStorageSession()));
78 #else
79     privateBrowsingCookieStorage().adoptCF(wkCreatePrivateInMemoryHTTPCookieStorage(0));
80 #endif
81 }
82
83 static void notifyCookiesChangedOnMainThread(void* context)
84 {
85     ASSERT(isMainThread());
86
87 #if USE(PLATFORM_STRATEGIES)
88     platformStrategies()->cookiesStrategy()->notifyCookiesChanged();
89 #endif
90 }
91
92 static void notifyCookiesChanged(CFHTTPCookieStorageRef inStorage, void *context)
93 {
94     callOnMainThread(notifyCookiesChangedOnMainThread, 0);
95 }
96
97 static inline CFRunLoopRef cookieStorageObserverRunLoop()
98 {
99     // We're using the loader run loop because we need a CFRunLoop to 
100     // call the CFNetwork cookie storage APIs with. Re-using the loader
101     // run loop is less overhead than starting a new thread to just listen
102     // for changes in cookies.
103     
104     // FIXME: The loaderRunLoop function name should be a little more generic.
105     return loaderRunLoop();
106 }
107
108 void startObservingCookieChanges()
109 {
110     ASSERT(isMainThread());
111
112     CFRunLoopRef runLoop = cookieStorageObserverRunLoop();
113     ASSERT(runLoop);
114
115     CFHTTPCookieStorageRef cookieStorage = currentCookieStorage();
116     ASSERT(cookieStorage);
117
118     CFHTTPCookieStorageScheduleWithRunLoop(cookieStorage, runLoop, kCFRunLoopCommonModes);
119     CFHTTPCookieStorageAddObserver(cookieStorage, runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0);
120 }
121
122 void stopObservingCookieChanges()
123 {
124     ASSERT(isMainThread());
125
126     CFRunLoopRef runLoop = cookieStorageObserverRunLoop();
127     ASSERT(runLoop);
128
129     CFHTTPCookieStorageRef cookieStorage = currentCookieStorage();
130     ASSERT(cookieStorage);
131
132     CFHTTPCookieStorageRemoveObserver(cookieStorage, runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0);
133     CFHTTPCookieStorageUnscheduleFromRunLoop(cookieStorage, runLoop, kCFRunLoopCommonModes);
134 }
135
136 } // namespace WebCore
137
138 #endif // USE(CFNETWORK)