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