Move NetworkStorageSession ownership to NetworkProcess
[WebKit-https.git] / Source / WebCore / platform / network / curl / CurlResourceHandleDelegate.cpp
1 /*
2  * Copyright (C) 2004, 2006 Apple Inc.  All rights reserved.
3  * Copyright (C) 2005, 2006 Michael Emmel mike.emmel@gmail.com
4  * Copyright (C) 2017 Sony Interactive Entertainment Inc.
5  * All rights reserved.
6  * Copyright (C) 2017 NAVER Corp.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
21  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "CurlResourceHandleDelegate.h"
32
33 #include "CurlCacheManager.h"
34 #include "CurlRequest.h"
35 #include "NetworkStorageSession.h"
36 #include "ResourceHandle.h"
37 #include "ResourceHandleClient.h"
38 #include "ResourceHandleInternal.h"
39
40 #include <wtf/CompletionHandler.h>
41
42 #if USE(CURL)
43
44 namespace WebCore {
45
46 CurlResourceHandleDelegate::CurlResourceHandleDelegate(ResourceHandle& handle)
47     : m_handle(handle)
48 {
49
50 }
51
52 void CurlResourceHandleDelegate::ref()
53 {
54     m_handle.ref();
55 }
56
57 void CurlResourceHandleDelegate::deref()
58 {
59     m_handle.deref();
60 }
61
62 bool CurlResourceHandleDelegate::cancelledOrClientless()
63 {
64     return m_handle.cancelledOrClientless();
65 }
66
67 ResourceHandleClient* CurlResourceHandleDelegate::client() const
68 {
69     return m_handle.client();
70 }
71
72 ResourceHandleInternal* CurlResourceHandleDelegate::d()
73 {
74     return m_handle.getInternal();
75 }
76
77 void CurlResourceHandleDelegate::curlDidSendData(CurlRequest& request, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
78 {
79     UNUSED_PARAM(request);
80     ASSERT(isMainThread());
81
82     if (cancelledOrClientless())
83         return;
84
85     client()->didSendData(&m_handle, bytesSent, totalBytesToBeSent);
86 }
87
88 static void handleCookieHeaders(const CurlResponse& response)
89 {
90     static const auto setCookieHeader = "set-cookie: ";
91
92     const auto& storageSession = *d()->m_context->storageSession(PAL::SessionID::defaultSessionID());
93     const auto& cookieJar = storageSession.cookieStorage();
94     for (const auto& header : response.headers) {
95         if (header.startsWithIgnoringASCIICase(setCookieHeader)) {
96             const auto contents = header.right(header.length() - strlen(setCookieHeader));
97             cookieJar.setCookiesFromHTTPResponse(storageSession, response.url, contents);
98         }
99     }
100 }
101
102 void CurlResourceHandleDelegate::curlDidReceiveResponse(CurlRequest& request, const CurlResponse& receivedResponse)
103 {
104     ASSERT(isMainThread());
105     ASSERT(!d()->m_defersLoading);
106
107     if (cancelledOrClientless())
108         return;
109
110     m_response = ResourceResponse(receivedResponse);
111
112     m_response.setCertificateInfo(request.certificateInfo().isolatedCopy());
113     m_response.setDeprecatedNetworkLoadMetrics(request.networkLoadMetrics().isolatedCopy());
114
115     handleCookieHeaders(receivedResponse);
116
117     if (m_response.shouldRedirect()) {
118         m_handle.willSendRequest();
119         return;
120     }
121
122     if (m_response.isUnauthorized() && receivedResponse.availableHttpAuth) {
123         AuthenticationChallenge challenge(receivedResponse, d()->m_authFailureCount, m_response, &m_handle);
124         m_handle.didReceiveAuthenticationChallenge(challenge);
125         d()->m_authFailureCount++;
126         return;
127     }
128
129     if (m_response.isNotModified()) {
130         URL cacheUrl = m_response.url();
131         cacheUrl.removeFragmentIdentifier();
132
133         if (CurlCacheManager::singleton().getCachedResponse(cacheUrl, m_response)) {
134             if (d()->m_addedCacheValidationHeaders) {
135                 m_response.setHTTPStatusCode(200);
136                 m_response.setHTTPStatusText("OK");
137             }
138         }
139     }
140
141     CurlCacheManager::singleton().didReceiveResponse(m_handle, m_response);
142
143     m_handle.didReceiveResponse(ResourceResponse(m_response), [this, protectedHandle = makeRef(m_handle)] {
144         m_handle.continueAfterDidReceiveResponse();
145     });
146 }
147
148 void CurlResourceHandleDelegate::curlDidReceiveBuffer(CurlRequest& request, Ref<SharedBuffer>&& buffer)
149 {
150     UNUSED_PARAM(request);
151     ASSERT(isMainThread());
152
153     if (cancelledOrClientless())
154         return;
155
156     CurlCacheManager::singleton().didReceiveData(m_handle, buffer->data(), buffer->size());
157     client()->didReceiveBuffer(&m_handle, WTFMove(buffer), buffer->size());
158 }
159
160 void CurlResourceHandleDelegate::curlDidComplete(CurlRequest& request)
161 {
162     ASSERT(isMainThread());
163
164     if (cancelledOrClientless())
165         return;
166
167     m_response.setDeprecatedNetworkLoadMetrics(request.networkLoadMetrics().isolatedCopy());
168
169     CurlCacheManager::singleton().didFinishLoading(m_handle);
170     client()->didFinishLoading(&m_handle);
171 }
172
173 void CurlResourceHandleDelegate::curlDidFailWithError(CurlRequest& request, const ResourceError& resourceError)
174 {
175     UNUSED_PARAM(request);
176     ASSERT(isMainThread());
177
178     if (cancelledOrClientless())
179         return;
180
181     CurlCacheManager::singleton().didFail(m_handle);
182     client()->didFail(&m_handle, resourceError);
183 }
184
185
186 } // namespace WebCore
187
188 #endif