Clean up AuthenticationChallengeProxy
[WebKit-https.git] / Source / WebKit / UIProcess / Downloads / DownloadProxy.cpp
1 /*
2  * Copyright (C) 2010-2016 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 #include "config.h"
27 #include "DownloadProxy.h"
28
29 #include "APIData.h"
30 #include "APIDownloadClient.h"
31 #include "AuthenticationChallengeProxy.h"
32 #include "DataReference.h"
33 #include "DownloadProxyMap.h"
34 #include "NetworkProcessMessages.h"
35 #include "NetworkProcessProxy.h"
36 #include "WebProcessMessages.h"
37 #include "WebProcessPool.h"
38 #include "WebProtectionSpace.h"
39 #include <WebCore/FileSystem.h>
40 #include <WebCore/MIMETypeRegistry.h>
41 #include <wtf/text/CString.h>
42 #include <wtf/text/WTFString.h>
43
44 namespace WebKit {
45 using namespace WebCore;
46
47 static uint64_t generateDownloadID()
48 {
49     static uint64_t uniqueDownloadID = 0;
50     return ++uniqueDownloadID;
51 }
52     
53 Ref<DownloadProxy> DownloadProxy::create(DownloadProxyMap& downloadProxyMap, WebProcessPool& processPool, const ResourceRequest& resourceRequest)
54 {
55     return adoptRef(*new DownloadProxy(downloadProxyMap, processPool, resourceRequest));
56 }
57
58 DownloadProxy::DownloadProxy(DownloadProxyMap& downloadProxyMap, WebProcessPool& processPool, const ResourceRequest& resourceRequest)
59     : m_downloadProxyMap(downloadProxyMap)
60     , m_processPool(&processPool)
61     , m_downloadID(generateDownloadID())
62     , m_request(resourceRequest)
63 {
64 }
65
66 DownloadProxy::~DownloadProxy()
67 {
68     ASSERT(!m_processPool);
69 }
70
71 void DownloadProxy::cancel()
72 {
73     if (!m_processPool)
74         return;
75
76     if (NetworkProcessProxy* networkProcess = m_processPool->networkProcess())
77         networkProcess->send(Messages::NetworkProcess::CancelDownload(m_downloadID), 0);
78 }
79
80 void DownloadProxy::invalidate()
81 {
82     ASSERT(m_processPool);
83     m_processPool = nullptr;
84 }
85
86 void DownloadProxy::processDidClose()
87 {
88     if (!m_processPool)
89         return;
90
91     m_processPool->downloadClient().processDidCrash(*m_processPool, *this);
92 }
93
94 WebPageProxy* DownloadProxy::originatingPage() const
95 {
96     return m_originatingPage.get();
97 }
98
99 void DownloadProxy::setOriginatingPage(WebPageProxy* page)
100 {
101     m_originatingPage = makeWeakPtr(page);
102 }
103
104 void DownloadProxy::didStart(const ResourceRequest& request, const String& suggestedFilename)
105 {
106     m_request = request;
107     m_suggestedFilename = suggestedFilename;
108
109     if (m_redirectChain.isEmpty() || m_redirectChain.last() != request.url())
110         m_redirectChain.append(request.url());
111
112     if (!m_processPool)
113         return;
114
115     m_processPool->downloadClient().didStart(*m_processPool, *this);
116 }
117
118 void DownloadProxy::didReceiveAuthenticationChallenge(AuthenticationChallenge&& authenticationChallenge, uint64_t challengeID)
119 {
120     if (!m_processPool)
121         return;
122
123     auto authenticationChallengeProxy = AuthenticationChallengeProxy::create(WTFMove(authenticationChallenge), challengeID, makeRef(*m_processPool->networkingProcessConnection()), nullptr);
124
125     m_processPool->downloadClient().didReceiveAuthenticationChallenge(*m_processPool, *this, authenticationChallengeProxy.get());
126 }
127
128 void DownloadProxy::willSendRequest(ResourceRequest&& proposedRequest, const ResourceResponse& redirectResponse)
129 {
130     if (!m_processPool)
131         return;
132
133     m_processPool->downloadClient().willSendRequest(*m_processPool, *this, WTFMove(proposedRequest), redirectResponse, [this, protectedThis = makeRef(*this)](ResourceRequest&& newRequest) {
134         m_redirectChain.append(newRequest.url());
135
136         if (!protectedThis->m_processPool)
137             return;
138
139         auto* networkProcessProxy = protectedThis->m_processPool->networkProcess();
140         if (!networkProcessProxy)
141             return;
142
143         networkProcessProxy->send(Messages::NetworkProcess::ContinueWillSendRequest(protectedThis->m_downloadID, newRequest), 0);
144     });
145 }
146
147 void DownloadProxy::didReceiveResponse(const ResourceResponse& response)
148 {
149     if (!m_processPool)
150         return;
151
152     m_processPool->downloadClient().didReceiveResponse(*m_processPool, *this, response);
153 }
154
155 void DownloadProxy::didReceiveData(uint64_t length)
156 {
157     if (!m_processPool)
158         return;
159
160     m_processPool->downloadClient().didReceiveData(*m_processPool, *this, length);
161 }
162
163 void DownloadProxy::decideDestinationWithSuggestedFilenameAsync(DownloadID downloadID, const String& suggestedFilename)
164 {
165     if (!m_processPool)
166         return;
167     
168     m_processPool->downloadClient().decideDestinationWithSuggestedFilename(*m_processPool, *this, suggestedFilename, [this, protectedThis = makeRef(*this), downloadID = downloadID] (AllowOverwrite allowOverwrite, String destination) {
169         SandboxExtension::Handle sandboxExtensionHandle;
170         if (!destination.isNull())
171             SandboxExtension::createHandle(destination, SandboxExtension::Type::ReadWrite, sandboxExtensionHandle);
172
173         if (auto* networkProcess = m_processPool->networkProcess())
174             networkProcess->send(Messages::NetworkProcess::ContinueDecidePendingDownloadDestination(downloadID, destination, sandboxExtensionHandle, allowOverwrite == AllowOverwrite::Yes), 0);
175     });
176 }
177
178 void DownloadProxy::didCreateDestination(const String& path)
179 {
180     if (!m_processPool)
181         return;
182
183     m_processPool->downloadClient().didCreateDestination(*m_processPool, *this, path);
184 }
185
186 void DownloadProxy::didFinish()
187 {
188     if (!m_processPool)
189         return;
190
191     m_processPool->downloadClient().didFinish(*m_processPool, *this);
192
193     // This can cause the DownloadProxy object to be deleted.
194     m_downloadProxyMap.downloadFinished(this);
195 }
196
197 static RefPtr<API::Data> createData(const IPC::DataReference& data)
198 {
199     if (data.isEmpty())
200         return 0;
201
202     return API::Data::create(data.data(), data.size());
203 }
204
205 void DownloadProxy::didFail(const ResourceError& error, const IPC::DataReference& resumeData)
206 {
207     if (!m_processPool)
208         return;
209
210     m_resumeData = createData(resumeData);
211
212     m_processPool->downloadClient().didFail(*m_processPool, *this, error);
213
214     // This can cause the DownloadProxy object to be deleted.
215     m_downloadProxyMap.downloadFinished(this);
216 }
217
218 void DownloadProxy::didCancel(const IPC::DataReference& resumeData)
219 {
220     m_resumeData = createData(resumeData);
221
222     m_processPool->downloadClient().didCancel(*m_processPool, *this);
223
224     // This can cause the DownloadProxy object to be deleted.
225     m_downloadProxyMap.downloadFinished(this);
226 }
227
228 } // namespace WebKit
229