Commit 32778ae4 authored by Bin Zhao's avatar Bin Zhao Committed by Commit Bot

[DIAL] Added a DialURLFetcher to handle Dial related HTTP requests

DeviceDescriptionFetcher and DialAppInfoFetcher have some common code.
Create a DialURLFetcher class to get rid of some duplications.

The common URLFetcher class can also be used to launch and stop Dial
apps when we implement DIAL launch at browser side.

Bug: 816628
Change-Id: I26bdfbbf7e2d59a68e3bf5aeaba8b6e3664bf430
Reviewed-on: https://chromium-review.googlesource.com/938158Reviewed-by: default avatarRamin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarDerek Cheng <imcheng@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Commit-Queue: Bin Zhao <zhaobin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#540242}
parent 42e81a6a
......@@ -25,8 +25,6 @@ static_library("discovery") {
"dial/device_description_service.h",
"dial/dial_app_discovery_service.cc",
"dial/dial_app_discovery_service.h",
"dial/dial_app_info_fetcher.cc",
"dial/dial_app_info_fetcher.h",
"dial/dial_device_data.cc",
"dial/dial_device_data.h",
"dial/dial_media_sink_service.cc",
......@@ -37,6 +35,8 @@ static_library("discovery") {
"dial/dial_registry.h",
"dial/dial_service.cc",
"dial/dial_service.h",
"dial/dial_url_fetcher.cc",
"dial/dial_url_fetcher.h",
"dial/parsed_dial_app_info.cc",
"dial/parsed_dial_app_info.h",
"dial/parsed_dial_device_description.cc",
......
......@@ -4,72 +4,14 @@
#include "chrome/browser/media/router/discovery/dial/device_description_fetcher.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
constexpr char kApplicationUrlHeaderName[] = "Application-URL";
constexpr int kMaxRetries = 3;
// DIAL devices are unlikely to expose uPnP functions other than DIAL, so 256kb
// should be more than sufficient.
constexpr int kMaxDescriptionSizeBytes = 262144;
namespace media_router {
namespace {
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("dial_get_device_description", R"(
semantics {
sender: "DIAL"
description:
"Chromium sends a request to a device (such as a smart TV) "
"discovered via the DIAL (Disovery and Launch) protocol to obtain "
"its device description. Chromium then uses the device description "
"to determine the capabilities of the device to be used as a "
"target for casting media content."
trigger:
"A new or updated device has been discovered via DIAL in the local "
"network."
data: "An HTTP GET request."
destination: OTHER
destination_other:
"A device in the local network."
}
policy {
cookies_allowed: NO
setting:
"This feature cannot be disabled by settings and can only be "
"disabled by media-router flag."
chrome_policy {
EnableMediaRouter {
policy_options {mode: MANDATORY}
EnableMediaRouter: false
}
}
})");
void BindURLLoaderFactoryRequestOnUIThread(
network::mojom::URLLoaderFactoryRequest request) {
network::mojom::URLLoaderFactory* factory =
g_browser_process->system_network_context_manager()
->GetURLLoaderFactory();
factory->Clone(std::move(request));
}
} // namespace
DeviceDescriptionFetcher::DeviceDescriptionFetcher(
const GURL& device_description_url,
base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb,
......@@ -86,75 +28,24 @@ DeviceDescriptionFetcher::~DeviceDescriptionFetcher() {
void DeviceDescriptionFetcher::Start() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!loader_);
auto request = std::make_unique<network::ResourceRequest>();
request->url = device_description_url_;
// net::LOAD_BYPASS_PROXY: Proxies almost certainly hurt more cases than they
// help.
// net::LOAD_DISABLE_CACHE: The request should not touch the cache.
// net::LOAD_DO_NOT_{SAVE,SEND}_COOKIES: The request should not touch cookies.
// net::LOAD_DO_NOT_SEND_AUTH_DATA: The request should not send auth data.
request->load_flags = net::LOAD_BYPASS_PROXY | net::LOAD_DISABLE_CACHE |
net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DO_NOT_SEND_COOKIES |
net::LOAD_DO_NOT_SEND_AUTH_DATA;
loader_ =
network::SimpleURLLoader::Create(std::move(request), kTrafficAnnotation);
// Allow the fetcher to retry on 5XX responses and ERR_NETWORK_CHANGED.
loader_->SetRetryOptions(
kMaxRetries,
network::SimpleURLLoader::RetryMode::RETRY_ON_5XX |
network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
// Section 5.4 of the DIAL spec prohibits redirects.
// In practice, the callback will only get called once, since |loader_| will
// be deleted on redirect.
loader_->SetOnRedirectCallback(base::BindRepeating(
&DeviceDescriptionFetcher::ReportRedirectError, base::Unretained(this)));
StartDownload();
}
DCHECK(!fetcher_);
void DeviceDescriptionFetcher::StartDownload() {
// Bind the request to the system URLLoaderFactory obtained on UI thread.
// Currently this is the only way to guarantee a live URLLoaderFactory.
// TOOD(mmenke): Figure out a way to do this transparently on IO thread.
network::mojom::URLLoaderFactoryPtr loader_factory;
content::BrowserThread::PostTask(
content::BrowserThread::UI, FROM_HERE,
base::BindOnce(&BindURLLoaderFactoryRequestOnUIThread,
mojo::MakeRequest(&loader_factory)));
loader_->DownloadToString(
loader_factory.get(),
fetcher_ = std::make_unique<DialURLFetcher>(
device_description_url_,
base::BindOnce(&DeviceDescriptionFetcher::ProcessResponse,
base::Unretained(this)),
kMaxDescriptionSizeBytes);
base::BindOnce(&DeviceDescriptionFetcher::ReportError,
base::Unretained(this)));
fetcher_->Start();
}
void DeviceDescriptionFetcher::ProcessResponse(
std::unique_ptr<std::string> response) {
void DeviceDescriptionFetcher::ProcessResponse(const std::string& response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (loader_->NetError() != net::Error::OK) {
ReportError(base::StringPrintf(
"HTTP %d: Unable to fetch device description", loader_->NetError()));
return;
}
if (!response || response->empty()) {
ReportError("Missing or empty response");
return;
}
if (!base::IsStringUTF8(*response)) {
ReportError("Invalid response encoding");
return;
}
DCHECK(fetcher_);
const network::ResourceResponseHead* response_info = loader_->ResponseInfo();
const network::ResourceResponseHead* response_info =
fetcher_->GetResponseHead();
DCHECK(response_info);
// NOTE: The uPnP spec requires devices to set a Content-Type: header of
......@@ -165,7 +56,7 @@ void DeviceDescriptionFetcher::ProcessResponse(
!response_info->headers->GetNormalizedHeader(kApplicationUrlHeaderName,
&app_url_header) ||
app_url_header.empty()) {
ReportError("Missing or empty Application-URL:");
ReportError(net::Error::OK, "Missing or empty Application-URL:");
return;
}
......@@ -175,7 +66,8 @@ void DeviceDescriptionFetcher::ProcessResponse(
if (!app_url.is_valid() || !app_url.SchemeIs("http") ||
!app_url.HostIsIPAddress() ||
app_url.host() != device_description_url_.host()) {
ReportError(base::StringPrintf("Invalid Application-URL: %s",
ReportError(net::Error::OK,
base::StringPrintf("Invalid Application-URL: %s",
app_url_header.c_str()));
return;
}
......@@ -186,20 +78,14 @@ void DeviceDescriptionFetcher::ProcessResponse(
app_url = GURL(app_url_header.substr(0, app_url_header.length() - 1));
}
std::move(success_cb_).Run(DialDeviceDescriptionData(*response, app_url));
}
void DeviceDescriptionFetcher::ReportRedirectError(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) {
// Cancel the request.
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
loader_.reset();
ReportError("Redirect not allowed");
std::move(success_cb_).Run(DialDeviceDescriptionData(response, app_url));
fetcher_.reset();
}
void DeviceDescriptionFetcher::ReportError(const std::string& message) {
void DeviceDescriptionFetcher::ReportError(int response_code,
const std::string& message) {
std::move(error_cb_).Run(message);
fetcher_.reset();
}
} // namespace media_router
......@@ -10,18 +10,9 @@
#include "base/callback.h"
#include "base/sequence_checker.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h"
#include "url/gurl.h"
namespace net {
struct RedirectInfo;
}
namespace network {
class SimpleURLLoader;
struct ResourceResponseHead;
}
namespace media_router {
struct DialDeviceDescriptionData;
......@@ -42,31 +33,24 @@ class DeviceDescriptionFetcher {
const GURL& device_description_url() { return device_description_url_; }
void Start();
// Marked virtual for tests.
virtual void Start();
private:
friend class TestDeviceDescriptionFetcher;
// Starts the download on |loader_|.
virtual void StartDownload();
// Processes the response from the GET request and invoke the success or
// error callback.
void ProcessResponse(std::unique_ptr<std::string> response);
// Invokes the error callback due to a redirect that had occurred. Also
// aborts the request.
void ReportRedirectError(const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head);
void ProcessResponse(const std::string& response);
// Runs |error_cb_| with |message| and clears it.
void ReportError(const std::string& message);
void ReportError(int response_code, const std::string& message);
const GURL device_description_url_;
base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb_;
base::OnceCallback<void(const std::string&)> error_cb_;
std::unique_ptr<network::SimpleURLLoader> loader_;
std::unique_ptr<DialURLFetcher> fetcher_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(DeviceDescriptionFetcher);
......
......@@ -12,11 +12,9 @@
#include "base/test/scoped_task_environment.h"
#include "chrome/browser/media/router/discovery/dial/device_description_fetcher.h"
#include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "chrome/browser/media/router/test/test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -37,12 +35,15 @@ class TestDeviceDescriptionFetcher : public DeviceDescriptionFetcher {
factory_(factory) {}
~TestDeviceDescriptionFetcher() override = default;
void StartDownload() override {
loader_->DownloadToString(
factory_,
void Start() override {
fetcher_ = std::make_unique<TestDialURLFetcher>(
device_description_url_,
base::BindOnce(&DeviceDescriptionFetcher::ProcessResponse,
base::Unretained(this)),
256 * 1024);
base::BindOnce(&DeviceDescriptionFetcher::ReportError,
base::Unretained(this)),
factory_);
fetcher_->Start();
}
private:
......@@ -67,14 +68,14 @@ class DeviceDescriptionFetcherTest : public testing::Test {
}
void StartRequest() {
fetcher_ = std::make_unique<TestDeviceDescriptionFetcher>(
description_fetcher_ = std::make_unique<TestDeviceDescriptionFetcher>(
url_,
base::BindOnce(&DeviceDescriptionFetcherTest::OnSuccess,
base::Unretained(this)),
base::BindOnce(&DeviceDescriptionFetcherTest::OnError,
base::Unretained(this)),
&loader_factory_);
fetcher_->Start();
description_fetcher_->Start();
base::RunLoop().RunUntilIdle();
}
......@@ -84,7 +85,7 @@ class DeviceDescriptionFetcherTest : public testing::Test {
network::TestURLLoaderFactory loader_factory_;
base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb_;
base::OnceCallback<void(const std::string&)> error_cb_;
std::unique_ptr<TestDeviceDescriptionFetcher> fetcher_;
std::unique_ptr<TestDeviceDescriptionFetcher> description_fetcher_;
GURL expected_app_url_;
std::string expected_description_;
std::string expected_error_;
......
......@@ -8,7 +8,7 @@
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/time/default_clock.h"
#include "chrome/browser/media/router/discovery/dial/dial_app_info_fetcher.h"
#include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h"
#include "chrome/browser/media/router/discovery/dial/safe_dial_app_info_parser.h"
#include "net/http/http_status_code.h"
#include "url/gurl.h"
......@@ -62,13 +62,12 @@ void DialAppDiscoveryService::FetchDialAppInfo(const MediaSinkInternal& sink,
GURL app_url = GetAppUrl(sink, app_name);
DVLOG(2) << "Fetch DIAL app info from: " << app_url.spec();
std::unique_ptr<DialAppInfoFetcher> fetcher =
std::make_unique<DialAppInfoFetcher>(
app_url,
base::BindOnce(&DialAppDiscoveryService::OnDialAppInfoFetchComplete,
base::Unretained(this), sink_id, app_name),
base::BindOnce(&DialAppDiscoveryService::OnDialAppInfoFetchError,
base::Unretained(this), sink_id, app_name));
std::unique_ptr<DialURLFetcher> fetcher = std::make_unique<DialURLFetcher>(
app_url,
base::BindOnce(&DialAppDiscoveryService::OnDialAppInfoFetchComplete,
base::Unretained(this), sink_id, app_name),
base::BindOnce(&DialAppDiscoveryService::OnDialAppInfoFetchError,
base::Unretained(this), sink_id, app_name));
fetcher->Start();
pending_fetcher_map_.emplace(request_id, std::move(fetcher));
}
......
......@@ -24,7 +24,7 @@ class Connector;
namespace media_router {
class DialAppInfoFetcher;
class DialURLFetcher;
class SafeDialAppInfoParser;
// Represents DIAL app status on receiver device.
......@@ -117,7 +117,7 @@ class DialAppDiscoveryService {
SafeDialAppInfoParser::ParsingResult parsing_result);
// Map of pending app info fetchers, keyed by request id.
base::flat_map<std::string, std::unique_ptr<DialAppInfoFetcher>>
base::flat_map<std::string, std::unique_ptr<DialURLFetcher>>
pending_fetcher_map_;
// See comments for DialAppInfoParseCompletedCallback.
......
......@@ -6,7 +6,6 @@
#include "base/strings/stringprintf.h"
#include "base/test/mock_callback.h"
#include "chrome/browser/media/router/discovery/dial/dial_app_info_fetcher.h"
#include "chrome/browser/media/router/discovery/dial/parsed_dial_device_description.h"
#include "chrome/browser/media/router/discovery/dial/safe_dial_app_info_parser.h"
#include "chrome/browser/media/router/test/test_helper.h"
......
......@@ -2,9 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/media/router/discovery/dial/dial_app_info_fetcher.h"
#include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "content/public/browser/browser_thread.h"
......@@ -20,22 +19,22 @@
constexpr int kMaxRetries = 3;
// DIAL devices are unlikely to expose uPnP functions other than DIAL, so 256kb
// should be more than sufficient.
constexpr int kMaxAppInfoSizeBytes = 262144;
constexpr int kMaxResponseSizeBytes = 262144;
namespace media_router {
namespace {
constexpr net::NetworkTrafficAnnotationTag kTrafficAnnotation =
net::DefineNetworkTrafficAnnotation("dial_get_app_info", R"(
net::DefineNetworkTrafficAnnotation("dial_url_fetcher", R"(
semantics {
sender: "DIAL"
description:
"Chromium sends a request to a device (such as a smart TV) "
"discovered via the DIAL (Discovery and Launch) protocol to obtain "
"its app info data. Chromium then uses the app info data to"
"determine the capabilities of the device to be used as a target"
"for casting media content."
"its device description or app info data. Chromium then uses the "
"data to determine the capabilities of the device to be used as a "
"targetfor casting media content."
trigger:
"A new or updated device has been discovered via DIAL in the local "
"network."
......@@ -66,26 +65,31 @@ void BindURLLoaderFactoryRequestOnUIThread(
} // namespace
DialAppInfoFetcher::DialAppInfoFetcher(
const GURL& app_url,
DialURLFetcher::DialURLFetcher(
const GURL& url,
base::OnceCallback<void(const std::string&)> success_cb,
base::OnceCallback<void(int, const std::string&)> error_cb)
: app_url_(app_url),
: url_(url),
success_cb_(std::move(success_cb)),
error_cb_(std::move(error_cb)) {
DCHECK(app_url_.is_valid());
DCHECK(url_.is_valid());
}
DialAppInfoFetcher::~DialAppInfoFetcher() {
DialURLFetcher::~DialURLFetcher() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
void DialAppInfoFetcher::Start() {
const network::ResourceResponseHead* DialURLFetcher::GetResponseHead() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return loader_ ? loader_->ResponseInfo() : nullptr;
}
void DialURLFetcher::Start() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!loader_);
auto request = std::make_unique<network::ResourceRequest>();
request->url = app_url_;
request->url = url_;
// net::LOAD_BYPASS_PROXY: Proxies almost certainly hurt more cases than they
// help.
......@@ -110,17 +114,17 @@ void DialAppInfoFetcher::Start() {
// In practice, the callback will only get called once, since |loader_| will
// be deleted.
loader_->SetOnRedirectCallback(base::BindRepeating(
&DialAppInfoFetcher::ReportRedirectError, base::Unretained(this)));
&DialURLFetcher::ReportRedirectError, base::Unretained(this)));
StartDownload();
}
void DialAppInfoFetcher::ReportError(int response_code,
const std::string& message) {
void DialURLFetcher::ReportError(int response_code,
const std::string& message) {
std::move(error_cb_).Run(response_code, message);
}
void DialAppInfoFetcher::ReportRedirectError(
void DialURLFetcher::ReportRedirectError(
const net::RedirectInfo& redirect_info,
const network::ResourceResponseHead& response_head) {
// Cancel the request.
......@@ -131,7 +135,7 @@ void DialAppInfoFetcher::ReportRedirectError(
ReportError(net::Error::OK, "Redirect not allowed");
}
void DialAppInfoFetcher::StartDownload() {
void DialURLFetcher::StartDownload() {
// Bind the request to the system URLLoaderFactory obtained on UI thread.
// Currently this is the only way to guarantee a live URLLoaderFactory.
// TOOD(mmenke): Figure out a way to do this transparently on IO thread.
......@@ -141,14 +145,13 @@ void DialAppInfoFetcher::StartDownload() {
base::BindOnce(&BindURLLoaderFactoryRequestOnUIThread,
mojo::MakeRequest(&loader_factory)));
loader_->DownloadToString(loader_factory.get(),
base::BindOnce(&DialAppInfoFetcher::ProcessResponse,
base::Unretained(this)),
kMaxAppInfoSizeBytes);
loader_->DownloadToString(
loader_factory.get(),
base::BindOnce(&DialURLFetcher::ProcessResponse, base::Unretained(this)),
kMaxResponseSizeBytes);
}
void DialAppInfoFetcher::ProcessResponse(
std::unique_ptr<std::string> response) {
void DialURLFetcher::ProcessResponse(std::unique_ptr<std::string> response) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
int response_code = loader_->NetError();
if (response_code != net::Error::OK) {
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DIAL_APP_INFO_FETCHER_H_
#define CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DIAL_APP_INFO_FETCHER_H_
#ifndef CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DIAL_URL_FETCHER_H_
#define CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DIAL_URL_FETCHER_H_
#include <memory>
#include <string>
......@@ -23,27 +23,39 @@ struct ResourceResponseHead;
namespace media_router {
// Used to make a single HTTP GET request with |app_url| to fetch an app info
// Used to make a single HTTP GET request with |url| to fetch a response
// from a DIAL device. If successful, |success_cb| is invoked with the result;
// otherwise, |error_cb| is invoked with an error reason.
// This class is not sequence safe.
class DialAppInfoFetcher {
class DialURLFetcher {
public:
DialAppInfoFetcher(
const GURL& app_url,
base::OnceCallback<void(const std::string&)> success_cb,
base::OnceCallback<void(int, const std::string&)> error_cb);
// Constructor.
// |url|: HTTP request URL
// |success_cb|: Invoked when HTTP request to |url| succeeds
// |arg 0|: response text of the HTTP request
// |error_cb|: Invoked when HTTP request to |url| fails
// |arg 0|: HTTP response code
// |arg 1|: error message
DialURLFetcher(const GURL& url,
base::OnceCallback<void(const std::string&)> success_cb,
base::OnceCallback<void(int, const std::string&)> error_cb);
virtual ~DialAppInfoFetcher();
virtual ~DialURLFetcher();
const GURL& app_url() { return app_url_; }
const GURL& url() { return url_; }
// Starts the fetch. |ProcessResponse| will be invoked on completion.
// |ReportRedirectError| will be invoked when a redirect occurrs.
void Start();
// Returns the response header of an HTTP request. The response header is
// owned by underlying |loader_| object and is reset per HTTP request. Returns
// nullptr if this function is called before |loader_| has informed the caller
// of completion.
const network::ResourceResponseHead* GetResponseHead() const;
private:
friend class TestDialAppInfoFetcher;
friend class TestDialURLFetcher;
// Starts the download on |loader_|.
virtual void StartDownload();
......@@ -58,15 +70,15 @@ class DialAppInfoFetcher {
// Runs |error_cb_| with |message| and clears it.
void ReportError(int response_code, const std::string& message);
const GURL app_url_;
const GURL url_;
base::OnceCallback<void(const std::string&)> success_cb_;
base::OnceCallback<void(int, const std::string&)> error_cb_;
std::unique_ptr<network::SimpleURLLoader> loader_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(DialAppInfoFetcher);
DISALLOW_COPY_AND_ASSIGN(DialURLFetcher);
};
} // namespace media_router
#endif // CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DIAL_APP_INFO_FETCHER_H_
#endif // CHROME_BROWSER_MEDIA_ROUTER_DISCOVERY_DIAL_DIAL_URL_FETCHER_H_
......@@ -9,14 +9,14 @@
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "chrome/browser/media/router/discovery/dial/dial_app_info_fetcher.h"
#include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h"
#include "chrome/browser/media/router/test/test_helper.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_fetcher.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
......@@ -24,32 +24,9 @@
namespace media_router {
class TestDialAppInfoFetcher : public DialAppInfoFetcher {
class DialURLFetcherTest : public testing::Test {
public:
TestDialAppInfoFetcher(
const GURL& app_url,
base::OnceCallback<void(const std::string&)> success_cb,
base::OnceCallback<void(int, const std::string&)> error_cb,
network::TestURLLoaderFactory* factory)
: DialAppInfoFetcher(app_url, std::move(success_cb), std::move(error_cb)),
factory_(factory) {}
~TestDialAppInfoFetcher() override = default;
void StartDownload() override {
loader_->DownloadToString(
factory_,
base::BindOnce(&DialAppInfoFetcher::ProcessResponse,
base::Unretained(this)),
256 * 1024);
}
private:
network::TestURLLoaderFactory* const factory_;
};
class DialAppInfoFetcherTest : public testing::Test {
public:
DialAppInfoFetcherTest() : url_("http://127.0.0.1/app/Youtube") {}
DialURLFetcherTest() : url_("http://127.0.0.1/app/Youtube") {}
void ExpectSuccess(const std::string& expected_app_info) {
EXPECT_CALL(*this, OnSuccess(expected_app_info));
......@@ -61,12 +38,10 @@ class DialAppInfoFetcherTest : public testing::Test {
}
void StartRequest() {
fetcher_ = std::make_unique<TestDialAppInfoFetcher>(
fetcher_ = std::make_unique<TestDialURLFetcher>(
url_,
base::BindOnce(&DialAppInfoFetcherTest::OnSuccess,
base::Unretained(this)),
base::BindOnce(&DialAppInfoFetcherTest::OnError,
base::Unretained(this)),
base::BindOnce(&DialURLFetcherTest::OnSuccess, base::Unretained(this)),
base::BindOnce(&DialURLFetcherTest::OnError, base::Unretained(this)),
&loader_factory_);
fetcher_->Start();
base::RunLoop().RunUntilIdle();
......@@ -77,7 +52,7 @@ class DialAppInfoFetcherTest : public testing::Test {
network::TestURLLoaderFactory loader_factory_;
const GURL url_;
std::string expected_error_;
std::unique_ptr<TestDialAppInfoFetcher> fetcher_;
std::unique_ptr<TestDialURLFetcher> fetcher_;
private:
MOCK_METHOD1(OnSuccess, void(const std::string&));
......@@ -88,10 +63,10 @@ class DialAppInfoFetcherTest : public testing::Test {
DoOnError();
}
DISALLOW_COPY_AND_ASSIGN(DialAppInfoFetcherTest);
DISALLOW_COPY_AND_ASSIGN(DialURLFetcherTest);
};
TEST_F(DialAppInfoFetcherTest, FetchSuccessful) {
TEST_F(DialURLFetcherTest, FetchSuccessful) {
std::string body("<xml>appInfo</xml>");
ExpectSuccess(body);
network::URLLoaderCompletionStatus status;
......@@ -101,7 +76,7 @@ TEST_F(DialAppInfoFetcherTest, FetchSuccessful) {
StartRequest();
}
TEST_F(DialAppInfoFetcherTest, FetchFailsOnMissingAppInfo) {
TEST_F(DialURLFetcherTest, FetchFailsOnMissingAppInfo) {
ExpectError("HTTP 404:");
loader_factory_.AddResponse(
......@@ -110,7 +85,7 @@ TEST_F(DialAppInfoFetcherTest, FetchFailsOnMissingAppInfo) {
StartRequest();
}
TEST_F(DialAppInfoFetcherTest, FetchFailsOnEmptyAppInfo) {
TEST_F(DialURLFetcherTest, FetchFailsOnEmptyAppInfo) {
ExpectError("Missing or empty response");
loader_factory_.AddResponse(url_, network::ResourceResponseHead(), "",
......@@ -118,7 +93,7 @@ TEST_F(DialAppInfoFetcherTest, FetchFailsOnEmptyAppInfo) {
StartRequest();
}
TEST_F(DialAppInfoFetcherTest, FetchFailsOnBadAppInfo) {
TEST_F(DialURLFetcherTest, FetchFailsOnBadAppInfo) {
ExpectError("Invalid response encoding");
std::string body("\xfc\x9c\xbf\x80\xbf\x80");
network::URLLoaderCompletionStatus status;
......
......@@ -8,6 +8,7 @@
#include "base/json/string_escape.h"
#include "base/strings/stringprintf.h"
#include "chrome/common/media_router/media_source.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "url/gurl.h"
namespace media_router {
......@@ -55,6 +56,22 @@ MockDialMediaSinkService::~MockDialMediaSinkService() = default;
MockCastMediaSinkService::MockCastMediaSinkService() : CastMediaSinkService() {}
MockCastMediaSinkService::~MockCastMediaSinkService() = default;
TestDialURLFetcher::TestDialURLFetcher(
const GURL& url,
base::OnceCallback<void(const std::string&)> success_cb,
base::OnceCallback<void(int, const std::string&)> error_cb,
network::TestURLLoaderFactory* factory)
: DialURLFetcher(url, std::move(success_cb), std::move(error_cb)),
factory_(factory) {}
TestDialURLFetcher::~TestDialURLFetcher() = default;
void TestDialURLFetcher::StartDownload() {
loader_->DownloadToString(
factory_,
base::BindOnce(&DialURLFetcher::ProcessResponse, base::Unretained(this)),
256 * 1024);
}
#endif // !defined(OS_ANDROID)
net::IPEndPoint CreateIPEndPoint(int num) {
......
......@@ -14,6 +14,7 @@
#include "base/macros.h"
#include "build/build_config.h"
#include "chrome/browser/media/router/discovery/dial/dial_media_sink_service.h"
#include "chrome/browser/media/router/discovery/dial/dial_url_fetcher.h"
#include "chrome/browser/media/router/discovery/mdns/cast_media_sink_service.h"
#include "chrome/browser/media/router/issue_manager.h"
#include "chrome/browser/media/router/issues_observer.h"
......@@ -23,6 +24,7 @@
#include "content/public/browser/presentation_service_delegate.h"
#include "content/public/common/presentation_connection_message.h"
#include "net/base/ip_endpoint.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gmock/include/gmock/gmock.h"
namespace media_router {
......@@ -131,6 +133,19 @@ class MockCastMediaSinkService : public CastMediaSinkService {
MOCK_METHOD0(OnUserGesture, void());
MOCK_METHOD0(StartMdnsDiscovery, void());
};
class TestDialURLFetcher : public DialURLFetcher {
public:
TestDialURLFetcher(const GURL& url,
base::OnceCallback<void(const std::string&)> success_cb,
base::OnceCallback<void(int, const std::string&)> error_cb,
network::TestURLLoaderFactory* factory);
~TestDialURLFetcher() override;
void StartDownload() override;
private:
network::TestURLLoaderFactory* const factory_;
};
#endif // !defined(OS_ANDROID)
// Helper function to create an IP endpoint object.
......
......@@ -3029,12 +3029,12 @@ test("unit_tests") {
"../browser/media/router/discovery/dial/device_description_fetcher_unittest.cc",
"../browser/media/router/discovery/dial/device_description_service_unittest.cc",
"../browser/media/router/discovery/dial/dial_app_discovery_service_unittest.cc",
"../browser/media/router/discovery/dial/dial_app_info_fetcher_unittest.cc",
"../browser/media/router/discovery/dial/dial_device_data_unittest.cc",
"../browser/media/router/discovery/dial/dial_media_sink_service_impl_unittest.cc",
"../browser/media/router/discovery/dial/dial_media_sink_service_unittest.cc",
"../browser/media/router/discovery/dial/dial_registry_unittest.cc",
"../browser/media/router/discovery/dial/dial_service_unittest.cc",
"../browser/media/router/discovery/dial/dial_url_fetcher_unittest.cc",
"../browser/media/router/discovery/dial/safe_dial_app_info_parser_unittest.cc",
"../browser/media/router/discovery/dial/safe_dial_device_description_parser_unittest.cc",
"../browser/media/router/discovery/mdns/cast_media_sink_service_impl_unittest.cc",
......
......@@ -74,8 +74,9 @@ Refer to README.md for content description and update process.
<item id="devtools_http_handler" hash_code="49160454" type="0" content_hash_code="88414393" os_list="linux,windows" file_path="content/browser/devtools/devtools_http_handler.cc"/>
<item id="devtools_interceptor" hash_code="98123737" type="0" content_hash_code="19053470" os_list="linux,windows" file_path="content/browser/devtools/devtools_url_interceptor_request_job.cc"/>
<item id="devtools_network_resource" hash_code="129652775" type="0" content_hash_code="24059212" os_list="linux,windows" file_path="chrome/browser/devtools/devtools_ui_bindings.cc"/>
<item id="dial_get_app_info" hash_code="15952025" type="0" content_hash_code="90542080" os_list="linux,windows" file_path="chrome/browser/media/router/discovery/dial/dial_app_info_fetcher.cc"/>
<item id="dial_get_device_description" hash_code="50422598" type="0" content_hash_code="129827780" os_list="linux,windows" file_path="chrome/browser/media/router/discovery/dial/device_description_fetcher.cc"/>
<item id="dial_get_app_info" hash_code="15952025" type="0" deprecated="2018-02-27" content_hash_code="90542080" file_path=""/>
<item id="dial_get_device_description" hash_code="50422598" type="0" deprecated="2018-02-27" content_hash_code="129827780" file_path=""/>
<item id="dial_url_fetcher" hash_code="41424546" type="0" content_hash_code="129828432" os_list="linux,windows" file_path="chrome/browser/media/router/discovery/dial/dial_url_fetcher.cc"/>
<item id="dns_over_https" hash_code="79895226" type="0" content_hash_code="45123510" os_list="linux,windows" file_path="net/dns/dns_transaction.cc"/>
<item id="dns_transaction" hash_code="79227717" type="0" content_hash_code="132206495" os_list="linux,windows" file_path="net/dns/dns_transaction.cc"/>
<item id="dom_distiller" hash_code="3989826" type="0" content_hash_code="106153970" os_list="linux,windows" file_path="components/dom_distiller/core/distiller_url_fetcher.cc"/>
......
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