Clean up which storage cookie jar functions use
[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 "CookieStorage.h"
28
29 #include "CookieStorageCFNet.h"
30
31 #include "ResourceHandle.h"
32 #include <wtf/MainThread.h>
33
34 #if PLATFORM(MAC)
35 #include "WebCoreSystemInterface.h"
36 #elif PLATFORM(WIN)
37 #include "LoaderRunLoopCF.h"
38 #include <CFNetwork/CFHTTPCookiesPriv.h>
39 #include <WebKitSystemInterface/WebKitSystemInterface.h>
40 #endif
41
42 #if USE(PLATFORM_STRATEGIES)
43 #include "CookiesStrategy.h"
44 #include "PlatformStrategies.h"
45 #endif
46
47 namespace WebCore {
48
49 #if PLATFORM(WIN)
50
51 static RetainPtr<CFHTTPCookieStorageRef>& cookieStorageOverride()
52 {
53     DEFINE_STATIC_LOCAL(RetainPtr<CFHTTPCookieStorageRef>, cookieStorage, ());
54     return cookieStorage;
55 }
56
57 #endif
58
59 RetainPtr<CFHTTPCookieStorageRef> currentCFHTTPCookieStorage()
60 {
61 #if PLATFORM(WIN)
62     if (RetainPtr<CFHTTPCookieStorageRef>& override = cookieStorageOverride())
63         return override;
64 #endif
65
66     if (CFURLStorageSessionRef session = ResourceHandle::currentStorageSession())
67         return RetainPtr<CFHTTPCookieStorageRef>(AdoptCF, wkCopyHTTPCookieStorage(session));
68
69 #if USE(CFNETWORK)
70     return wkGetDefaultHTTPCookieStorage();
71 #else
72     // When using NSURLConnection, we also use its shared cookie storage.
73     return 0;
74 #endif
75 }
76
77 RetainPtr<CFHTTPCookieStorageRef> defaultCFHTTPCookieStorage()
78 {
79 #if PLATFORM(WIN)
80     if (RetainPtr<CFHTTPCookieStorageRef>& override = cookieStorageOverride())
81         return override;
82 #endif
83
84     if (CFURLStorageSessionRef session = ResourceHandle::defaultStorageSession())
85         return RetainPtr<CFHTTPCookieStorageRef>(AdoptCF, wkCopyHTTPCookieStorage(session));
86
87 #if USE(CFNETWORK)
88     return wkGetDefaultHTTPCookieStorage();
89 #else
90     // When using NSURLConnection, we also use its shared cookie storage.
91     return 0;
92 #endif
93 }
94
95 #if PLATFORM(WIN)
96
97 void overrideCookieStorage(CFHTTPCookieStorageRef cookieStorage)
98 {
99     ASSERT(isMainThread());
100     // FIXME: Why don't we retain it? The only caller is an API method that takes cookie storage as a raw argument.
101     cookieStorageOverride().adoptCF(cookieStorage);
102 }
103
104 static void notifyCookiesChangedOnMainThread(void*)
105 {
106     ASSERT(isMainThread());
107
108 #if USE(PLATFORM_STRATEGIES)
109     platformStrategies()->cookiesStrategy()->notifyCookiesChanged();
110 #endif
111 }
112
113 static void notifyCookiesChanged(CFHTTPCookieStorageRef, void *)
114 {
115     callOnMainThread(notifyCookiesChangedOnMainThread, 0);
116 }
117
118 static inline CFRunLoopRef cookieStorageObserverRunLoop()
119 {
120     // We're using the loader run loop because we need a CFRunLoop to 
121     // call the CFNetwork cookie storage APIs with. Re-using the loader
122     // run loop is less overhead than starting a new thread to just listen
123     // for changes in cookies.
124     
125     // FIXME: The loaderRunLoop function name should be a little more generic.
126     return loaderRunLoop();
127 }
128
129 void startObservingCookieChanges()
130 {
131     ASSERT(isMainThread());
132
133     CFRunLoopRef runLoop = cookieStorageObserverRunLoop();
134     ASSERT(runLoop);
135
136     RetainPtr<CFHTTPCookieStorageRef> cookieStorage = defaultCFHTTPCookieStorage();
137     ASSERT(cookieStorage);
138
139     CFHTTPCookieStorageScheduleWithRunLoop(cookieStorage.get(), runLoop, kCFRunLoopCommonModes);
140     CFHTTPCookieStorageAddObserver(cookieStorage.get(), runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0);
141 }
142
143 void stopObservingCookieChanges()
144 {
145     ASSERT(isMainThread());
146
147     CFRunLoopRef runLoop = cookieStorageObserverRunLoop();
148     ASSERT(runLoop);
149
150     RetainPtr<CFHTTPCookieStorageRef> cookieStorage = defaultCFHTTPCookieStorage();
151     ASSERT(cookieStorage);
152
153     CFHTTPCookieStorageRemoveObserver(cookieStorage.get(), runLoop, kCFRunLoopDefaultMode, notifyCookiesChanged, 0);
154     CFHTTPCookieStorageUnscheduleFromRunLoop(cookieStorage.get(), runLoop, kCFRunLoopCommonModes);
155 }
156
157 #endif // PLATFORM(WIN)
158
159 } // namespace WebCore