Skip to content

Commit

Permalink
Create offline_url_utils
Browse files Browse the repository at this point in the history
This utils will handle all the conversions between offline file path
and URLs.

BUG=664124

Review-Url: https://codereview.chromium.org/2506993002
Cr-Commit-Position: refs/heads/master@{#432541}
  • Loading branch information
olivierrobin authored and Commit bot committed Nov 16, 2016
1 parent 97337ee commit 5ab336c
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 64 deletions.
4 changes: 4 additions & 0 deletions ios/chrome/browser/reading_list/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

source_set("reading_list") {
sources = [
"offline_url_utils.cc",
"offline_url_utils.h",
"reading_list_download_service.cc",
"reading_list_download_service.h",
"reading_list_download_service_factory.cc",
Expand Down Expand Up @@ -49,6 +51,7 @@ source_set("reading_list") {
source_set("unit_tests") {
testonly = true
sources = [
"offline_url_utils_unittest.cc",
"reading_list_entry_unittest.cc",
"reading_list_model_storage_unittest.mm",
"reading_list_model_unittest.cc",
Expand All @@ -62,5 +65,6 @@ source_set("unit_tests") {
"//ios/chrome/browser/dom_distiller",
"//ios/web:test_support",
"//testing/gtest",
"//url",
]
}
67 changes: 67 additions & 0 deletions ios/chrome/browser/reading_list/offline_url_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ios/chrome/browser/reading_list/offline_url_utils.h"

#include "base/md5.h"
#include "base/strings/stringprintf.h"
#include "ios/chrome/browser/chrome_url_constants.h"

namespace {
const char kOfflineDirectory[] = "Offline";
const char kMainPageFileName[] = "page.html";
} // namespace

namespace reading_list {

base::FilePath OfflineRootDirectoryPath(const base::FilePath& profile_path) {
return profile_path.Append(FILE_PATH_LITERAL(kOfflineDirectory));
}

std::string OfflineURLDirectoryID(const GURL& url) {
return base::MD5String(url.spec());
}

base::FilePath OfflinePagePath(const GURL& url) {
base::FilePath directory(OfflineURLDirectoryID(url));
return directory.Append(FILE_PATH_LITERAL(kMainPageFileName));
}

base::FilePath OfflineURLDirectoryAbsolutePath(
const base::FilePath& profile_path,
const GURL& url) {
return OfflineRootDirectoryPath(profile_path)
.Append(OfflineURLDirectoryID(url));
}

base::FilePath OfflinePageAbsolutePath(const base::FilePath& profile_path,
const GURL& url) {
return OfflineRootDirectoryPath(profile_path).Append(OfflinePagePath(url));
}

GURL DistilledURLForPath(const base::FilePath& distilled_path) {
if (distilled_path.empty()) {
return GURL();
}
return GURL(kChromeUIOfflineURL + distilled_path.value());
}

GURL FileURLForDistilledURL(const GURL& distilled_url,
const base::FilePath& profile_path,
GURL* resources_root_url) {
if (!distilled_url.is_valid()) {
return GURL();
}
DCHECK(distilled_url.SchemeIs(kChromeUIScheme));
base::FilePath offline_path = profile_path.AppendASCII(kOfflineDirectory);

GURL file_url(base::StringPrintf("%s%s", url::kFileScheme,
url::kStandardSchemeSeparator) +
offline_path.value() + distilled_url.path());
if (resources_root_url) {
*resources_root_url = file_url.Resolve(".");
}
return file_url;
}
}
57 changes: 57 additions & 0 deletions ios/chrome/browser/reading_list/offline_url_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IOS_CHROME_BROWSER_READING_LIST_OFFLINE_URL_UTILS_H_
#define IOS_CHROME_BROWSER_READING_LIST_OFFLINE_URL_UTILS_H_

#include <string>

#include "base/files/file_path.h"
#include "url/gurl.h"

namespace reading_list {

// The absolute path of the directory where offline URLs are saved.
// |profile_path| is the path to the profile directory that contain the offline
// directory.
base::FilePath OfflineRootDirectoryPath(const base::FilePath& profile_path);

// The absolute path of the directory where a |url| is saved offline.
// Contains the page and supporting files (images).
// |profile_path| is the path to the profile directory that contain the offline
// directory.
// The directory may not exist.
base::FilePath OfflineURLDirectoryAbsolutePath(
const base::FilePath& profile_path,
const GURL& url);

// The absolute path of the offline webpage for the |url|. The file may not
// exist.
// |profile_path| is the path to the profile directory that contain the offline
// directory.
base::FilePath OfflinePageAbsolutePath(const base::FilePath& profile_path,
const GURL& url);

// The relative path to the offline webpage for the |url|. The result is
// relative to |OfflineRootDirectoryPath()|.
// The file may not exist.
base::FilePath OfflinePagePath(const GURL& url);

// The name of the directory containing offline data for |url|.
std::string OfflineURLDirectoryID(const GURL& url);

// The distilled URL chrome://offline/... that will load the file at |path|.
GURL DistilledURLForPath(const base::FilePath& path);

// The file URL pointing to the local file to load to display |distilled_url|.
// If |resources_root_url| is not nullptr, it is set to a file URL to the
// directory conatining all the resources needed by |distilled_url|.
// |profile_path| is the path to the profile directory.
GURL FileURLForDistilledURL(const GURL& distilled_url,
const base::FilePath& profile_path,
GURL* resources_root_url);

} // namespace reading_list

#endif // IOS_CHROME_BROWSER_READING_LIST_OFFLINE_URL_UTILS_H_
89 changes: 89 additions & 0 deletions ios/chrome/browser/reading_list/offline_url_utils_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ios/chrome/browser/reading_list/offline_url_utils.h"

#include <string>

#include "base/files/file_path.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

// Checks the root directory of offline pages.
TEST(OfflineURLUtilsTest, OfflineRootDirectoryPathTest) {
base::FilePath profile_path("/profile_path");
base::FilePath offline_directory =
reading_list::OfflineRootDirectoryPath(profile_path);
EXPECT_EQ("/profile_path/Offline", offline_directory.value());
}

// Checks the offline page directory is the MD5 of the URL
TEST(OfflineURLUtilsTest, OfflineURLDirectoryIDTest) {
GURL url("http://www.google.com/test");
// MD5 of "http://www.google.com/test"
std::string md5 = "0090071ef710946a1263c276284bb3b8";
std::string directory_id = reading_list::OfflineURLDirectoryID(url);
EXPECT_EQ(md5, directory_id);
}

// Checks the offline page directory is
// |profile_path|/Offline/OfflineURLDirectoryID;
TEST(OfflineURLUtilsTest, OfflineURLDirectoryAbsolutePathTest) {
base::FilePath profile_path("/profile_path");
GURL url("http://www.google.com/test");
base::FilePath offline_directory =
reading_list::OfflineURLDirectoryAbsolutePath(profile_path, url);
EXPECT_EQ("/profile_path/Offline/0090071ef710946a1263c276284bb3b8",
offline_directory.value());
}

// Checks the offline page absolute path is
// |profile_path|/Offline/OfflineURLDirectoryID/page.html;
TEST(OfflineURLUtilsTest, OfflinePageAbsolutePathTest) {
base::FilePath profile_path("/profile_path");
GURL url("http://www.google.com/test");
base::FilePath offline_page =
reading_list::OfflinePageAbsolutePath(profile_path, url);
EXPECT_EQ("/profile_path/Offline/0090071ef710946a1263c276284bb3b8/page.html",
offline_page.value());
}

// Checks the offline page path is OfflineURLDirectoryID/page.html;
TEST(OfflineURLUtilsTest, OfflinePagePathTest) {
GURL url("http://www.google.com/test");
base::FilePath offline_page = reading_list::OfflinePagePath(url);
EXPECT_EQ("0090071ef710946a1263c276284bb3b8/page.html", offline_page.value());
}

// Checks the distilled URL for the page is chrome://offline/MD5/page.html;
TEST(OfflineURLUtilsTest, DistilledURLForPathTest) {
base::FilePath page_path("MD5/page.html");
GURL distilled_url = reading_list::DistilledURLForPath(page_path);
EXPECT_EQ("chrome://offline/MD5/page.html", distilled_url.spec());
}

// Checks the file path for chrome://offline/MD5/page.html is
// file://profile_path/Offline/MD5/page.html.
// Checks the resource root for chrome://offline/MD5/page.html is
// file://profile_path/Offline/MD5
TEST(OfflineURLUtilsTest, FileURLForDistilledURLTest) {
base::FilePath profile_path("/profile_path");
GURL file_url =
reading_list::FileURLForDistilledURL(GURL(), profile_path, nullptr);
EXPECT_FALSE(file_url.is_valid());

GURL distilled_url("chrome://offline/MD5/page.html");
file_url = reading_list::FileURLForDistilledURL(distilled_url, profile_path,
nullptr);
EXPECT_TRUE(file_url.is_valid());
EXPECT_TRUE(file_url.SchemeIsFile());
EXPECT_EQ("/profile_path/Offline/MD5/page.html", file_url.path());

GURL resource_url;
file_url = reading_list::FileURLForDistilledURL(distilled_url, profile_path,
&resource_url);
EXPECT_TRUE(resource_url.is_valid());
EXPECT_TRUE(resource_url.SchemeIsFile());
EXPECT_EQ("/profile_path/Offline/MD5/", resource_url.path());
}
12 changes: 2 additions & 10 deletions ios/chrome/browser/reading_list/reading_list_entry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,7 @@
#include "ios/chrome/browser/reading_list/reading_list_entry.h"

#include "base/memory/ptr_util.h"

namespace {
// URL used to open offline pages.
// This variable will be moved to chrome_url_constants.
const char kChromeUIOfflineURL[] = "chrome://offline/";
}
#include "ios/chrome/browser/reading_list/offline_url_utils.h"

// The backoff time is the following: 10min, 10min, 1h, 2h, 2h..., starting
// after the first failure.
Expand Down Expand Up @@ -85,10 +80,7 @@ const base::FilePath& ReadingListEntry::DistilledPath() const {
}

const GURL ReadingListEntry::DistilledURL() const {
if (distilled_path_.empty()) {
return GURL();
}
return GURL(kChromeUIOfflineURL + distilled_path_.value());
return reading_list::DistilledURLForPath(distilled_path_);
}

base::TimeDelta ReadingListEntry::TimeUntilNextTry() const {
Expand Down
51 changes: 18 additions & 33 deletions ios/chrome/browser/reading_list/url_downloader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/md5.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#include "ios/chrome/browser/chrome_paths.h"
#include "ios/chrome/browser/dom_distiller/distiller_viewer.h"
#include "ios/chrome/browser/reading_list/offline_url_utils.h"
#include "ios/web/public/web_thread.h"
#include "net/base/escape.h"
#include "url/gurl.h"

const char kReadingListOfflineDirectory[] = "Offline";

// URLDownloader

URLDownloader::URLDownloader(
Expand All @@ -44,7 +42,9 @@ void URLDownloader::OfflineURLExists(const GURL& url,
base::Callback<void(bool)> callback) {
task_tracker_.PostTaskAndReplyWithResult(
web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(),
FROM_HERE, base::Bind(&base::PathExists, OfflinePageAbsolutePath(url)),
FROM_HERE,
base::Bind(&base::PathExists,
reading_list::OfflinePageAbsolutePath(base_directory_, url)),
callback);
}

Expand Down Expand Up @@ -73,8 +73,8 @@ void URLDownloader::DownloadCompletionHandler(const GURL& url,
auto post_delete = base::Bind(
[](URLDownloader* _this, const GURL& url, const std::string& title,
SuccessState success) {
_this->download_completion_.Run(url, success,
_this->OfflinePagePath(url), title);
_this->download_completion_.Run(
url, success, reading_list::OfflinePagePath(url), title);
_this->distiller_.reset();
_this->working_ = false;
_this->HandleNextTask();
Expand All @@ -89,7 +89,8 @@ void URLDownloader::DownloadCompletionHandler(const GURL& url,
[](const base::FilePath& offline_directory_path) {
base::DeleteFile(offline_directory_path, true);
},
OfflineURLDirectoryAbsolutePath(url)),
reading_list::OfflineURLDirectoryAbsolutePath(
base_directory_, url)),
post_delete);
} else {
post_delete.Run();
Expand Down Expand Up @@ -117,7 +118,9 @@ void URLDownloader::HandleNextTask() {
task_tracker_.PostTaskAndReplyWithResult(
web::WebThread::GetTaskRunnerForThread(web::WebThread::FILE).get(),
FROM_HERE, base::Bind(&base::DeleteFile,
OfflineURLDirectoryAbsolutePath(url), true),
reading_list::OfflineURLDirectoryAbsolutePath(
base_directory_, url),
true),
base::Bind(&URLDownloader::DeleteCompletionHandler,
base::Unretained(this), url));
} else if (task.first == DOWNLOAD) {
Expand Down Expand Up @@ -173,30 +176,9 @@ URLDownloader::SuccessState URLDownloader::SaveDistilledHTML(
return ERROR_PERMANENT;
}

base::FilePath URLDownloader::OfflineRootDirectoryPath() {
return base_directory_.Append(
FILE_PATH_LITERAL(kReadingListOfflineDirectory));
}

std::string URLDownloader::OfflineURLDirectoryID(const GURL& url) {
return base::MD5String(url.spec());
}

base::FilePath URLDownloader::OfflinePagePath(const GURL& url) {
base::FilePath directory(OfflineURLDirectoryID(url));
return directory.Append(FILE_PATH_LITERAL("page.html"));
}

base::FilePath URLDownloader::OfflineURLDirectoryAbsolutePath(const GURL& url) {
return OfflineRootDirectoryPath().Append(OfflineURLDirectoryID(url));
}

base::FilePath URLDownloader::OfflinePageAbsolutePath(const GURL& url) {
return OfflineRootDirectoryPath().Append(OfflinePagePath(url));
}

bool URLDownloader::CreateOfflineURLDirectory(const GURL& url) {
base::FilePath path = OfflineURLDirectoryAbsolutePath(url);
base::FilePath path =
reading_list::OfflineURLDirectoryAbsolutePath(base_directory_, url);
if (!DirectoryExists(path)) {
return CreateDirectoryAndGetError(path, nil);
}
Expand All @@ -209,7 +191,9 @@ bool URLDownloader::SaveImage(const GURL& url,
std::string* image_name) {
std::string image_hash = base::MD5String(image_url.spec());
*image_name = image_hash;
base::FilePath path = OfflineURLDirectoryAbsolutePath(url).Append(image_hash);
base::FilePath path =
reading_list::OfflineURLDirectoryAbsolutePath(base_directory_, url)
.Append(image_hash);
if (!base::PathExists(path)) {
return base::WriteFile(path, data.c_str(), data.length()) > 0;
}
Expand Down Expand Up @@ -243,6 +227,7 @@ bool URLDownloader::SaveHTMLForURL(std::string html, const GURL& url) {
if (html.empty()) {
return false;
}
base::FilePath path = OfflinePageAbsolutePath(url);
base::FilePath path =
reading_list::OfflinePageAbsolutePath(base_directory_, url);
return base::WriteFile(path, html.c_str(), html.length()) > 0;
}
Loading

0 comments on commit 5ab336c

Please sign in to comment.