Source/WebCore/ChangeLog

 12017-07-19 Basuke Suzuki <Basuke.Suzuki@sony.com>
 2
 3 curl: Don't try to close & move the downloaded file twice
 4 https://bugs.webkit.org/show_bug.cgi?id=134393
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * platform/network/curl/CurlDownload.cpp:
 9 (WebCore::CurlDownload::~CurlDownload):
 10 (WebCore::CurlDownload::init):
 11 (WebCore::CurlDownload::start):
 12 (WebCore::CurlDownload::cancel):
 13 (WebCore::CurlDownload::getTempPath):
 14 (WebCore::CurlDownload::getUrl):
 15 (WebCore::CurlDownload::getResponse):
 16 (WebCore::CurlDownload::closeFile):
 17 (WebCore::CurlDownload::moveFileToDestination):
 18 (WebCore::CurlDownload::addHeaders):
 19 (WebCore::CurlDownload::didReceiveHeader):
 20 (WebCore::CurlDownload::didReceiveData):
 21 (WebCore::CurlDownload::success):
 22 (WebCore::CurlDownload::cleanup):
 23 (WebCore::CurlDownload::writeCallback):
 24 (WebCore::CurlDownload::headerCallback):
 25 (WebCore::CurlDownload::didReceiveResponse): Deleted.
 26 (WebCore::CurlDownload::didReceiveDataOfLength): Deleted.
 27 (WebCore::CurlDownload::didFinish): Deleted.
 28 (WebCore::CurlDownload::didFail): Deleted.
 29 (WebCore::CurlDownload::downloadFinishedCallback): Deleted.
 30 (WebCore::CurlDownload::downloadFailedCallback): Deleted.
 31 (WebCore::CurlDownload::receivedDataCallback): Deleted.
 32 (WebCore::CurlDownload::receivedResponseCallback): Deleted.
 33 * platform/network/curl/CurlDownload.h:
 34
1352017-07-19 Matt Lewis <jlewis3@apple.com>
236
337 Unreviewed, rolling out r219646.

Source/WebCore/platform/network/curl/CurlDownload.cpp

@@CurlDownload::CurlDownload() = default;
4949CurlDownload::~CurlDownload()
5050{
5151 closeFile();
52  moveFileToDestination();
5352}
5453
5554void CurlDownload::init(CurlDownloadListener* listener, const URL& url)

@@void CurlDownload::init(CurlDownloadListener* listener, const URL& url)
5756 if (!listener)
5857 return;
5958
60  LockHolder locker(m_mutex);
61 
6259 m_curlHandle.enableShareHandle();
6360
6461 m_curlHandle.setUrl(url);

@@void CurlDownload::init(CurlDownloadListener* listener, ResourceHandle*, const R
8784bool CurlDownload::start()
8885{
8986 m_job = CurlJobManager::singleton().add(m_curlHandle, [this, protectedThis = makeRef(*this)](CurlJobResult result) mutable {
 87 ASSERT(isMainThread());
 88
9089 switch (result) {
9190 case CurlJobResult::Done:
92  didFinish();
 91 success();
 92
 93 if (m_listener)
 94 m_listener->didFinish();
9395 break;
9496
9597 case CurlJobResult::Error:
96  didFail();
 98 cleanup();
 99
 100 if (m_listener)
 101 m_listener->didFail();
97102 break;
98103
99104 case CurlJobResult::Cancelled:
 105 cleanup();
100106 break;
101107 }
102108 });

@@bool CurlDownload::start()
105111
106112bool CurlDownload::cancel()
107113{
 114 m_cancelled = true;
108115 CurlJobManager::singleton().cancel(m_job);
109116 return true;
110117}
111118
112119String CurlDownload::getTempPath() const
113120{
114  LockHolder locker(m_mutex);
115121 return m_tempPath;
116122}
117123
118124String CurlDownload::getUrl() const
119125{
120  LockHolder locker(m_mutex);
121126 return String(m_curlHandle.url());
122127}
123128
124129ResourceResponse CurlDownload::getResponse() const
125130{
126  LockHolder locker(m_mutex);
127131 return m_response;
128132}
129133
130134void CurlDownload::closeFile()
131135{
132  LockHolder locker(m_mutex);
133 
134136 if (m_tempHandle != invalidPlatformFileHandle) {
135137 WebCore::closeFile(m_tempHandle);
136138 m_tempHandle = invalidPlatformFileHandle;

@@void CurlDownload::closeFile()
139141
140142void CurlDownload::moveFileToDestination()
141143{
142  LockHolder locker(m_mutex);
143 
144144 if (m_destination.isEmpty())
145145 return;
146146

@@void CurlDownload::writeDataToFile(const char* data, int size)
158158
159159void CurlDownload::addHeaders(const ResourceRequest& request)
160160{
161  LockHolder locker(m_mutex);
162161 m_curlHandle.appendRequestHeaders(request.httpHeaderFields());
163162}
164163
165164void CurlDownload::didReceiveHeader(const String& header)
166165{
167  LockHolder locker(m_mutex);
168 
169166 if (header == "\r\n" || header == "\n") {
170 
171167 long httpCode = 0;
172168 m_curlHandle.getResponseCode(httpCode);
173169
 170 // @FIXME error handling may be required
174171 if (httpCode >= 200 && httpCode < 300) {
175172 URL url = m_curlHandle.getEffectiveURL();
176  callOnMainThread([this, url = url.isolatedCopy(), protectedThis = makeRef(*this)] {
177  m_response.setURL(url);
178  m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));
179  m_response.setTextEncodingName(extractCharsetFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));
 173 m_response.setURL(url);
 174 m_response.setMimeType(extractMIMETypeFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));
 175 m_response.setTextEncodingName(extractCharsetFromMediaType(m_response.httpHeaderField(HTTPHeaderName::ContentType)));
180176
181  didReceiveResponse();
 177 callOnMainThread([this, protectedThis = makeRef(*this)] {
 178 if (m_listener)
 179 m_listener->didReceiveResponse();
182180 });
183181 }
184182 } else {
185  callOnMainThread([this, header = header.isolatedCopy(), protectedThis = makeRef(*this)] {
186  int splitPos = header.find(":");
187  if (splitPos != -1)
188  m_response.setHTTPHeaderField(header.left(splitPos), header.substring(splitPos + 1).stripWhiteSpace());
189  });
 183 auto position = header.find(":");
 184 if (position != notFound)
 185 m_response.setHTTPHeaderField(header.left(position), header.substring(position + 1).stripWhiteSpace());
190186 }
191187}
192188
193189void CurlDownload::didReceiveData(void* data, int size)
194190{
195  LockHolder locker(m_mutex);
196 
197  callOnMainThread([this, size, protectedThis = makeRef(*this)] {
198  didReceiveDataOfLength(size);
 191 callOnMainThread([this, size, protectedThis = makeRef(*this)]() {
 192 if (m_listener)
 193 m_listener->didReceiveDataOfLength(size);
199194 });
200195
201196 writeDataToFile(static_cast<const char*>(data), size);
202197}
203198
204 void CurlDownload::didReceiveResponse()
205 {
206  if (m_listener)
207  m_listener->didReceiveResponse();
208 }
209 
210 void CurlDownload::didReceiveDataOfLength(int size)
211 {
212  if (m_listener)
213  m_listener->didReceiveDataOfLength(size);
214 }
215 
216 void CurlDownload::didFinish()
 199void CurlDownload::success()
217200{
218201 closeFile();
219202 moveFileToDestination();
220 
221  if (m_listener)
222  m_listener->didFinish();
223203}
224204
225 void CurlDownload::didFail()
 205void CurlDownload::cleanup()
226206{
227207 closeFile();
228  {
229  LockHolder locker(m_mutex);
230 
231  if (m_deletesFileUponFailure)
232  deleteFile(m_tempPath);
233  }
234208
235  if (m_listener)
236  m_listener->didFail();
 209 if (m_deletesFileUponFailure)
 210 deleteFile(m_tempPath);
237211}
238212
239213size_t CurlDownload::writeCallback(char* ptr, size_t size, size_t nmemb, void* data)

@@size_t CurlDownload::writeCallback(char* ptr, size_t size, size_t nmemb, void* d
241215 size_t totalSize = size * nmemb;
242216 CurlDownload* download = reinterpret_cast<CurlDownload*>(data);
243217
244  if (download)
 218 if (download && !download->m_cancelled)
245219 download->didReceiveData(static_cast<void*>(ptr), totalSize);
246220
247221 return totalSize;

@@size_t CurlDownload::headerCallback(char* ptr, size_t size, size_t nmemb, void*
252226 size_t totalSize = size * nmemb;
253227 CurlDownload* download = reinterpret_cast<CurlDownload*>(data);
254228
255  String header(static_cast<const char*>(ptr), totalSize);
 229 if (download && !download->m_cancelled) {
 230 String header(static_cast<const char*>(ptr), totalSize);
256231
257  if (download)
258232 download->didReceiveHeader(header);
 233 }
259234
260235 return totalSize;
261236}
262237
263 void CurlDownload::downloadFinishedCallback(CurlDownload* download)
264 {
265  if (download)
266  download->didFinish();
267 }
268 
269 void CurlDownload::downloadFailedCallback(CurlDownload* download)
270 {
271  if (download)
272  download->didFail();
273 }
274 
275 void CurlDownload::receivedDataCallback(CurlDownload* download, int size)
276 {
277  if (download)
278  download->didReceiveDataOfLength(size);
279 }
280 
281 void CurlDownload::receivedResponseCallback(CurlDownload* download)
282 {
283  if (download)
284  download->didReceiveResponse();
285 }
286 
287238}
288239
289240#endif

Source/WebCore/platform/network/curl/CurlDownload.h

@@public:
6565
6666 String getTempPath() const;
6767 String getUrl() const;
68  WebCore::ResourceResponse getResponse() const;
 68 ResourceResponse getResponse() const;
6969
7070 bool deletesFileUponFailure() const { return m_deletesFileUponFailure; }
7171 void setDeletesFileUponFailure(bool deletesFileUponFailure) { m_deletesFileUponFailure = deletesFileUponFailure; }

@@private:
8484 void didReceiveData(void* data, int size);
8585
8686 // Called on main thread.
87  void didReceiveResponse();
88  void didReceiveDataOfLength(int size);
89  void didFinish();
90  void didFail();
 87 void success();
 88 void cleanup();
9189
9290 static size_t writeCallback(char* ptr, size_t, size_t nmemb, void* data);
9391 static size_t headerCallback(char* ptr, size_t, size_t nmemb, void* data);
9492
95  static void downloadFinishedCallback(CurlDownload*);
96  static void downloadFailedCallback(CurlDownload*);
97  static void receivedDataCallback(CurlDownload*, int size);
98  static void receivedResponseCallback(CurlDownload*);
99 
10093 CurlHandle m_curlHandle;
10194 CurlJobTicket m_job;
 95 bool m_cancelled;
10296 String m_tempPath;
10397 String m_destination;
104  WebCore::PlatformFileHandle m_tempHandle { invalidPlatformFileHandle };
105  WebCore::ResourceResponse m_response;
 98 PlatformFileHandle m_tempHandle { invalidPlatformFileHandle };
 99 ResourceResponse m_response;
106100 bool m_deletesFileUponFailure { false };
107  mutable Lock m_mutex;
108101 CurlDownloadListener* m_listener { nullptr };
109102};
110103