chromeos: Replace resource ID in drive URL with path

BUG=175948
TEST=Open a .txt file in Google Drive directory from both Files.app and Ctrl-O


Review URL: https://chromiumcodereview.appspot.com/13401003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192541 0039d316-1c4b-4281-b951-d872f2087c98
parent 89c0e15a
...@@ -115,18 +115,16 @@ void OpenEditURLUIThread(Profile* profile, const GURL& edit_url) { ...@@ -115,18 +115,16 @@ void OpenEditURLUIThread(Profile* profile, const GURL& edit_url) {
void OnGetEntryInfoByResourceId(Profile* profile, void OnGetEntryInfoByResourceId(Profile* profile,
const std::string& resource_id, const std::string& resource_id,
DriveFileError error, DriveFileError error,
const base::FilePath& /* drive_file_path */, const base::FilePath& drive_file_path,
scoped_ptr<DriveEntryProto> entry_proto) { scoped_ptr<DriveEntryProto> entry_proto) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (error != DRIVE_FILE_OK) if (error != DRIVE_FILE_OK)
return; return;
DCHECK(entry_proto.get()); const GURL edit_url = FilePathToDriveURL(drive_file_path);
const std::string& base_name = entry_proto->base_name();
const GURL edit_url = GetFileResourceUrl(resource_id, base_name);
OpenEditURLUIThread(profile, edit_url); OpenEditURLUIThread(profile, edit_url);
DVLOG(1) << "OnFindEntryByResourceId " << edit_url; DVLOG(1) << "OnGetEntryInfoByResourceId " << edit_url;
} }
} // namespace } // namespace
...@@ -179,15 +177,21 @@ const base::FilePath& GetDriveMyDriveMountPointPath() { ...@@ -179,15 +177,21 @@ const base::FilePath& GetDriveMyDriveMountPointPath() {
return drive_mydrive_mount_path; return drive_mydrive_mount_path;
} }
GURL GetFileResourceUrl(const std::string& resource_id, GURL FilePathToDriveURL(const base::FilePath& path) {
const std::string& file_name) { std::string url(base::StringPrintf("%s:%s",
std::string url(base::StringPrintf(
"%s:%s",
chrome::kDriveScheme, chrome::kDriveScheme,
net::EscapePath(resource_id).c_str())); path.AsUTF8Unsafe().c_str()));
return GURL(url); return GURL(url);
} }
base::FilePath DriveURLToFilePath(const GURL& url) {
if (!url.is_valid() || url.scheme() != chrome::kDriveScheme)
return base::FilePath();
std::string path_string = net::UnescapeURLComponent(
url.path(), net::UnescapeRule::NORMAL);
return base::FilePath::FromUTF8Unsafe(path_string);
}
void ModifyDriveFileResourceUrl(Profile* profile, void ModifyDriveFileResourceUrl(Profile* profile,
const base::FilePath& drive_cache_path, const base::FilePath& drive_cache_path,
GURL* url) { GURL* url) {
......
...@@ -89,10 +89,11 @@ const std::string& GetDriveMountPointPathAsString(); ...@@ -89,10 +89,11 @@ const std::string& GetDriveMountPointPathAsString();
// Returns the 'local' root of remote file system as "/special". // Returns the 'local' root of remote file system as "/special".
const base::FilePath& GetSpecialRemoteRootPath(); const base::FilePath& GetSpecialRemoteRootPath();
// Returns the gdata file resource url formatted as // Returns the gdata file resource url formatted as "drive:<path>"
// chrome://drive/<resource_id>/<file_name>. GURL FilePathToDriveURL(const base::FilePath& path);
GURL GetFileResourceUrl(const std::string& resource_id,
const std::string& file_name); // Converts a drive: URL back to a path that can be passed to DriveFileSystem.
base::FilePath DriveURLToFilePath(const GURL& url);
// Given a profile and a drive_cache_path, return the file resource url. // Given a profile and a drive_cache_path, return the file resource url.
void ModifyDriveFileResourceUrl(Profile* profile, void ModifyDriveFileResourceUrl(Profile* profile,
......
...@@ -5,11 +5,37 @@ ...@@ -5,11 +5,37 @@
#include "chrome/browser/chromeos/drive/drive_file_system_util.h" #include "chrome/browser/chromeos/drive/drive_file_system_util.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace drive { namespace drive {
namespace util { namespace util {
TEST(DriveFileSystemUtilTest, FilePathToDriveURL) {
base::FilePath path;
// Path with alphabets and numbers.
path = GetDriveMyDriveRootPath().AppendASCII("foo/bar012.txt");
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
// Path with symbols.
path = GetDriveMyDriveRootPath().AppendASCII(
" !\"#$%&'()*+,-.:;<=>?@[\\]^_`{|}~");
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
// Path with '%'.
path = GetDriveMyDriveRootPath().AppendASCII("%19%20%21.txt");
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
// Path with multi byte characters.
string16 utf16_string;
utf16_string.push_back(0x307b); // HIRAGANA_LETTER_HO
utf16_string.push_back(0x3052); // HIRAGANA_LETTER_GE
path = GetDriveMyDriveRootPath().Append(
base::FilePath::FromUTF8Unsafe(UTF16ToUTF8(utf16_string) + ".txt"));
EXPECT_EQ(path, DriveURLToFilePath(FilePathToDriveURL(path)));
}
TEST(DriveFileSystemUtilTest, IsUnderDriveMountPoint) { TEST(DriveFileSystemUtilTest, IsUnderDriveMountPoint) {
EXPECT_FALSE(IsUnderDriveMountPoint( EXPECT_FALSE(IsUnderDriveMountPoint(
base::FilePath::FromUTF8Unsafe("/wherever/foo.txt"))); base::FilePath::FromUTF8Unsafe("/wherever/foo.txt")));
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "chrome/browser/chromeos/drive/drive.pb.h" #include "chrome/browser/chromeos/drive/drive.pb.h"
#include "chrome/browser/chromeos/drive/drive_file_system_interface.h" #include "chrome/browser/chromeos/drive/drive_file_system_interface.h"
#include "chrome/browser/chromeos/drive/drive_file_system_util.h"
#include "chrome/browser/chromeos/drive/drive_system_service.h" #include "chrome/browser/chromeos/drive/drive_system_service.h"
#include "chrome/browser/google_apis/base_operations.h" #include "chrome/browser/google_apis/base_operations.h"
#include "chrome/browser/google_apis/task_util.h" #include "chrome/browser/google_apis/task_util.h"
...@@ -69,20 +70,6 @@ std::string FixupMimeType(const std::string& type) { ...@@ -69,20 +70,6 @@ std::string FixupMimeType(const std::string& type) {
return type; return type;
} }
// Helper function that extracts and unescapes resource_id from drive urls
// (drive:<resource_id>).
bool ParseDriveUrl(const std::string& path, std::string* resource_id) {
const std::string drive_schema(chrome::kDriveScheme + std::string(":"));
if (!StartsWithASCII(path, drive_schema, false) ||
path.size() <= drive_schema.size()) {
return false;
}
std::string id = path.substr(drive_schema.size());
*resource_id = net::UnescapeURLComponent(id, kUrlPathUnescapeMask);
return resource_id->size();
}
// Helper function to cancel Drive download operation on UI thread. // Helper function to cancel Drive download operation on UI thread.
void CancelDriveDownloadOnUIThread( void CancelDriveDownloadOnUIThread(
const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter,
...@@ -109,39 +96,37 @@ void CancelDriveDownload( ...@@ -109,39 +96,37 @@ void CancelDriveDownload(
file_system_getter, drive_file_path)); file_system_getter, drive_file_path));
} }
// Helper function to call DriveFileSystem::GetEntryInfoByResourceId. // Helper function to call DriveFileSystem::GetEntryInfoByPath.
void GetEntryInfoByResourceIdOnUIThread( void GetEntryInfoByPathOnUIThread(
const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter,
const std::string& resource_id, const base::FilePath& path,
const drive::GetEntryInfoWithFilePathCallback& callback) { const drive::GetEntryInfoCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DriveFileSystemInterface* file_system = file_system_getter.Run(); DriveFileSystemInterface* file_system = file_system_getter.Run();
if (!file_system) { if (!file_system) {
callback.Run(DRIVE_FILE_ERROR_FAILED, callback.Run(DRIVE_FILE_ERROR_FAILED, scoped_ptr<DriveEntryProto>());
base::FilePath(),
scoped_ptr<DriveEntryProto>());
return; return;
} }
file_system->GetEntryInfoByResourceId(resource_id, callback); file_system->GetEntryInfoByPath(path, callback);
} }
// Returns the entry info for the |resource_id| on DriveFileSystem returned by // Returns the entry info for the |path| on DriveFileSystem returned by
// |file_system_getter| via |callback|. // |file_system_getter| via |callback|.
// The main task will be done on UI thread, but this method itself is designed // The main task will be done on UI thread, but this method itself is designed
// to be run on IO thread. Also the |callback| will be run on IO thread, too. // to be run on IO thread. Also the |callback| will be run on IO thread, too.
void GetEntryInfoByResourceId( void GetEntryInfoByPath(
const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter, const DriveURLRequestJob::DriveFileSystemGetter& file_system_getter,
const std::string& resource_id, const base::FilePath& path,
const drive::GetEntryInfoWithFilePathCallback& callback) { const drive::GetEntryInfoCallback& callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
BrowserThread::PostTask( BrowserThread::PostTask(
BrowserThread::UI, BrowserThread::UI,
FROM_HERE, FROM_HERE,
base::Bind(&GetEntryInfoByResourceIdOnUIThread, base::Bind(&GetEntryInfoByPathOnUIThread,
file_system_getter, file_system_getter,
resource_id, path,
google_apis::CreateRelayCallback(callback))); google_apis::CreateRelayCallback(callback)));
} }
...@@ -262,19 +247,10 @@ void DriveURLRequestJob::Start() { ...@@ -262,19 +247,10 @@ void DriveURLRequestJob::Start() {
net::ERR_METHOD_NOT_SUPPORTED)); net::ERR_METHOD_NOT_SUPPORTED));
return; return;
} }
GetEntryInfoByPath(file_system_getter_,
std::string resource_id; util::DriveURLToFilePath(request_->url()),
if (!ParseDriveUrl(request_->url().spec(), &resource_id)) { base::Bind(&DriveURLRequestJob::OnGetEntryInfoByPath,
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED, weak_ptr_factory_.GetWeakPtr()));
net::ERR_INVALID_URL));
return;
}
GetEntryInfoByResourceId(
file_system_getter_,
resource_id,
base::Bind(&DriveURLRequestJob::OnGetEntryInfoByResourceId,
weak_ptr_factory_.GetWeakPtr(), resource_id));
} }
void DriveURLRequestJob::Kill() { void DriveURLRequestJob::Kill() {
...@@ -435,32 +411,32 @@ DriveURLRequestJob::~DriveURLRequestJob() { ...@@ -435,32 +411,32 @@ DriveURLRequestJob::~DriveURLRequestJob() {
//======================= DriveURLRequestJob private methods =================== //======================= DriveURLRequestJob private methods ===================
void DriveURLRequestJob::OnGetEntryInfoByResourceId( void DriveURLRequestJob::OnGetEntryInfoByPath(
const std::string& resource_id,
DriveFileError error, DriveFileError error,
const base::FilePath& drive_file_path,
scoped_ptr<DriveEntryProto> entry_proto) { scoped_ptr<DriveEntryProto> entry_proto) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
if (entry_proto.get() && !entry_proto->has_file_specific_info()) if (entry_proto.get() && !entry_proto->has_file_specific_info())
error = DRIVE_FILE_ERROR_NOT_FOUND; error = DRIVE_FILE_ERROR_NOT_FOUND;
if (error == DRIVE_FILE_OK) { if (error != DRIVE_FILE_OK) {
DCHECK(entry_proto.get());
mime_type_ = entry_proto->file_specific_info().content_mime_type();
drive_file_path_ = drive_file_path;
initial_file_size_ = entry_proto->file_info().size();
} else {
mime_type_.clear(); mime_type_.clear();
drive_file_path_.clear(); drive_file_path_.clear();
initial_file_size_ = 0; initial_file_size_ = 0;
NotifyStartError(net::URLRequestStatus(net::URLRequestStatus::FAILED,
net::ERR_FILE_NOT_FOUND));
return;
} }
DCHECK(entry_proto.get());
mime_type_ = entry_proto->file_specific_info().content_mime_type();
drive_file_path_ = util::DriveURLToFilePath(request_->url());
initial_file_size_ = entry_proto->file_info().size();
remaining_bytes_ = initial_file_size_; remaining_bytes_ = initial_file_size_;
DVLOG(1) << "Getting file for resource id"; DVLOG(1) << "Getting file for resource id";
GetFileByResourceId( GetFileByResourceId(
file_system_getter_, file_system_getter_,
resource_id, entry_proto->resource_id(),
base::Bind(&DriveURLRequestJob::OnGetFileByResourceId, base::Bind(&DriveURLRequestJob::OnGetFileByResourceId,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
base::Bind(&DriveURLRequestJob::OnUrlFetchDownloadData, base::Bind(&DriveURLRequestJob::OnUrlFetchDownloadData,
......
...@@ -90,10 +90,8 @@ class DriveURLRequestJob : public net::URLRequestJob { ...@@ -90,10 +90,8 @@ class DriveURLRequestJob : public net::URLRequestJob {
// Helper callback for handling result of file_util::GetFileSize(). // Helper callback for handling result of file_util::GetFileSize().
void OnGetFileSize(int64 *file_size, bool success); void OnGetFileSize(int64 *file_size, bool success);
// Helper callback for GetEntryInfoByResourceId invoked by Start(). // Helper callback for GetEntryInfoByPath invoked by Start().
void OnGetEntryInfoByResourceId(const std::string& resource_id, void OnGetEntryInfoByPath(DriveFileError error,
DriveFileError error,
const base::FilePath& drive_file_path,
scoped_ptr<DriveEntryProto> entry_proto); scoped_ptr<DriveEntryProto> entry_proto);
// Helper methods for ReadRawData to open file and read from its corresponding // Helper methods for ReadRawData to open file and read from its corresponding
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/drive/drive_file_system_util.h"
#include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread.h"
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_test_util.h"
...@@ -45,7 +46,8 @@ class DriveURLRequestJobTest : public testing::Test { ...@@ -45,7 +46,8 @@ class DriveURLRequestJobTest : public testing::Test {
TEST_F(DriveURLRequestJobTest, NonGetMethod) { TEST_F(DriveURLRequestJobTest, NonGetMethod) {
net::TestURLRequest request( net::TestURLRequest request(
GURL("drive:file_id"), delegate_.get(), url_request_context_.get()); util::FilePathToDriveURL(base::FilePath::FromUTF8Unsafe("file")),
delegate_.get(), url_request_context_.get());
request.set_method("POST"); // Set non "GET" method. request.set_method("POST"); // Set non "GET" method.
scoped_refptr<DriveURLRequestJob> job( scoped_refptr<DriveURLRequestJob> job(
...@@ -59,20 +61,4 @@ TEST_F(DriveURLRequestJobTest, NonGetMethod) { ...@@ -59,20 +61,4 @@ TEST_F(DriveURLRequestJobTest, NonGetMethod) {
EXPECT_EQ(net::ERR_METHOD_NOT_SUPPORTED, request.status().error()); EXPECT_EQ(net::ERR_METHOD_NOT_SUPPORTED, request.status().error());
} }
TEST_F(DriveURLRequestJobTest, NonDriveScheme) {
net::TestURLRequest request(
GURL("http://www.google.com"),
delegate_.get(), url_request_context_.get());
scoped_refptr<DriveURLRequestJob> job(
new DriveURLRequestJob(
base::Bind(&GetNullDriveFileSystem),
&request, network_delegate_.get()));
job->Start();
MessageLoop::current()->RunUntilIdle();
EXPECT_EQ(net::URLRequestStatus::FAILED, request.status().status());
EXPECT_EQ(net::ERR_INVALID_URL, request.status().error());
}
} // namespace drive } // namespace drive
...@@ -283,9 +283,8 @@ void OnDriveFileFound(Profile* profile, ...@@ -283,9 +283,8 @@ void OnDriveFileFound(Profile* profile,
if (error == drive::DRIVE_FILE_OK) { if (error == drive::DRIVE_FILE_OK) {
GURL page_url; GURL page_url;
if (file_type == drive::REGULAR_FILE) { if (file_type == drive::REGULAR_FILE) {
page_url = drive::util::GetFileResourceUrl( page_url = drive::util::FilePathToDriveURL(
entry_proto->resource_id(), drive::util::ExtractDrivePath(file_path));
entry_proto->base_name());
} else if (file_type == drive::HOSTED_DOCUMENT) { } else if (file_type == drive::HOSTED_DOCUMENT) {
page_url = GURL(entry_proto->file_specific_info().alternate_url()); page_url = GURL(entry_proto->file_specific_info().alternate_url());
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment