| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ios/chrome/browser/reading_list/url_downloader.h" | 5 #include "ios/chrome/browser/reading_list/url_downloader.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 task_tracker_() {} | 39 task_tracker_() {} |
| 40 | 40 |
| 41 URLDownloader::~URLDownloader() { | 41 URLDownloader::~URLDownloader() { |
| 42 task_tracker_.TryCancelAll(); | 42 task_tracker_.TryCancelAll(); |
| 43 } | 43 } |
| 44 | 44 |
| 45 void URLDownloader::OfflineURLExists(const GURL& url, | 45 void URLDownloader::OfflineURLExists(const GURL& url, |
| 46 base::Callback<void(bool)> callback) { | 46 base::Callback<void(bool)> callback) { |
| 47 task_tracker_.PostTaskAndReplyWithResult( | 47 task_tracker_.PostTaskAndReplyWithResult( |
| 48 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), | 48 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), |
| 49 FROM_HERE, base::Bind(&base::PathExists, OfflineURLPagePath(url)), | 49 FROM_HERE, base::Bind(&base::PathExists, OfflinePageAbsolutePath(url)), |
| 50 callback); | 50 callback); |
| 51 } | 51 } |
| 52 | 52 |
| 53 void URLDownloader::RemoveOfflineURL(const GURL& url) { | 53 void URLDownloader::RemoveOfflineURL(const GURL& url) { |
| 54 // Remove all download tasks for this url as it would be pointless work. | 54 // Remove all download tasks for this url as it would be pointless work. |
| 55 tasks_.erase( | 55 tasks_.erase( |
| 56 std::remove(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)), | 56 std::remove(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)), |
| 57 tasks_.end()); | 57 tasks_.end()); |
| 58 tasks_.push_back(std::make_pair(DELETE, url)); | 58 tasks_.push_back(std::make_pair(DELETE, url)); |
| 59 HandleNextTask(); | 59 HandleNextTask(); |
| 60 } | 60 } |
| 61 | 61 |
| 62 void URLDownloader::DownloadOfflineURL(const GURL& url) { | 62 void URLDownloader::DownloadOfflineURL(const GURL& url) { |
| 63 if (std::find(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)) == | 63 if (std::find(tasks_.begin(), tasks_.end(), std::make_pair(DOWNLOAD, url)) == |
| 64 tasks_.end()) { | 64 tasks_.end()) { |
| 65 tasks_.push_back(std::make_pair(DOWNLOAD, url)); | 65 tasks_.push_back(std::make_pair(DOWNLOAD, url)); |
| 66 HandleNextTask(); | 66 HandleNextTask(); |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 void URLDownloader::DownloadCompletionHandler(const GURL& url, | 70 void URLDownloader::DownloadCompletionHandler(const GURL& url, |
| 71 const std::string& title, | 71 const std::string& title, |
| 72 SuccessState success) { | 72 SuccessState success) { |
| 73 DCHECK(working_); | 73 DCHECK(working_); |
| 74 | 74 |
| 75 auto post_delete = base::Bind( | 75 auto post_delete = base::Bind( |
| 76 [](URLDownloader* _this, const GURL& url, const std::string& title, | 76 [](URLDownloader* _this, const GURL& url, const std::string& title, |
| 77 SuccessState success) { | 77 SuccessState success) { |
| 78 _this->download_completion_.Run( | 78 _this->download_completion_.Run(url, success, |
| 79 url, success, | 79 _this->OfflinePagePath(url), title); |
| 80 GURL(std::string(url::kFileScheme) + url::kStandardSchemeSeparator + | |
| 81 _this->OfflineURLPagePath(url).value()), | |
| 82 title); | |
| 83 _this->distiller_.reset(); | 80 _this->distiller_.reset(); |
| 84 _this->working_ = false; | 81 _this->working_ = false; |
| 85 _this->HandleNextTask(); | 82 _this->HandleNextTask(); |
| 86 }, | 83 }, |
| 87 base::Unretained(this), url, title, success); | 84 base::Unretained(this), url, title, success); |
| 88 | 85 |
| 89 // If downloading failed, clean up any partial download. | 86 // If downloading failed, clean up any partial download. |
| 90 if (success == ERROR_RETRY || success == ERROR_PERMANENT) { | 87 if (success == ERROR_RETRY || success == ERROR_PERMANENT) { |
| 91 task_tracker_.PostTaskAndReply( | 88 task_tracker_.PostTaskAndReply( |
| 92 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), | 89 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), |
| 93 FROM_HERE, base::Bind( | 90 FROM_HERE, base::Bind( |
| 94 [](const base::FilePath& offline_directory_path) { | 91 [](const base::FilePath& offline_directory_path) { |
| 95 base::DeleteFile(offline_directory_path, true); | 92 base::DeleteFile(offline_directory_path, true); |
| 96 }, | 93 }, |
| 97 OfflineURLDirectoryPath(url)), | 94 OfflineURLDirectoryAbsolutePath(url)), |
| 98 post_delete); | 95 post_delete); |
| 99 } else { | 96 } else { |
| 100 post_delete.Run(); | 97 post_delete.Run(); |
| 101 } | 98 } |
| 102 } | 99 } |
| 103 | 100 |
| 104 void URLDownloader::DeleteCompletionHandler(const GURL& url, bool success) { | 101 void URLDownloader::DeleteCompletionHandler(const GURL& url, bool success) { |
| 105 DCHECK(working_); | 102 DCHECK(working_); |
| 106 delete_completion_.Run(url, success); | 103 delete_completion_.Run(url, success); |
| 107 working_ = false; | 104 working_ = false; |
| 108 HandleNextTask(); | 105 HandleNextTask(); |
| 109 } | 106 } |
| 110 | 107 |
| 111 void URLDownloader::HandleNextTask() { | 108 void URLDownloader::HandleNextTask() { |
| 112 if (working_ || tasks_.empty()) { | 109 if (working_ || tasks_.empty()) { |
| 113 return; | 110 return; |
| 114 } | 111 } |
| 115 working_ = true; | 112 working_ = true; |
| 116 | 113 |
| 117 Task task = tasks_.front(); | 114 Task task = tasks_.front(); |
| 118 tasks_.pop_front(); | 115 tasks_.pop_front(); |
| 119 GURL url = task.second; | 116 GURL url = task.second; |
| 120 | 117 |
| 121 if (task.first == DELETE) { | 118 if (task.first == DELETE) { |
| 122 task_tracker_.PostTaskAndReplyWithResult( | 119 task_tracker_.PostTaskAndReplyWithResult( |
| 123 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), | 120 web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(), |
| 124 FROM_HERE, | 121 FROM_HERE, base::Bind(&base::DeleteFile, |
| 125 base::Bind(&base::DeleteFile, OfflineURLDirectoryPath(url), true), | 122 OfflineURLDirectoryAbsolutePath(url), true), |
| 126 base::Bind(&URLDownloader::DeleteCompletionHandler, | 123 base::Bind(&URLDownloader::DeleteCompletionHandler, |
| 127 base::Unretained(this), url)); | 124 base::Unretained(this), url)); |
| 128 } else if (task.first == DOWNLOAD) { | 125 } else if (task.first == DOWNLOAD) { |
| 129 DCHECK(!distiller_); | 126 DCHECK(!distiller_); |
| 130 OfflineURLExists(url, base::Bind(&URLDownloader::DownloadURL, | 127 OfflineURLExists(url, base::Bind(&URLDownloader::DownloadURL, |
| 131 base::Unretained(this), url)); | 128 base::Unretained(this), url)); |
| 132 } | 129 } |
| 133 } | 130 } |
| 134 | 131 |
| 135 void URLDownloader::DownloadURL(GURL url, bool offline_url_exists) { | 132 void URLDownloader::DownloadURL(GURL url, bool offline_url_exists) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 images, | 168 images, |
| 172 const std::string& html) { | 169 const std::string& html) { |
| 173 if (CreateOfflineURLDirectory(url)) { | 170 if (CreateOfflineURLDirectory(url)) { |
| 174 return SaveHTMLForURL(SaveAndReplaceImagesInHTML(url, html, images), url) | 171 return SaveHTMLForURL(SaveAndReplaceImagesInHTML(url, html, images), url) |
| 175 ? DOWNLOAD_SUCCESS | 172 ? DOWNLOAD_SUCCESS |
| 176 : ERROR_PERMANENT; | 173 : ERROR_PERMANENT; |
| 177 } | 174 } |
| 178 return ERROR_PERMANENT; | 175 return ERROR_PERMANENT; |
| 179 } | 176 } |
| 180 | 177 |
| 181 base::FilePath URLDownloader::OfflineDirectoryPath() { | 178 base::FilePath URLDownloader::OfflineRootDirectoryPath() { |
| 182 return base_directory_.Append(FILE_PATH_LITERAL(kOfflineDirectory)); | 179 return base_directory_.Append(FILE_PATH_LITERAL(kOfflineDirectory)); |
| 183 } | 180 } |
| 184 | 181 |
| 185 base::FilePath URLDownloader::OfflineURLDirectoryPath(const GURL& url) { | 182 std::string URLDownloader::OfflineURLDirectoryID(const GURL& url) { |
| 186 std::string hash = base::MD5String(url.spec()); | 183 return base::MD5String(url.spec()); |
| 187 return OfflineDirectoryPath().AppendASCII(hash); | |
| 188 } | 184 } |
| 189 | 185 |
| 190 base::FilePath URLDownloader::OfflineURLPagePath(const GURL& url) { | 186 base::FilePath URLDownloader::OfflinePagePath(const GURL& url) { |
| 191 return OfflineURLDirectoryPath(url).Append(FILE_PATH_LITERAL("page.html")); | 187 base::FilePath directory(OfflineURLDirectoryID(url)); |
| 188 return directory.Append(FILE_PATH_LITERAL("page.html")); |
| 189 } |
| 190 |
| 191 base::FilePath URLDownloader::OfflineURLDirectoryAbsolutePath(const GURL& url) { |
| 192 return OfflineRootDirectoryPath().Append(OfflineURLDirectoryID(url)); |
| 193 } |
| 194 |
| 195 base::FilePath URLDownloader::OfflinePageAbsolutePath(const GURL& url) { |
| 196 return OfflineRootDirectoryPath().Append(OfflinePagePath(url)); |
| 192 } | 197 } |
| 193 | 198 |
| 194 bool URLDownloader::CreateOfflineURLDirectory(const GURL& url) { | 199 bool URLDownloader::CreateOfflineURLDirectory(const GURL& url) { |
| 195 base::FilePath path = OfflineURLDirectoryPath(url); | 200 base::FilePath path = OfflineURLDirectoryAbsolutePath(url); |
| 196 if (!DirectoryExists(path)) { | 201 if (!DirectoryExists(path)) { |
| 197 return CreateDirectoryAndGetError(path, nil); | 202 return CreateDirectoryAndGetError(path, nil); |
| 198 } | 203 } |
| 199 return true; | 204 return true; |
| 200 } | 205 } |
| 201 | 206 |
| 202 bool URLDownloader::SaveImage(const GURL& url, | 207 bool URLDownloader::SaveImage(const GURL& url, |
| 203 const GURL& image_url, | 208 const GURL& image_url, |
| 204 const std::string& data, | 209 const std::string& data, |
| 205 std::string* image_name) { | 210 std::string* image_name) { |
| 206 std::string image_hash = base::MD5String(image_url.spec()); | 211 std::string image_hash = base::MD5String(image_url.spec()); |
| 207 *image_name = image_hash; | 212 *image_name = image_hash; |
| 208 base::FilePath path = OfflineURLDirectoryPath(url).Append(image_hash); | 213 base::FilePath path = OfflineURLDirectoryAbsolutePath(url).Append(image_hash); |
| 209 if (!base::PathExists(path)) { | 214 if (!base::PathExists(path)) { |
| 210 return base::WriteFile(path, data.c_str(), data.length()) > 0; | 215 return base::WriteFile(path, data.c_str(), data.length()) > 0; |
| 211 } | 216 } |
| 212 return true; | 217 return true; |
| 213 } | 218 } |
| 214 | 219 |
| 215 std::string URLDownloader::SaveAndReplaceImagesInHTML( | 220 std::string URLDownloader::SaveAndReplaceImagesInHTML( |
| 216 const GURL& url, | 221 const GURL& url, |
| 217 const std::string& html, | 222 const std::string& html, |
| 218 const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& | 223 const std::vector<dom_distiller::DistillerViewerInterface::ImageInfo>& |
| (...skipping 13 matching lines...) Expand all Loading... |
| 232 pos = mutable_html.find(image_url, pos + local_image_name.size()); | 237 pos = mutable_html.find(image_url, pos + local_image_name.size()); |
| 233 } | 238 } |
| 234 } | 239 } |
| 235 return mutable_html; | 240 return mutable_html; |
| 236 } | 241 } |
| 237 | 242 |
| 238 bool URLDownloader::SaveHTMLForURL(std::string html, const GURL& url) { | 243 bool URLDownloader::SaveHTMLForURL(std::string html, const GURL& url) { |
| 239 if (html.empty()) { | 244 if (html.empty()) { |
| 240 return false; | 245 return false; |
| 241 } | 246 } |
| 242 base::FilePath path = OfflineURLPagePath(url); | 247 base::FilePath path = OfflinePageAbsolutePath(url); |
| 243 return base::WriteFile(path, html.c_str(), html.length()) > 0; | 248 return base::WriteFile(path, html.c_str(), html.length()) > 0; |
| 244 } | 249 } |
| OLD | NEW |