Disallow fetching of file:// URLs discovered by DHCP-based WPAD.
Bug: 839647
TBR: stevenjb@chromium.org
Cq-Include-Trybots: master.tryserver.chromium.linux:linux_mojo
Change-Id: I9223238b5f187d632d68d54fd2ee4fd50981fc56
Reviewed-on: https://chromium-review.googlesource.com/1045610
Commit-Queue: Eric Roman <eroman@chromium.org>
Reviewed-by: Helen Li <xunjieli@chromium.org>
Cr-Commit-Position: refs/heads/master@{#556644}
diff --git a/chromeos/network/dhcp_pac_file_fetcher_chromeos.cc b/chromeos/network/dhcp_pac_file_fetcher_chromeos.cc
index c4d4348..4605b22 100644
--- a/chromeos/network/dhcp_pac_file_fetcher_chromeos.cc
+++ b/chromeos/network/dhcp_pac_file_fetcher_chromeos.cc
@@ -35,7 +35,7 @@
net::URLRequestContext* url_request_context)
: weak_ptr_factory_(this) {
DCHECK(url_request_context);
- pac_file_fetcher_.reset(new net::PacFileFetcherImpl(url_request_context));
+ pac_file_fetcher_ = net::PacFileFetcherImpl::Create(url_request_context);
if (NetworkHandler::IsInitialized())
network_handler_task_runner_ = NetworkHandler::Get()->task_runner();
}
diff --git a/net/data/pac_file_fetcher_unittest/redirect-to-file b/net/data/pac_file_fetcher_unittest/redirect-to-file
new file mode 100644
index 0000000..f21ca1e
--- /dev/null
+++ b/net/data/pac_file_fetcher_unittest/redirect-to-file
@@ -0,0 +1 @@
+-redirected-
diff --git a/net/data/pac_file_fetcher_unittest/redirect-to-file.mock-http-headers b/net/data/pac_file_fetcher_unittest/redirect-to-file.mock-http-headers
new file mode 100644
index 0000000..20a45ae
--- /dev/null
+++ b/net/data/pac_file_fetcher_unittest/redirect-to-file.mock-http-headers
@@ -0,0 +1,2 @@
+HTTP/1.1 302 Found
+Location: file://bin/cat
diff --git a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
index b81f44d..d6515969 100644
--- a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
+++ b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.cc
@@ -153,7 +153,7 @@
TransitionToFinish();
} else {
state_ = STATE_WAIT_URL;
- script_fetcher_.reset(ImplCreateScriptFetcher());
+ script_fetcher_ = ImplCreateScriptFetcher();
script_fetcher_->Fetch(pac_url_, &pac_script_,
base::Bind(&DhcpPacFileAdapterFetcher::OnFetcherDone,
base::Unretained(this)),
@@ -194,8 +194,9 @@
return state_;
}
-PacFileFetcher* DhcpPacFileAdapterFetcher::ImplCreateScriptFetcher() {
- return new PacFileFetcherImpl(url_request_context_);
+std::unique_ptr<PacFileFetcher>
+DhcpPacFileAdapterFetcher::ImplCreateScriptFetcher() {
+ return PacFileFetcherImpl::Create(url_request_context_);
}
DhcpPacFileAdapterFetcher::DhcpQuery*
diff --git a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h
index 6e07d2b..4d84aef 100644
--- a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h
+++ b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win.h
@@ -148,7 +148,7 @@
};
// Virtual methods introduced to allow unit testing.
- virtual PacFileFetcher* ImplCreateScriptFetcher();
+ virtual std::unique_ptr<PacFileFetcher> ImplCreateScriptFetcher();
virtual DhcpQuery* ImplCreateDhcpQuery();
virtual base::TimeDelta ImplGetTimeout() const;
diff --git a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc
index ac97700..7fbffc8 100644
--- a/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc
+++ b/net/proxy_resolution/dhcp_pac_file_adapter_fetcher_win_unittest.cc
@@ -56,7 +56,7 @@
fetcher_ = NULL;
}
- PacFileFetcher* ImplCreateScriptFetcher() override {
+ std::unique_ptr<PacFileFetcher> ImplCreateScriptFetcher() override {
// We don't maintain ownership of the fetcher, it is transferred to
// the caller.
fetcher_ = new MockPacFileFetcher();
@@ -65,7 +65,7 @@
FROM_HERE, base::TimeDelta::FromMilliseconds(fetcher_delay_ms_), this,
&MockDhcpPacFileAdapterFetcher::OnFetcherTimer);
}
- return fetcher_;
+ return base::WrapUnique(fetcher_);
}
class DelayingDhcpQuery : public DhcpQuery {
@@ -276,9 +276,8 @@
url_request_context_(context) {}
// Returns a real PAC file fetcher.
- PacFileFetcher* ImplCreateScriptFetcher() override {
- PacFileFetcher* fetcher = new PacFileFetcherImpl(url_request_context_);
- return fetcher;
+ std::unique_ptr<PacFileFetcher> ImplCreateScriptFetcher() override {
+ return PacFileFetcherImpl::Create(url_request_context_);
}
URLRequestContext* url_request_context_;
diff --git a/net/proxy_resolution/pac_file_fetcher_impl.cc b/net/proxy_resolution/pac_file_fetcher_impl.cc
index 6a02e00..688f32f 100644
--- a/net/proxy_resolution/pac_file_fetcher_impl.cc
+++ b/net/proxy_resolution/pac_file_fetcher_impl.cc
@@ -19,6 +19,7 @@
#include "net/base/request_priority.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_response_headers.h"
+#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request_context.h"
// TODO(eroman):
@@ -81,17 +82,15 @@
} // namespace
-PacFileFetcherImpl::PacFileFetcherImpl(URLRequestContext* url_request_context)
- : url_request_context_(url_request_context),
- buf_(new IOBuffer(kBufSize)),
- next_id_(0),
- cur_request_id_(0),
- result_code_(OK),
- result_text_(NULL),
- max_response_bytes_(kDefaultMaxResponseBytes),
- max_duration_(kDefaultMaxDuration),
- weak_factory_(this) {
- DCHECK(url_request_context);
+std::unique_ptr<PacFileFetcherImpl> PacFileFetcherImpl::Create(
+ URLRequestContext* url_request_context) {
+ return base::WrapUnique(new PacFileFetcherImpl(url_request_context, false));
+}
+
+std::unique_ptr<PacFileFetcherImpl>
+PacFileFetcherImpl::CreateWithFileUrlSupport(
+ URLRequestContext* url_request_context) {
+ return base::WrapUnique(new PacFileFetcherImpl(url_request_context, true));
}
PacFileFetcherImpl::~PacFileFetcherImpl() {
@@ -137,6 +136,9 @@
if (!url_request_context_)
return ERR_CONTEXT_SHUT_DOWN;
+ if (!IsUrlSchemeAllowed(url))
+ return ERR_DISALLOWED_URL_SCHEME;
+
// Handle base-64 encoded data-urls that contain custom PAC scripts.
if (url.SchemeIs("data")) {
std::string mime_type;
@@ -211,6 +213,27 @@
}
}
+void PacFileFetcherImpl::OnReceivedRedirect(URLRequest* request,
+ const RedirectInfo& redirect_info,
+ bool* defer_redirect) {
+ int error = OK;
+
+ // Redirection to file:// is never OK. Ordinarily this is handled lower in the
+ // stack (|FileProtocolHandler::IsSafeRedirectTarget|), but this is reachable
+ // when built without file:// suppport. Return the same error for consistency.
+ if (redirect_info.new_url.SchemeIsFile()) {
+ error = ERR_UNSAFE_REDIRECT;
+ } else if (!IsUrlSchemeAllowed(redirect_info.new_url)) {
+ error = ERR_DISALLOWED_URL_SCHEME;
+ }
+
+ if (error != OK) {
+ // Fail the redirect.
+ request->CancelWithError(error);
+ OnResponseCompleted(request, error);
+ }
+}
+
void PacFileFetcherImpl::OnAuthRequired(URLRequest* request,
AuthChallengeInfo* auth_info) {
DCHECK_EQ(request, cur_request_.get());
@@ -280,6 +303,36 @@
}
}
+PacFileFetcherImpl::PacFileFetcherImpl(URLRequestContext* url_request_context,
+ bool allow_file_url)
+ : url_request_context_(url_request_context),
+ buf_(new IOBuffer(kBufSize)),
+ next_id_(0),
+ cur_request_id_(0),
+ result_code_(OK),
+ result_text_(NULL),
+ max_response_bytes_(kDefaultMaxResponseBytes),
+ max_duration_(kDefaultMaxDuration),
+ allow_file_url_(allow_file_url),
+ weak_factory_(this) {
+ DCHECK(url_request_context);
+}
+
+bool PacFileFetcherImpl::IsUrlSchemeAllowed(const GURL& url) const {
+ // Always allow http://, https://, data:, and ftp://.
+ if (url.SchemeIsHTTPOrHTTPS() || url.SchemeIs("ftp") || url.SchemeIs("data"))
+ return true;
+
+ // Only permit file:// if |allow_file_url_| was set. file:// should not be
+ // allowed for URLs that were auto-detected, or as the result of a server-side
+ // redirect.
+ if (url.SchemeIsFile())
+ return allow_file_url_;
+
+ // Disallow any other URL scheme.
+ return false;
+}
+
void PacFileFetcherImpl::ReadBody(URLRequest* request) {
// Read as many bytes as are available synchronously.
while (true) {
diff --git a/net/proxy_resolution/pac_file_fetcher_impl.h b/net/proxy_resolution/pac_file_fetcher_impl.h
index dac5a82..92d95993 100644
--- a/net/proxy_resolution/pac_file_fetcher_impl.h
+++ b/net/proxy_resolution/pac_file_fetcher_impl.h
@@ -38,7 +38,23 @@
// Note that while a request is in progress, we will be holding a reference
// to |url_request_context|. Be careful not to create cycles between the
// fetcher and the context; you can break such cycles by calling Cancel().
- explicit PacFileFetcherImpl(URLRequestContext* url_request_context);
+ //
+ // Fetch() supports the following URL schemes, provided the underlying
+ // |url_request_context| also supports them:
+ //
+ // * http://
+ // * https://
+ // * ftp://
+ // * data:
+ static std::unique_ptr<PacFileFetcherImpl> Create(
+ URLRequestContext* url_request_context);
+
+ // Same as Create(), but additionally allows fetching PAC URLs from file://
+ // URLs (provided the URLRequestContext supports it).
+ //
+ // This should not be used in new code (see https://crbug.com/839566).
+ static std::unique_ptr<PacFileFetcherImpl> CreateWithFileUrlSupport(
+ URLRequestContext* url_request_context);
~PacFileFetcherImpl() override;
@@ -58,6 +74,9 @@
void OnShutdown() override;
// URLRequest::Delegate methods:
+ void OnReceivedRedirect(URLRequest* request,
+ const RedirectInfo& redirect_info,
+ bool* defer_redirect) override;
void OnAuthRequired(URLRequest* request,
AuthChallengeInfo* auth_info) override;
void OnSSLCertificateError(URLRequest* request,
@@ -69,6 +88,13 @@
private:
enum { kBufSize = 4096 };
+ PacFileFetcherImpl(URLRequestContext* url_request_context,
+ bool allow_file_url);
+
+ // Returns true if |url| has an acceptable URL scheme (i.e. http://, https://,
+ // etc).
+ bool IsUrlSchemeAllowed(const GURL& url) const;
+
// Read more bytes from the response.
void ReadBody(URLRequest* request);
@@ -129,6 +155,8 @@
// The time that the first byte was received.
base::TimeTicks fetch_time_to_first_byte_;
+ const bool allow_file_url_;
+
// Factory for creating the time-out task. This takes care of revoking
// outstanding tasks when |this| is deleted.
base::WeakPtrFactory<PacFileFetcherImpl> weak_factory_;
diff --git a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
index 635178a..9fa21ce 100644
--- a/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
+++ b/net/proxy_resolution/pac_file_fetcher_impl_unittest.cc
@@ -123,9 +123,12 @@
URLRequestContextStorage storage_;
};
-#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
// Get a file:// url relative to net/data/proxy/pac_file_fetcher_unittest.
GURL GetTestFileUrl(const std::string& relpath) {
+#if BUILDFLAG(DISABLE_FILE_SUPPORT)
+ LOG(WARNING)
+ << "Built a file:// URL to test data, however file support is disabled.";
+#endif // BUILDFLAG(DISABLE_FILE_SUPPORT)
base::FilePath path;
base::PathService::Get(base::DIR_SOURCE_ROOT, &path);
path = path.AppendASCII("net");
@@ -134,7 +137,6 @@
GURL base_url = FilePathToFileURL(path);
return GURL(base_url.spec() + "/" + relpath);
}
-#endif // !BUILDFLAG(DISABLE_FILE_SUPPORT)
// Really simple NetworkDelegate so we can allow local file access on ChromeOS
// without introducing layering violations. Also causes a test failure if a
@@ -224,46 +226,91 @@
RequestContext context_;
};
-#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
-TEST_F(PacFileFetcherImplTest, FileUrl) {
- PacFileFetcherImpl pac_fetcher(&context_);
+// Try fetching a non-existent PAC file via file://.
+TEST_F(PacFileFetcherImplTest, FileUrlDoesNotExist) {
+ auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);
- { // Fetch a non-existent file.
- base::string16 text;
- TestCompletionCallback callback;
- int result =
- pac_fetcher.Fetch(GetTestFileUrl("does-not-exist"), &text,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
- EXPECT_THAT(result, IsError(ERR_IO_PENDING));
- EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_NOT_FOUND));
- EXPECT_TRUE(text.empty());
- }
- { // Fetch a file that exists.
- base::string16 text;
- TestCompletionCallback callback;
- int result =
- pac_fetcher.Fetch(GetTestFileUrl("pac.txt"), &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
- EXPECT_THAT(result, IsError(ERR_IO_PENDING));
- EXPECT_THAT(callback.WaitForResult(), IsOk());
- EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
- }
-}
+ base::string16 text;
+ TestCompletionCallback callback;
+ int result =
+ pac_fetcher->Fetch(GetTestFileUrl("does-not-exist"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ EXPECT_THAT(result, IsError(ERR_IO_PENDING));
+ EXPECT_TRUE(text.empty());
+
+#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
+ EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_NOT_FOUND));
+#else
+ EXPECT_THAT(callback.WaitForResult(), IsError(ERR_UNKNOWN_URL_SCHEME));
#endif // !BUILDFLAG(DISABLE_FILE_SUPPORT)
+}
+
+TEST_F(PacFileFetcherImplTest, FileUrlExists) {
+ auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);
+
+ base::string16 text;
+ TestCompletionCallback callback;
+ int result =
+ pac_fetcher->Fetch(GetTestFileUrl("pac.txt"), &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+
+ EXPECT_THAT(result, IsError(ERR_IO_PENDING));
+
+#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
+ EXPECT_THAT(callback.WaitForResult(), IsOk());
+ EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
+#else
+ EXPECT_THAT(callback.WaitForResult(), IsError(ERR_UNKNOWN_URL_SCHEME));
+#endif // !BUILDFLAG(DISABLE_FILE_SUPPORT)
+}
+
+TEST_F(PacFileFetcherImplTest, FileUrlNotAllowed) {
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
+
+ // Fetch a file that exists, however the PacFileFetcherImpl does not allow use
+ // of file://.
+ base::string16 text;
+ TestCompletionCallback callback;
+ int result =
+ pac_fetcher->Fetch(GetTestFileUrl("pac.txt"), &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_THAT(result, IsError(ERR_DISALLOWED_URL_SCHEME));
+}
+
+// Even if the fetcher allows file://, a server-side redirect from http -->
+// file:// should not work.
+//
+// It is currently disallowed lower in the stack and results in an
+// ERR_UNSAFE_REDIRECT.
+TEST_F(PacFileFetcherImplTest, RedirectToFileUrl) {
+ ASSERT_TRUE(test_server_.Start());
+
+ auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);
+
+ GURL url(test_server_.GetURL("/redirect-to-file"));
+
+ base::string16 text;
+ TestCompletionCallback callback;
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
+ EXPECT_THAT(result, IsError(ERR_IO_PENDING));
+ EXPECT_THAT(callback.WaitForResult(), IsError(ERR_UNSAFE_REDIRECT));
+}
// Note that all mime types are allowed for PAC file, to be consistent
// with other browsers.
TEST_F(PacFileFetcherImplTest, HttpMimeType) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
{ // Fetch a PAC with mime type "text/plain"
GURL url(test_server_.GetURL("/pac.txt"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.txt-\n"), text);
@@ -272,8 +319,8 @@
GURL url(test_server_.GetURL("/pac.html"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.html-\n"), text);
@@ -282,8 +329,8 @@
GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
@@ -293,14 +340,14 @@
TEST_F(PacFileFetcherImplTest, HttpStatusCode) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
{ // Fetch a PAC which gives a 500 -- FAIL
GURL url(test_server_.GetURL("/500.pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PAC_STATUS_NOT_OK));
EXPECT_TRUE(text.empty());
@@ -309,8 +356,8 @@
GURL url(test_server_.GetURL("/404.pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_PAC_STATUS_NOT_OK));
EXPECT_TRUE(text.empty());
@@ -320,15 +367,15 @@
TEST_F(PacFileFetcherImplTest, ContentDisposition) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
// Fetch PAC scripts via HTTP with a Content-Disposition header -- should
// have no effect.
GURL url(test_server_.GetURL("/downloadable.pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-downloadable.pac-\n"), text);
@@ -338,15 +385,15 @@
TEST_F(PacFileFetcherImplTest, NoCache) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
// Fetch a PAC script whose HTTP headers make it cacheable for 1 hour.
GURL url(test_server_.GetURL("/cacheable_1hr.pac"));
{
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-cacheable_1hr.pac-\n"), text);
@@ -361,8 +408,8 @@
{
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
// Expect any error. The exact error varies by platform.
@@ -373,10 +420,10 @@
TEST_F(PacFileFetcherImplTest, TooLarge) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::CreateWithFileUrlSupport(&context_);
// Set the maximum response size to 50 bytes.
- int prev_size = pac_fetcher.SetSizeConstraint(50);
+ int prev_size = pac_fetcher->SetSizeConstraint(50);
// These two URLs are the same file, but are http:// vs file://
GURL urls[] = {
@@ -392,22 +439,22 @@
const GURL& url = urls[i];
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_FILE_TOO_BIG));
EXPECT_TRUE(text.empty());
}
// Restore the original size bound.
- pac_fetcher.SetSizeConstraint(prev_size);
+ pac_fetcher->SetSizeConstraint(prev_size);
{ // Make sure we can still fetch regular URLs.
GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
@@ -418,13 +465,13 @@
TEST_F(PacFileFetcherImplTest, Empty) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
GURL url(test_server_.GetURL("/empty"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(0u, text.size());
@@ -433,11 +480,11 @@
TEST_F(PacFileFetcherImplTest, Hang) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
// Set the timeout period to 0.5 seconds.
base::TimeDelta prev_timeout =
- pac_fetcher.SetTimeoutConstraint(base::TimeDelta::FromMilliseconds(500));
+ pac_fetcher->SetTimeoutConstraint(base::TimeDelta::FromMilliseconds(500));
// Try fetching a URL which takes 1.2 seconds. We should abort the request
// after 500 ms, and fail with a timeout error.
@@ -445,22 +492,22 @@
GURL url(test_server_.GetURL("/slow/proxy.pac?1.2"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT));
EXPECT_TRUE(text.empty());
}
// Restore the original timeout period.
- pac_fetcher.SetTimeoutConstraint(prev_timeout);
+ pac_fetcher->SetTimeoutConstraint(prev_timeout);
{ // Make sure we can still fetch regular URLs.
GURL url(test_server_.GetURL("/pac.nsproxy"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("-pac.nsproxy-\n"), text);
@@ -473,15 +520,15 @@
TEST_F(PacFileFetcherImplTest, Encodings) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
// Test a response that is gzip-encoded -- should get inflated.
{
GURL url(test_server_.GetURL("/gzipped_pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("This data was gzipped.\n"), text);
@@ -493,8 +540,8 @@
GURL url(test_server_.GetURL("/utf16be_pac"));
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_EQ(ASCIIToUTF16("This was encoded as UTF-16BE.\n"), text);
@@ -502,7 +549,7 @@
}
TEST_F(PacFileFetcherImplTest, DataURLs) {
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
const char kEncodedUrl[] =
"data:application/x-ns-proxy-autoconfig;base64,ZnVuY3Rpb24gRmluZFByb3h5R"
@@ -520,8 +567,8 @@
GURL url(kEncodedUrl);
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsOk());
EXPECT_EQ(ASCIIToUTF16(kPacScript), text);
}
@@ -534,8 +581,8 @@
GURL url(kEncodedUrlBroken);
base::string16 text;
TestCompletionCallback callback;
- int result = pac_fetcher.Fetch(url, &text, callback.callback(),
- TRAFFIC_ANNOTATION_FOR_TESTS);
+ int result = pac_fetcher->Fetch(url, &text, callback.callback(),
+ TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_FAILED));
}
}
@@ -559,8 +606,7 @@
TestCompletionCallback callback;
base::string16 text;
for (int i = 0; i < num_requests; i++) {
- std::unique_ptr<PacFileFetcherImpl> pac_fetcher =
- std::make_unique<PacFileFetcherImpl>(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
GURL url(test_server_.GetURL("/hung"));
// Fine to use the same string and callback for all of these, as they should
// all hang.
@@ -582,16 +628,16 @@
TEST_F(PacFileFetcherImplTest, OnShutdown) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
base::string16 text;
TestCompletionCallback callback;
int result =
- pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ pac_fetcher->Fetch(test_server_.GetURL("/hung"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_IO_PENDING));
EXPECT_EQ(1u, context_.url_requests()->size());
- pac_fetcher.OnShutdown();
+ pac_fetcher->OnShutdown();
EXPECT_EQ(0u, context_.url_requests()->size());
EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONTEXT_SHUT_DOWN));
@@ -600,22 +646,23 @@
EXPECT_EQ(0u, context_.url_requests()->size());
EXPECT_FALSE(callback.have_result());
- result = pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ result =
+ pac_fetcher->Fetch(test_server_.GetURL("/hung"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
}
TEST_F(PacFileFetcherImplTest, OnShutdownWithNoLiveRequest) {
ASSERT_TRUE(test_server_.Start());
- PacFileFetcherImpl pac_fetcher(&context_);
- pac_fetcher.OnShutdown();
+ auto pac_fetcher = PacFileFetcherImpl::Create(&context_);
+ pac_fetcher->OnShutdown();
base::string16 text;
TestCompletionCallback callback;
int result =
- pac_fetcher.Fetch(test_server_.GetURL("/hung"), &text,
- callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
+ pac_fetcher->Fetch(test_server_.GetURL("/hung"), &text,
+ callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_THAT(result, IsError(ERR_CONTEXT_SHUT_DOWN));
EXPECT_EQ(0u, context_.url_requests()->size());
}
diff --git a/services/network/url_request_context_builder_mojo.cc b/services/network/url_request_context_builder_mojo.cc
index d1f27e39..122176e 100644
--- a/services/network/url_request_context_builder_mojo.cc
+++ b/services/network/url_request_context_builder_mojo.cc
@@ -56,8 +56,8 @@
if (mojo_proxy_resolver_factory_) {
std::unique_ptr<net::DhcpPacFileFetcher> dhcp_pac_file_fetcher =
dhcp_fetcher_factory_->Create(url_request_context);
- std::unique_ptr<net::PacFileFetcher> pac_file_fetcher =
- std::make_unique<net::PacFileFetcherImpl>(url_request_context);
+ auto pac_file_fetcher =
+ net::PacFileFetcherImpl::CreateWithFileUrlSupport(url_request_context);
return CreateProxyResolutionServiceUsingMojoFactory(
std::move(mojo_proxy_resolver_factory_),
std::move(proxy_config_service), std::move(pac_file_fetcher),