Commit 9f11faaa authored by Allen Vicencio's avatar Allen Vicencio Committed by Commit Bot

Add SmbUrl class

Adds SmbUrl class which is used to represent Smb URLs. Includes unit
tests.

Bug: 757625
Change-Id: I2105f08a0df55dbaa0d50b1637d419a6cf5335f7
Reviewed-on: https://chromium-review.googlesource.com/1048745Reviewed-by: default avatarZentaro Kavanagh <zentaro@chromium.org>
Commit-Queue: Allen Vicencio <allenvic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557223}
parent 7cdad605
...@@ -1571,6 +1571,8 @@ source_set("chromeos") { ...@@ -1571,6 +1571,8 @@ source_set("chromeos") {
"smb_client/discovery/mdns_host_locator.h", "smb_client/discovery/mdns_host_locator.h",
"smb_client/discovery/network_scanner.cc", "smb_client/discovery/network_scanner.cc",
"smb_client/discovery/network_scanner.h", "smb_client/discovery/network_scanner.h",
"smb_client/smb_constants.cc",
"smb_client/smb_constants.h",
"smb_client/smb_file_system.cc", "smb_client/smb_file_system.cc",
"smb_client/smb_file_system.h", "smb_client/smb_file_system.h",
"smb_client/smb_file_system_id.cc", "smb_client/smb_file_system_id.cc",
...@@ -1583,6 +1585,8 @@ source_set("chromeos") { ...@@ -1583,6 +1585,8 @@ source_set("chromeos") {
"smb_client/smb_service_factory.h", "smb_client/smb_service_factory.h",
"smb_client/smb_task_queue.cc", "smb_client/smb_task_queue.cc",
"smb_client/smb_task_queue.h", "smb_client/smb_task_queue.h",
"smb_client/smb_url.cc",
"smb_client/smb_url.h",
"smb_client/temp_file_manager.cc", "smb_client/temp_file_manager.cc",
"smb_client/temp_file_manager.h", "smb_client/temp_file_manager.h",
"status/network_menu.cc", "status/network_menu.cc",
...@@ -2100,6 +2104,7 @@ source_set("unit_tests") { ...@@ -2100,6 +2104,7 @@ source_set("unit_tests") {
"smb_client/smb_file_system_id_test.cc", "smb_client/smb_file_system_id_test.cc",
"smb_client/smb_service_unittest.cc", "smb_client/smb_service_unittest.cc",
"smb_client/smb_task_queue_unittest.cc", "smb_client/smb_task_queue_unittest.cc",
"smb_client/smb_url_unittest.cc",
"smb_client/temp_file_manager_unittest.cc", "smb_client/temp_file_manager_unittest.cc",
"system/automatic_reboot_manager_unittest.cc", "system/automatic_reboot_manager_unittest.cc",
"system/device_disabling_manager_unittest.cc", "system/device_disabling_manager_unittest.cc",
......
// Copyright 2018 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 "chrome/browser/chromeos/smb_client/smb_constants.h"
namespace chromeos {
namespace smb_client {
const char kSmbScheme[] = "smb";
const char kSmbSchemePrefix[] = "smb://";
} // namespace smb_client
} // namespace chromeos
// Copyright 2018 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 CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_CONSTANTS_H_
#define CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_CONSTANTS_H_
namespace chromeos {
namespace smb_client {
extern const char kSmbScheme[];
extern const char kSmbSchemePrefix[];
} // namespace smb_client
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_CONSTANTS_H_
// Copyright 2018 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 "chrome/browser/chromeos/smb_client/smb_url.h"
#include "base/strings/string_util.h"
#include "chrome/browser/chromeos/smb_client/smb_constants.h"
namespace chromeos {
namespace smb_client {
namespace {
const char kDoubleBackslash[] = "\\\\";
// Returns true if |url| starts with "smb://" or "\\".
bool ShouldProcessUrl(const std::string& url) {
return base::StartsWith(url, kSmbSchemePrefix,
base::CompareCase::INSENSITIVE_ASCII) ||
base::StartsWith(url, kDoubleBackslash,
base::CompareCase::INSENSITIVE_ASCII);
}
// Adds "smb://" to the beginning of |url| if not present.
std::string AddSmbSchemeIfMissing(const std::string& url) {
DCHECK(ShouldProcessUrl(url));
if (base::StartsWith(url, kSmbSchemePrefix,
base::CompareCase::INSENSITIVE_ASCII)) {
return url;
}
return std::string(kSmbSchemePrefix) + url;
}
} // namespace
SmbUrl::SmbUrl() = default;
SmbUrl::~SmbUrl() = default;
bool SmbUrl::InitializeWithUrl(const std::string& url) {
// Only process |url| if it starts with "smb://" or "\\".
if (ShouldProcessUrl(url)) {
// Add "smb://" if |url| starts with "\\".
url_ = GURL(AddSmbSchemeIfMissing(url));
}
return IsValid();
}
std::string SmbUrl::GetHost() const {
DCHECK(IsValid());
return url_.host();
}
const std::string& SmbUrl::ToString() const {
DCHECK(IsValid());
return url_.spec();
}
std::string SmbUrl::ReplaceHost(const std::string& new_host) const {
DCHECK(IsValid());
GURL::Replacements replace_host;
replace_host.SetHostStr(new_host);
return url_.ReplaceComponents(replace_host).spec();
}
bool SmbUrl::IsValid() const {
return url_.is_valid();
}
} // namespace smb_client
} // namespace chromeos
// Copyright 2018 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 CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_URL_H_
#define CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_URL_H_
#include <string>
#include "base/macros.h"
#include "url/gurl.h"
namespace chromeos {
namespace smb_client {
// Represents an SMB URL.
// This class stores a URL using GURL to a share and can contain either an
// resolved or unresolved host. The host can be replaced when the address is
// resolved by using ReplaceHost(). The passed URL must start with either
// "smb://" or "\\" when initializing with InitializeWithUrl.
class SmbUrl {
public:
// Initializes an empty and invalid SmbUrl.
SmbUrl();
~SmbUrl();
// Initializes SmbUrl and saves |url|. |url| must start with
// either "smb://" or "\\". Returns true if |url| is valid.
bool InitializeWithUrl(const std::string& url) WARN_UNUSED_RESULT;
// Returns the host of the URL which can be resolved or unresolved.
std::string GetHost() const;
// Returns the full URL.
const std::string& ToString() const;
// Replaces the host to |new_host| and returns the full URL. Does not
// change the original URL.
std::string ReplaceHost(const std::string& new_host) const;
// Returns true if the passed URL is valid and was properly parsed.
bool IsValid() const;
private:
GURL url_;
DISALLOW_COPY_AND_ASSIGN(SmbUrl);
};
} // namespace smb_client
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_SMB_CLIENT_SMB_URL_H_
// Copyright 2018 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 "chrome/browser/chromeos/smb_client/smb_url.h"
#include <string>
#include "chrome/browser/chromeos/smb_client/smb_constants.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/url_util.h"
namespace chromeos {
namespace smb_client {
class SmbUrlTest : public testing::Test {
public:
SmbUrlTest() {
// Add the scheme to the "standard" list for url_util. This enables GURL to
// properly process the domain from the url.
url::AddStandardScheme(kSmbScheme, url::SCHEME_WITH_HOST);
}
~SmbUrlTest() override = default;
private:
DISALLOW_COPY_AND_ASSIGN(SmbUrlTest);
};
TEST_F(SmbUrlTest, NotValidWhenInitialized) {
SmbUrl smb_url;
EXPECT_FALSE(smb_url.IsValid());
}
TEST_F(SmbUrlTest, EmptyUrlIsInvalid) {
const std::string empty_url = "";
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl(empty_url));
EXPECT_FALSE(smb_url.IsValid());
}
TEST_F(SmbUrlTest, InvalidUrls) {
{
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl("smb"));
}
{
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl("smb://"));
}
{
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl("\\"));
}
{
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl("\\\\"));
}
{
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl("smb:///"));
}
}
TEST_F(SmbUrlTest, ValidUrls) {
{
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl("smb://x"));
const std::string expected_url = "smb://x/";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "x";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl("smb:///x"));
const std::string expected_url = "smb://x/";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "x";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl("smb://server/share/long/folder"));
const std::string expected_url = "smb://server/share/long/folder";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(
smb_url.InitializeWithUrl("smb://server/share/folder.with.dots"));
const std::string expected_url = "smb://server/share/folder.with.dots";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(
smb_url.InitializeWithUrl("smb://server\\share/mixed\\slashes"));
const std::string expected_url = "smb://server/share/mixed/slashes";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl("\\\\server/share"));
const std::string expected_url = "smb://server/share";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl("\\\\server\\share/mixed//slashes"));
const std::string expected_url = "smb://server/share/mixed//slashes";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
{
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl("smb://192.168.0.1/share"));
const std::string expected_url = "smb://192.168.0.1/share";
EXPECT_EQ(expected_url, smb_url.ToString());
const std::string expected_host = "192.168.0.1";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
}
TEST_F(SmbUrlTest, NotValidIfStartsWithoutSchemeOrDoubleBackslash) {
const std::string url = "192.168.0.1/share";
SmbUrl smb_url;
EXPECT_FALSE(smb_url.InitializeWithUrl(url));
EXPECT_FALSE(smb_url.IsValid());
}
TEST_F(SmbUrlTest, StartsWithBackslashRemovesBackslashAndAddsScheme) {
const std::string url = "\\\\192.168.0.1\\share";
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl(url));
const std::string expected_url = "smb://192.168.0.1/share";
EXPECT_TRUE(smb_url.IsValid());
EXPECT_EQ(expected_url, smb_url.ToString());
}
TEST_F(SmbUrlTest, GetHostWithIp) {
const std::string url = "smb://192.168.0.1/share";
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl(url));
const std::string expected_host = "192.168.0.1";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
TEST_F(SmbUrlTest, GetHostWithDomain) {
const std::string url = "smb://server/share";
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl(url));
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
}
TEST_F(SmbUrlTest, HostBecomesLowerCase) {
const std::string url = "smb://SERVER/share";
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl(url));
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
const std::string expected_url = "smb://server/share";
EXPECT_EQ(expected_url, smb_url.ToString());
}
TEST_F(SmbUrlTest, ReplacesHost) {
const std::string url = "smb://server/share";
const std::string new_host = "192.168.0.1";
SmbUrl smb_url;
EXPECT_TRUE(smb_url.InitializeWithUrl(url));
const std::string expected_host = "server";
EXPECT_EQ(expected_host, smb_url.GetHost());
const std::string expected_url = "smb://192.168.0.1/share";
EXPECT_EQ(expected_url, smb_url.ReplaceHost(new_host));
// GetHost returns the original host.
EXPECT_EQ(expected_host, smb_url.GetHost());
}
} // namespace smb_client
} // namespace chromeos
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