321634c75e6505f67cb2445c0d585e7faa45d907
[WebKit.git] / Source / WebKit / UIProcess / API / Cocoa / WKHTTPCookieStore.mm
1 /*
2  * Copyright (C) 2017 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 "WKHTTPCookieStoreInternal.h"
28
29 #if WK_API_ENABLED
30
31 #import "HTTPCookieAcceptPolicy.h"
32 #import "WeakObjCPtr.h"
33 #import <WebCore/CFNetworkSPI.h>
34 #import <WebCore/Cookie.h>
35 #import <WebCore/URL.h>
36 #import <wtf/HashMap.h>
37 #import <wtf/RetainPtr.h>
38
39 static NSArray<NSHTTPCookie *> *coreCookiesToNSCookies(const Vector<WebCore::Cookie>& coreCookies)
40 {
41     NSMutableArray<NSHTTPCookie *> *nsCookies = [NSMutableArray arrayWithCapacity:coreCookies.size()];
42
43     for (auto& cookie : coreCookies)
44         [nsCookies addObject:(NSHTTPCookie *)cookie];
45
46     return nsCookies;
47 }
48
49 class WKHTTPCookieStoreObserver : public API::HTTPCookieStore::Observer {
50 public:
51     explicit WKHTTPCookieStoreObserver(id<WKHTTPCookieStoreObserver> observer)
52         : m_observer(observer)
53     {
54     }
55
56 private:
57     void cookiesDidChange(API::HTTPCookieStore& cookieStore) final
58     {
59         [m_observer.get() cookiesDidChangeInCookieStore:WebKit::wrapper(cookieStore)];
60     }
61
62     WebKit::WeakObjCPtr<id<WKHTTPCookieStoreObserver>> m_observer;
63 };
64
65 @implementation WKHTTPCookieStore {
66     HashMap<id<WKHTTPCookieStoreObserver>, std::unique_ptr<WKHTTPCookieStoreObserver>> _observers;
67 }
68
69 - (void)dealloc
70 {
71     for (auto& observer : _observers.values())
72         _cookieStore->unregisterObserver(*observer);
73
74     _cookieStore->API::HTTPCookieStore::~HTTPCookieStore();
75
76     [super dealloc];
77 }
78
79 - (void)getAllCookies:(void (^)(NSArray<NSHTTPCookie *> *))completionHandler
80 {
81     _cookieStore->cookies([handler = adoptNS([completionHandler copy])](const Vector<WebCore::Cookie>& cookies) {
82         auto rawHandler = (void (^)(NSArray<NSHTTPCookie *> *))handler.get();
83         rawHandler(coreCookiesToNSCookies(cookies));
84     });
85 }
86
87 - (void)setCookie:(NSHTTPCookie *)cookie completionHandler:(void (^)())completionHandler
88 {
89     _cookieStore->setCookie(cookie, [handler = adoptNS([completionHandler copy])]() {
90         auto rawHandler = (void (^)())handler.get();
91         if (rawHandler)
92             rawHandler();
93     });
94
95 }
96
97 - (void)deleteCookie:(NSHTTPCookie *)cookie completionHandler:(void (^)())completionHandler
98 {
99     _cookieStore->deleteCookie(cookie, [handler = adoptNS([completionHandler copy])]() {
100         auto rawHandler = (void (^)())handler.get();
101         if (rawHandler)
102             rawHandler();
103     });
104 }
105
106 - (void)addObserver:(id<WKHTTPCookieStoreObserver>)observer
107 {
108     auto result = _observers.add(observer, nullptr);
109     if (!result.isNewEntry)
110         return;
111
112     result.iterator->value = std::make_unique<WKHTTPCookieStoreObserver>(observer);
113     _cookieStore->registerObserver(*result.iterator->value);
114 }
115
116 - (void)removeObserver:(id<WKHTTPCookieStoreObserver>)observer
117 {
118     auto result = _observers.take(observer);
119     if (!result)
120         return;
121
122     _cookieStore->unregisterObserver(*result);
123 }
124
125 #pragma mark WKObject protocol implementation
126
127 - (API::Object&)_apiObject
128 {
129     return *_cookieStore;
130 }
131
132 @end
133
134 #endif