summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbengr <bengr@chromium.org>2014-11-06 17:36:50 -0800
committerCommit bot <commit-bot@chromium.org>2014-11-07 01:37:23 +0000
commit1bf8e9456a103d086f53400bdc169c437a1590a4 (patch)
treea0eca7b338d85490758a28cdb5bb10cd5cd407a3
parentf9567f85788355bf3da8df030cbc232421d00b7d (diff)
downloadchromium_src-1bf8e9456a103d086f53400bdc169c437a1590a4.zip
chromium_src-1bf8e9456a103d086f53400bdc169c437a1590a4.tar.gz
chromium_src-1bf8e9456a103d086f53400bdc169c437a1590a4.tar.bz2
Adds MaybeInterceptRedirect and MaybeInterceptResponse to the URLRequestInterceptor interface as well as to URLRequestJobFactory.
BUG=429505 Review URL: https://codereview.chromium.org/686343002 Cr-Commit-Position: refs/heads/master@{#303154}
-rw-r--r--android_webview/browser/net/aw_url_request_job_factory.cc14
-rw-r--r--android_webview/browser/net/aw_url_request_job_factory.h12
-rw-r--r--chrome/browser/chromeos/fileapi/external_file_url_request_job_unittest.cc13
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.cc16
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry.h10
-rw-r--r--chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc14
-rw-r--r--content/browser/appcache/appcache_request_handler_unittest.cc13
-rw-r--r--content/browser/appcache/appcache_url_request_job_unittest.cc13
-rw-r--r--content/browser/fileapi/file_system_dir_url_request_job_unittest.cc13
-rw-r--r--content/browser/fileapi/file_system_url_request_job_unittest.cc13
-rw-r--r--content/browser/fileapi/file_writer_delegate_unittest.cc13
-rw-r--r--content/browser/loader/resource_dispatcher_host_unittest.cc22
-rw-r--r--net/data/url_request_unittest/simple.html1
-rw-r--r--net/data/url_request_unittest/simple.html.mock-http-headers3
-rw-r--r--net/data/url_request_unittest/two-content-lengths.html1
-rw-r--r--net/data/url_request_unittest/two-content-lengths.html.mock-http-headers4
-rw-r--r--net/url_request/url_request_file_job_unittest.cc13
-rw-r--r--net/url_request/url_request_intercepting_job_factory.cc27
-rw-r--r--net/url_request/url_request_intercepting_job_factory.h10
-rw-r--r--net/url_request/url_request_interceptor.cc12
-rw-r--r--net/url_request/url_request_interceptor.h16
-rw-r--r--net/url_request/url_request_job_factory.h9
-rw-r--r--net/url_request/url_request_job_factory_impl.cc13
-rw-r--r--net/url_request/url_request_job_factory_impl.h10
-rw-r--r--net/url_request/url_request_job_manager.cc14
-rw-r--r--net/url_request/url_request_test_util.cc17
-rw-r--r--net/url_request/url_request_test_util.h9
-rw-r--r--net/url_request/url_request_unittest.cc802
28 files changed, 1079 insertions, 48 deletions
diff --git a/android_webview/browser/net/aw_url_request_job_factory.cc b/android_webview/browser/net/aw_url_request_job_factory.cc
index 2872d01..984458c 100644
--- a/android_webview/browser/net/aw_url_request_job_factory.cc
+++ b/android_webview/browser/net/aw_url_request_job_factory.cc
@@ -57,6 +57,20 @@ URLRequestJob* AwURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
request, network_delegate, net::ERR_UNKNOWN_URL_SCHEME);
}
+net::URLRequestJob* AwURLRequestJobFactory::MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const {
+ return next_factory_->MaybeInterceptRedirect(
+ request, network_delegate, location);
+}
+
+net::URLRequestJob* AwURLRequestJobFactory::MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const {
+ return next_factory_->MaybeInterceptResponse(request, network_delegate);
+}
+
bool AwURLRequestJobFactory::SetProtocolHandler(
const std::string& scheme,
ProtocolHandler* protocol_handler) {
diff --git a/android_webview/browser/net/aw_url_request_job_factory.h b/android_webview/browser/net/aw_url_request_job_factory.h
index 6cf507b..db1cfae 100644
--- a/android_webview/browser/net/aw_url_request_job_factory.h
+++ b/android_webview/browser/net/aw_url_request_job_factory.h
@@ -29,10 +29,20 @@ class AwURLRequestJobFactory : public net::URLRequestJobFactory {
ProtocolHandler* protocol_handler);
// net::URLRequestJobFactory implementation.
- virtual net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
+ net::URLRequestJob* MaybeCreateJobWithProtocolHandler(
const std::string& scheme,
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
+
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override;
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override;
+
virtual bool IsHandledProtocol(const std::string& scheme) const override;
virtual bool IsHandledURL(const GURL& url) const override;
virtual bool IsSafeRedirectTarget(const GURL& location) const override;
diff --git a/chrome/browser/chromeos/fileapi/external_file_url_request_job_unittest.cc b/chrome/browser/chromeos/fileapi/external_file_url_request_job_unittest.cc
index 34cf213..3c4fe88 100644
--- a/chrome/browser/chromeos/fileapi/external_file_url_request_job_unittest.cc
+++ b/chrome/browser/chromeos/fileapi/external_file_url_request_job_unittest.cc
@@ -63,6 +63,19 @@ class TestURLRequestJobFactory : public net::URLRequestJobFactory {
profile_id_, request, network_delegate);
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
virtual bool IsHandledProtocol(const std::string& scheme) const override {
return scheme == chrome::kExternalFileScheme;
}
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.cc b/chrome/browser/custom_handlers/protocol_handler_registry.cc
index 72f134d6..99bfd7c 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.cc
@@ -190,6 +190,22 @@ MaybeCreateJobWithProtocolHandler(
scheme, request, network_delegate);
}
+net::URLRequestJob*
+ProtocolHandlerRegistry::JobInterceptorFactory::MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const {
+ return job_factory_->MaybeInterceptRedirect(
+ request, network_delegate, location);
+}
+
+net::URLRequestJob*
+ProtocolHandlerRegistry::JobInterceptorFactory::MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const {
+ return job_factory_->MaybeInterceptResponse(request, network_delegate);
+}
+
bool ProtocolHandlerRegistry::JobInterceptorFactory::IsHandledProtocol(
const std::string& scheme) const {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry.h b/chrome/browser/custom_handlers/protocol_handler_registry.h
index 3426ab0..6c25ac1 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry.h
+++ b/chrome/browser/custom_handlers/protocol_handler_registry.h
@@ -116,6 +116,16 @@ class ProtocolHandlerRegistry : public KeyedService {
const std::string& scheme,
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
+
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override;
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override;
+
bool IsHandledProtocol(const std::string& scheme) const override;
bool IsHandledURL(const GURL& url) const override;
bool IsSafeRedirectTarget(const GURL& location) const override;
diff --git a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
index ab54350..7a1f09e 100644
--- a/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
+++ b/chrome/browser/custom_handlers/protocol_handler_registry_unittest.cc
@@ -69,6 +69,20 @@ class FakeURLRequestJobFactory : public net::URLRequestJobFactory {
net::NetworkDelegate* network_delegate) const override {
return NULL;
}
+
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return false;
}
diff --git a/content/browser/appcache/appcache_request_handler_unittest.cc b/content/browser/appcache/appcache_request_handler_unittest.cc
index 5d53a8b..9543f7e 100644
--- a/content/browser/appcache/appcache_request_handler_unittest.cc
+++ b/content/browser/appcache/appcache_request_handler_unittest.cc
@@ -134,6 +134,19 @@ class AppCacheRequestHandlerTest : public testing::Test {
}
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return scheme == "http";
};
diff --git a/content/browser/appcache/appcache_url_request_job_unittest.cc b/content/browser/appcache/appcache_url_request_job_unittest.cc
index 08b0fc1..8acc71c 100644
--- a/content/browser/appcache/appcache_url_request_job_unittest.cc
+++ b/content/browser/appcache/appcache_url_request_job_unittest.cc
@@ -72,6 +72,19 @@ class MockURLRequestJobFactory : public net::URLRequestJobFactory {
}
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return scheme == "http";
};
diff --git a/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc b/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc
index 6f7f423..e496954 100644
--- a/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc
+++ b/content/browser/fileapi/file_system_dir_url_request_job_unittest.cc
@@ -88,6 +88,19 @@ class FileSystemDirURLRequestJobFactory : public net::URLRequestJobFactory {
request, network_delegate, storage_domain_, file_system_context_);
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return true;
}
diff --git a/content/browser/fileapi/file_system_url_request_job_unittest.cc b/content/browser/fileapi/file_system_url_request_job_unittest.cc
index b6ec510..4dcba3b 100644
--- a/content/browser/fileapi/file_system_url_request_job_unittest.cc
+++ b/content/browser/fileapi/file_system_url_request_job_unittest.cc
@@ -97,6 +97,19 @@ class FileSystemURLRequestJobFactory : public net::URLRequestJobFactory {
request, network_delegate, storage_domain_, file_system_context_);
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return true;
}
diff --git a/content/browser/fileapi/file_writer_delegate_unittest.cc b/content/browser/fileapi/file_writer_delegate_unittest.cc
index f69d9d7..d907843 100644
--- a/content/browser/fileapi/file_writer_delegate_unittest.cc
+++ b/content/browser/fileapi/file_writer_delegate_unittest.cc
@@ -219,6 +219,19 @@ class BlobURLRequestJobFactory : public net::URLRequestJobFactory {
request, network_delegate, *content_data_);
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return scheme == "blob";
}
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index d600a27..d18facd 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -492,6 +492,15 @@ class TestURLRequestJobFactory : public net::URLRequestJobFactory {
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override;
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override;
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override;
+
bool IsHandledProtocol(const std::string& scheme) const override {
return supported_schemes_.count(scheme) > 0;
}
@@ -3000,4 +3009,17 @@ net::URLRequestJob* TestURLRequestJobFactory::MaybeCreateJobWithProtocolHandler(
}
}
+net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const {
+ return nullptr;
+}
+
+net::URLRequestJob* TestURLRequestJobFactory::MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const {
+ return nullptr;
+}
+
} // namespace content
diff --git a/net/data/url_request_unittest/simple.html b/net/data/url_request_unittest/simple.html
new file mode 100644
index 0000000..ce01362
--- /dev/null
+++ b/net/data/url_request_unittest/simple.html
@@ -0,0 +1 @@
+hello
diff --git a/net/data/url_request_unittest/simple.html.mock-http-headers b/net/data/url_request_unittest/simple.html.mock-http-headers
new file mode 100644
index 0000000..be8f7b5
--- /dev/null
+++ b/net/data/url_request_unittest/simple.html.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: text/html
+Content-Length: 5
diff --git a/net/data/url_request_unittest/two-content-lengths.html b/net/data/url_request_unittest/two-content-lengths.html
new file mode 100644
index 0000000..364322d
--- /dev/null
+++ b/net/data/url_request_unittest/two-content-lengths.html
@@ -0,0 +1 @@
+This file is boring; all the action's in the .mock-http-headers.
diff --git a/net/data/url_request_unittest/two-content-lengths.html.mock-http-headers b/net/data/url_request_unittest/two-content-lengths.html.mock-http-headers
new file mode 100644
index 0000000..707c0b0
--- /dev/null
+++ b/net/data/url_request_unittest/two-content-lengths.html.mock-http-headers
@@ -0,0 +1,4 @@
+HTTP/1.1 200 OK
+Content-Type: text/html
+Content-Length: 42
+Content-Length: 41
diff --git a/net/url_request/url_request_file_job_unittest.cc b/net/url_request/url_request_file_job_unittest.cc
index f4d7f7a..23ded74 100644
--- a/net/url_request/url_request_file_job_unittest.cc
+++ b/net/url_request/url_request_file_job_unittest.cc
@@ -82,6 +82,19 @@ class CallbacksJobFactory : public URLRequestJobFactory {
return job;
}
+ net::URLRequestJob* MaybeInterceptRedirect(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ return nullptr;
+ }
+
+ net::URLRequestJob* MaybeInterceptResponse(
+ net::URLRequest* request,
+ net::NetworkDelegate* network_delegate) const override {
+ return nullptr;
+ }
+
bool IsHandledProtocol(const std::string& scheme) const override {
return scheme == "file";
}
diff --git a/net/url_request/url_request_intercepting_job_factory.cc b/net/url_request/url_request_intercepting_job_factory.cc
index 43789e1..ea2d1f2 100644
--- a/net/url_request/url_request_intercepting_job_factory.cc
+++ b/net/url_request/url_request_intercepting_job_factory.cc
@@ -32,6 +32,33 @@ MaybeCreateJobWithProtocolHandler(
scheme, request, network_delegate);
}
+URLRequestJob* URLRequestInterceptingJobFactory::MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const {
+ DCHECK(CalledOnValidThread());
+ URLRequestJob* job = interceptor_->MaybeInterceptRedirect(request,
+ network_delegate,
+ location);
+ if (job)
+ return job;
+ return job_factory_->MaybeInterceptRedirect(request,
+ network_delegate,
+ location);
+}
+
+URLRequestJob* URLRequestInterceptingJobFactory::MaybeInterceptResponse(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const {
+ DCHECK(CalledOnValidThread());
+ URLRequestJob* job = interceptor_->MaybeInterceptResponse(request,
+ network_delegate);
+ if (job)
+ return job;
+ return job_factory_->MaybeInterceptResponse(request,
+ network_delegate);
+}
+
bool URLRequestInterceptingJobFactory::IsHandledProtocol(
const std::string& scheme) const {
return job_factory_->IsHandledProtocol(scheme);
diff --git a/net/url_request/url_request_intercepting_job_factory.h b/net/url_request/url_request_intercepting_job_factory.h
index 857dbf4..056b385 100644
--- a/net/url_request/url_request_intercepting_job_factory.h
+++ b/net/url_request/url_request_intercepting_job_factory.h
@@ -42,6 +42,16 @@ class NET_EXPORT URLRequestInterceptingJobFactory
const std::string& scheme,
URLRequest* request,
NetworkDelegate* network_delegate) const override;
+
+ URLRequestJob* MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const override;
+
+ URLRequestJob* MaybeInterceptResponse(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override;
+
bool IsHandledProtocol(const std::string& scheme) const override;
bool IsHandledURL(const GURL& url) const override;
bool IsSafeRedirectTarget(const GURL& location) const override;
diff --git a/net/url_request/url_request_interceptor.cc b/net/url_request/url_request_interceptor.cc
index bcd0fd5..b93611b 100644
--- a/net/url_request/url_request_interceptor.cc
+++ b/net/url_request/url_request_interceptor.cc
@@ -12,4 +12,16 @@ URLRequestInterceptor::URLRequestInterceptor() {
URLRequestInterceptor::~URLRequestInterceptor() {
}
+URLRequestJob* URLRequestInterceptor::MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const {
+ return nullptr;
+}
+
+URLRequestJob* URLRequestInterceptor::MaybeInterceptResponse(
+ URLRequest* request, NetworkDelegate* network_delegate) const {
+ return nullptr;
+}
+
} // namespace net
diff --git a/net/url_request/url_request_interceptor.h b/net/url_request/url_request_interceptor.h
index 682368d..f7d5275 100644
--- a/net/url_request/url_request_interceptor.h
+++ b/net/url_request/url_request_interceptor.h
@@ -8,6 +8,8 @@
#include "base/macros.h"
#include "net/base/net_export.h"
+class GURL;
+
namespace net {
class URLRequest;
@@ -28,6 +30,20 @@ class NET_EXPORT URLRequestInterceptor {
virtual URLRequestJob* MaybeInterceptRequest(
URLRequest* request, NetworkDelegate* network_delegate) const = 0;
+ // Returns a URLRequestJob to handle |request|, if the interceptor wants to
+ // take over the handling of the request after a redirect is received,
+ // instead of using the default ProtocolHandler. Otherwise, returns NULL.
+ virtual URLRequestJob* MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const;
+
+ // Returns a URLRequestJob to handle |request, if the interceptor wants to
+ // take over the handling of the request after a response has started,
+ // instead of using the default ProtocolHandler. Otherwise, returns NULL.
+ virtual URLRequestJob* MaybeInterceptResponse(
+ URLRequest* request, NetworkDelegate* network_delegate) const;
+
private:
DISALLOW_COPY_AND_ASSIGN(URLRequestInterceptor);
};
diff --git a/net/url_request/url_request_job_factory.h b/net/url_request/url_request_job_factory.h
index d4cc49e..96f218a 100644
--- a/net/url_request/url_request_job_factory.h
+++ b/net/url_request/url_request_job_factory.h
@@ -47,6 +47,15 @@ class NET_EXPORT URLRequestJobFactory
URLRequest* request,
NetworkDelegate* network_delegate) const = 0;
+ virtual URLRequestJob* MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const = 0;
+
+ virtual URLRequestJob* MaybeInterceptResponse(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const = 0;
+
virtual bool IsHandledProtocol(const std::string& scheme) const = 0;
virtual bool IsHandledURL(const GURL& url) const = 0;
diff --git a/net/url_request/url_request_job_factory_impl.cc b/net/url_request/url_request_job_factory_impl.cc
index 57e775b..264a7a1 100644
--- a/net/url_request/url_request_job_factory_impl.cc
+++ b/net/url_request/url_request_job_factory_impl.cc
@@ -63,6 +63,19 @@ URLRequestJob* URLRequestJobFactoryImpl::MaybeCreateJobWithProtocolHandler(
return it->second->MaybeCreateJob(request, network_delegate);
}
+URLRequestJob* URLRequestJobFactoryImpl::MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const {
+ return nullptr;
+}
+
+URLRequestJob* URLRequestJobFactoryImpl::MaybeInterceptResponse(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const {
+ return nullptr;
+}
+
bool URLRequestJobFactoryImpl::IsHandledProtocol(
const std::string& scheme) const {
DCHECK(CalledOnValidThread());
diff --git a/net/url_request/url_request_job_factory_impl.h b/net/url_request/url_request_job_factory_impl.h
index 695661e..8d1d8d9 100644
--- a/net/url_request/url_request_job_factory_impl.h
+++ b/net/url_request/url_request_job_factory_impl.h
@@ -33,6 +33,16 @@ class NET_EXPORT URLRequestJobFactoryImpl : public URLRequestJobFactory {
const std::string& scheme,
URLRequest* request,
NetworkDelegate* network_delegate) const override;
+
+ URLRequestJob* MaybeInterceptRedirect(
+ URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const override;
+
+ URLRequestJob* MaybeInterceptResponse(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override;
+
bool IsHandledProtocol(const std::string& scheme) const override;
bool IsHandledURL(const GURL& url) const override;
bool IsSafeRedirectTarget(const GURL& location) const override;
diff --git a/net/url_request/url_request_job_manager.cc b/net/url_request/url_request_job_manager.cc
index 0fe557b..6fcff22 100644
--- a/net/url_request/url_request_job_manager.cc
+++ b/net/url_request/url_request_job_manager.cc
@@ -128,6 +128,13 @@ URLRequestJob* URLRequestJobManager::MaybeInterceptRedirect(
if (job)
return job;
}
+
+ URLRequestJob* job =
+ request->context()->job_factory()->MaybeInterceptRedirect(
+ request, network_delegate, location);
+ if (job)
+ return job;
+
return NULL;
}
@@ -154,6 +161,13 @@ URLRequestJob* URLRequestJobManager::MaybeInterceptResponse(
if (job)
return job;
}
+
+ URLRequestJob* job =
+ request->context()->job_factory()->MaybeInterceptResponse(
+ request, network_delegate);
+ if (job)
+ return job;
+
return NULL;
}
diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc
index 82d8579..8f70ee7 100644
--- a/net/url_request/url_request_test_util.cc
+++ b/net/url_request/url_request_test_util.cc
@@ -317,11 +317,14 @@ TestNetworkDelegate::TestNetworkDelegate()
blocked_set_cookie_count_(0),
set_cookie_count_(0),
observed_before_proxy_headers_sent_callbacks_(0),
+ before_send_headers_count_(0),
+ headers_received_count_(0),
has_load_timing_info_before_redirect_(false),
has_load_timing_info_before_auth_(false),
can_access_files_(true),
can_throttle_requests_(true),
- cancel_request_with_policy_violating_referrer_(false) {
+ cancel_request_with_policy_violating_referrer_(false),
+ will_be_intercepted_on_next_error_(false) {
}
TestNetworkDelegate::~TestNetworkDelegate() {
@@ -386,7 +389,7 @@ int TestNetworkDelegate::OnBeforeSendHeaders(
next_states_[req_id] =
kStageSendHeaders |
kStageCompletedError; // request canceled by delegate
-
+ before_send_headers_count_++;
return OK;
}
@@ -406,9 +409,11 @@ void TestNetworkDelegate::OnSendHeaders(
event_order_[req_id] += "OnSendHeaders\n";
EXPECT_TRUE(next_states_[req_id] & kStageSendHeaders) <<
event_order_[req_id];
- next_states_[req_id] =
- kStageHeadersReceived |
- kStageCompletedError;
+ if (!will_be_intercepted_on_next_error_)
+ next_states_[req_id] = kStageHeadersReceived | kStageCompletedError;
+ else
+ next_states_[req_id] = kStageResponseStarted;
+ will_be_intercepted_on_next_error_ = false;
}
int TestNetworkDelegate::OnHeadersReceived(
@@ -445,7 +450,7 @@ int TestNetworkDelegate::OnHeadersReceived(
if (!allowed_unsafe_redirect_url_.is_empty())
*allowed_unsafe_redirect_url = allowed_unsafe_redirect_url_;
}
-
+ headers_received_count_++;
return OK;
}
diff --git a/net/url_request/url_request_test_util.h b/net/url_request/url_request_test_util.h
index 5784931..1289db7 100644
--- a/net/url_request/url_request_test_util.h
+++ b/net/url_request/url_request_test_util.h
@@ -275,12 +275,18 @@ class TestNetworkDelegate : public NetworkDelegate {
int observed_before_proxy_headers_sent_callbacks() const {
return observed_before_proxy_headers_sent_callbacks_;
}
+ int before_send_headers_count() const { return before_send_headers_count_; }
+ int headers_received_count() const { return headers_received_count_; }
// Last observed proxy in proxy header sent callback.
HostPortPair last_observed_proxy() {
return last_observed_proxy_;
}
+ void set_can_be_intercepted_on_error(bool can_be_intercepted_on_error) {
+ will_be_intercepted_on_next_error_ = can_be_intercepted_on_error;
+ }
+
protected:
// NetworkDelegate:
int OnBeforeURLRequest(URLRequest* request,
@@ -343,6 +349,8 @@ class TestNetworkDelegate : public NetworkDelegate {
int blocked_set_cookie_count_;
int set_cookie_count_;
int observed_before_proxy_headers_sent_callbacks_;
+ int before_send_headers_count_;
+ int headers_received_count_;
// Last observed proxy in before proxy header sent callback.
HostPortPair last_observed_proxy_;
@@ -365,6 +373,7 @@ class TestNetworkDelegate : public NetworkDelegate {
bool can_access_files_; // true by default
bool can_throttle_requests_; // true by default
bool cancel_request_with_policy_violating_referrer_; // false by default
+ bool will_be_intercepted_on_next_error_;
};
// Overrides the host used by the LocalHttpTestServer in
diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc
index 139b6f3..3bb7c15 100644
--- a/net/url_request/url_request_unittest.cc
+++ b/net/url_request/url_request_unittest.cc
@@ -72,6 +72,8 @@
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_http_job.h"
+#include "net/url_request/url_request_intercepting_job_factory.h"
+#include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_redirect_job.h"
#include "net/url_request/url_request_test_job.h"
@@ -607,31 +609,52 @@ class URLRequestTest : public PlatformTest {
URLRequestTest() : default_context_(true) {
default_context_.set_network_delegate(&default_network_delegate_);
default_context_.set_net_log(&net_log_);
- job_factory_.SetProtocolHandler("data", new DataProtocolHandler);
-#if !defined(DISABLE_FILE_SUPPORT)
- job_factory_.SetProtocolHandler(
- "file", new FileProtocolHandler(base::MessageLoopProxy::current()));
-#endif
- default_context_.set_job_factory(&job_factory_);
- default_context_.Init();
+ job_factory_impl_ = new URLRequestJobFactoryImpl();
+ job_factory_.reset(job_factory_impl_);
}
+
~URLRequestTest() override {
// URLRequestJobs may post clean-up tasks on destruction.
base::RunLoop().RunUntilIdle();
}
+ virtual void SetUp() {
+ SetUpFactory();
+ default_context_.set_job_factory(job_factory_.get());
+ default_context_.Init();
+ PlatformTest::SetUp();
+ }
+
+ virtual void SetUpFactory() {
+ job_factory_impl_->SetProtocolHandler("data", new DataProtocolHandler);
+#if !defined(DISABLE_FILE_SUPPORT)
+ job_factory_impl_->SetProtocolHandler(
+ "file", new FileProtocolHandler(base::MessageLoopProxy::current()));
+#endif
+ }
+
+ TestNetworkDelegate* default_network_delegate() {
+ return &default_network_delegate_;
+ }
+
+ const TestURLRequestContext& default_context() const {
+ return default_context_;
+ }
+
+
// Adds the TestJobInterceptor to the default context.
TestJobInterceptor* AddTestInterceptor() {
TestJobInterceptor* protocol_handler_ = new TestJobInterceptor();
- job_factory_.SetProtocolHandler("http", NULL);
- job_factory_.SetProtocolHandler("http", protocol_handler_);
+ job_factory_impl_->SetProtocolHandler("http", NULL);
+ job_factory_impl_->SetProtocolHandler("http", protocol_handler_);
return protocol_handler_;
}
protected:
CapturingNetLog net_log_;
TestNetworkDelegate default_network_delegate_; // Must outlive URLRequest.
- URLRequestJobFactoryImpl job_factory_;
+ URLRequestJobFactoryImpl* job_factory_impl_;
+ scoped_ptr<URLRequestJobFactory> job_factory_;
TestURLRequestContext default_context_;
};
@@ -1574,29 +1597,570 @@ TEST_F(URLRequestTest, InterceptRespectsCancelInRestart) {
EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
}
-LoadTimingInfo RunLoadTimingTest(const LoadTimingInfo& job_load_timing,
- URLRequestContext* context) {
- TestInterceptor interceptor;
- interceptor.intercept_main_request_ = true;
- interceptor.main_request_load_timing_info_ = job_load_timing;
+// An Interceptor for use with interceptor tests.
+class MockURLRequestInterceptor : public URLRequestInterceptor {
+ public:
+ // Static getters for canned response header and data strings.
+ static std::string ok_data() {
+ return URLRequestTestJob::test_data_1();
+ }
+
+ static std::string ok_headers() {
+ return URLRequestTestJob::test_headers();
+ }
+
+ static std::string redirect_data() {
+ return std::string();
+ }
+
+ static std::string redirect_headers() {
+ return URLRequestTestJob::test_redirect_headers();
+ }
+
+ static std::string error_data() {
+ return std::string("ohhh nooooo mr. bill!");
+ }
+
+ static std::string error_headers() {
+ return URLRequestTestJob::test_error_headers();
+ }
+
+ MockURLRequestInterceptor()
+ : intercept_main_request_(false), restart_main_request_(false),
+ cancel_main_request_(false), cancel_then_restart_main_request_(false),
+ simulate_main_network_error_(false),
+ intercept_redirect_(false), cancel_redirect_request_(false),
+ intercept_final_response_(false), cancel_final_request_(false),
+ use_url_request_http_job_(false),
+ did_intercept_main_(false), did_restart_main_(false),
+ did_cancel_main_(false), did_cancel_then_restart_main_(false),
+ did_simulate_error_main_(false),
+ did_intercept_redirect_(false), did_cancel_redirect_(false),
+ did_intercept_final_(false), did_cancel_final_(false) {
+ }
+
+ ~MockURLRequestInterceptor() override {
+ }
+
+ // URLRequestInterceptor implementation:
+ URLRequestJob* MaybeInterceptRequest(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override {
+ if (restart_main_request_) {
+ restart_main_request_ = false;
+ did_restart_main_ = true;
+ return new RestartTestJob(request, network_delegate);
+ }
+ if (cancel_main_request_) {
+ cancel_main_request_ = false;
+ did_cancel_main_ = true;
+ return new CancelTestJob(request, network_delegate);
+ }
+ if (cancel_then_restart_main_request_) {
+ cancel_then_restart_main_request_ = false;
+ did_cancel_then_restart_main_ = true;
+ return new CancelThenRestartTestJob(request, network_delegate);
+ }
+ if (simulate_main_network_error_) {
+ simulate_main_network_error_ = false;
+ did_simulate_error_main_ = true;
+ if (use_url_request_http_job_) {
+ return URLRequestHttpJob::Factory(request, network_delegate, "http");
+ }
+ // This job will result in error since the requested URL is not one of the
+ // URLs supported by these tests.
+ return new URLRequestTestJob(request, network_delegate, true);
+ }
+ if (!intercept_main_request_)
+ return nullptr;
+ intercept_main_request_ = false;
+ did_intercept_main_ = true;
+ URLRequestTestJob* job = new URLRequestTestJob(request,
+ network_delegate,
+ main_headers_,
+ main_data_,
+ true);
+ job->set_load_timing_info(main_request_load_timing_info_);
+ return job;
+ }
+
+ URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
+ NetworkDelegate* network_delegate,
+ const GURL& location) const override {
+ if (cancel_redirect_request_) {
+ cancel_redirect_request_ = false;
+ did_cancel_redirect_ = true;
+ return new CancelTestJob(request, network_delegate);
+ }
+ if (!intercept_redirect_)
+ return nullptr;
+ intercept_redirect_ = false;
+ did_intercept_redirect_ = true;
+ if (use_url_request_http_job_) {
+ return URLRequestHttpJob::Factory(request, network_delegate, "http");
+ }
+ return new URLRequestTestJob(request,
+ network_delegate,
+ redirect_headers_,
+ redirect_data_,
+ true);
+ }
+
+ URLRequestJob* MaybeInterceptResponse(
+ URLRequest* request,
+ NetworkDelegate* network_delegate) const override {
+ if (cancel_final_request_) {
+ cancel_final_request_ = false;
+ did_cancel_final_ = true;
+ return new CancelTestJob(request, network_delegate);
+ }
+ if (!intercept_final_response_)
+ return nullptr;
+ intercept_final_response_ = false;
+ did_intercept_final_ = true;
+ if (use_url_request_http_job_) {
+ return URLRequestHttpJob::Factory(request, network_delegate, "http");
+ }
+ return new URLRequestTestJob(request,
+ network_delegate,
+ final_headers_,
+ final_data_,
+ true);
+ }
+
+ void set_intercept_main_request(bool intercept_main_request) {
+ intercept_main_request_ = intercept_main_request;
+ }
+
+ void set_main_headers(const std::string& main_headers) {
+ main_headers_ = main_headers;
+ }
+
+ void set_main_data(const std::string& main_data) {
+ main_data_ = main_data;
+ }
+
+ void set_main_request_load_timing_info(
+ const LoadTimingInfo& main_request_load_timing_info) {
+ main_request_load_timing_info_ = main_request_load_timing_info;
+ }
+
+ void set_restart_main_request(bool restart_main_request) {
+ restart_main_request_ = restart_main_request;
+ }
+
+ void set_cancel_main_request(bool cancel_main_request) {
+ cancel_main_request_ = cancel_main_request;
+ }
+
+ void set_cancel_then_restart_main_request(
+ bool cancel_then_restart_main_request) {
+ cancel_then_restart_main_request_ = cancel_then_restart_main_request;
+ }
+
+ void set_simulate_main_network_error(bool simulate_main_network_error) {
+ simulate_main_network_error_ = simulate_main_network_error;
+ }
+
+ void set_intercept_redirect(bool intercept_redirect) {
+ intercept_redirect_ = intercept_redirect;
+ }
+
+ void set_redirect_headers(const std::string& redirect_headers) {
+ redirect_headers_ = redirect_headers;
+ }
+
+ void set_redirect_data(const std::string& redirect_data) {
+ redirect_data_ = redirect_data;
+ }
+
+ void set_cancel_redirect_request(bool cancel_redirect_request) {
+ cancel_redirect_request_ = cancel_redirect_request;
+ }
+
+ void set_intercept_final_response(bool intercept_final_response) {
+ intercept_final_response_ = intercept_final_response;
+ }
+
+ void set_final_headers(const std::string& final_headers) {
+ final_headers_ = final_headers;
+ }
+
+ void set_final_data(const std::string& final_data) {
+ final_data_ = final_data;
+ }
+
+ void set_cancel_final_request(bool cancel_final_request) {
+ cancel_final_request_ = cancel_final_request;
+ }
+
+ void set_use_url_request_http_job(bool use_url_request_http_job) {
+ use_url_request_http_job_ = use_url_request_http_job;
+ }
+
+ bool did_intercept_main() const {
+ return did_intercept_main_;
+ }
+
+ bool did_restart_main() const {
+ return did_restart_main_;
+ }
+
+ bool did_cancel_main() const {
+ return did_cancel_main_;
+ }
+
+ bool did_cancel_then_restart_main() const {
+ return did_cancel_then_restart_main_;
+ }
+
+ bool did_simulate_error_main() const {
+ return did_simulate_error_main_;
+ }
+
+ bool did_intercept_redirect() const {
+ return did_intercept_redirect_;
+ }
+
+ bool did_cancel_redirect() const {
+ return did_cancel_redirect_;
+ }
+
+ bool did_intercept_final() const {
+ return did_intercept_final_;
+ }
+
+ bool did_cancel_final() const {
+ return did_cancel_final_;
+ }
+
+ private:
+ // Indicate whether to intercept the main request, and if so specify the
+ // response to return and the LoadTimingInfo to use.
+ mutable bool intercept_main_request_;
+ mutable std::string main_headers_;
+ mutable std::string main_data_;
+ mutable LoadTimingInfo main_request_load_timing_info_;
+
+ // These indicate actions that can be taken within MaybeInterceptRequest.
+ mutable bool restart_main_request_;
+ mutable bool cancel_main_request_;
+ mutable bool cancel_then_restart_main_request_;
+ mutable bool simulate_main_network_error_;
+
+ // Indicate whether to intercept redirects, and if so specify the response to
+ // return.
+ mutable bool intercept_redirect_;
+ mutable std::string redirect_headers_;
+ mutable std::string redirect_data_;
+
+ // Cancel the request within MaybeInterceptRedirect.
+ mutable bool cancel_redirect_request_;
+
+ // Indicate whether to intercept the final response, and if so specify the
+ // response to return.
+ mutable bool intercept_final_response_;
+ mutable std::string final_headers_;
+ mutable std::string final_data_;
+
+ // Cancel the final request within MaybeInterceptResponse.
+ mutable bool cancel_final_request_;
+
+ // Instruct the interceptor to use a real URLRequestHTTPJob.
+ mutable bool use_url_request_http_job_;
+
+ // These indicate if the interceptor did something or not.
+ mutable bool did_intercept_main_;
+ mutable bool did_restart_main_;
+ mutable bool did_cancel_main_;
+ mutable bool did_cancel_then_restart_main_;
+ mutable bool did_simulate_error_main_;
+ mutable bool did_intercept_redirect_;
+ mutable bool did_cancel_redirect_;
+ mutable bool did_intercept_final_;
+ mutable bool did_cancel_final_;
+};
+
+// Inherit PlatformTest since we require the autorelease pool on Mac OS X.
+class URLRequestInterceptorTest : public URLRequestTest {
+ public:
+ URLRequestInterceptorTest() : URLRequestTest(), interceptor_(NULL) {
+ }
+
+ ~URLRequestInterceptorTest() override {
+ // URLRequestJobs may post clean-up tasks on destruction.
+ base::RunLoop().RunUntilIdle();
+ }
+
+ void SetUpFactory() override {
+ interceptor_ = new MockURLRequestInterceptor();
+ job_factory_.reset(new URLRequestInterceptingJobFactory(
+ job_factory_.Pass(), make_scoped_ptr(interceptor_)));
+ }
+
+ MockURLRequestInterceptor* interceptor() const {
+ return interceptor_;
+ }
+
+ private:
+ MockURLRequestInterceptor* interceptor_;
+};
+
+TEST_F(URLRequestInterceptorTest, Intercept) {
+ // Intercept the main request and respond with a simple response.
+ interceptor()->set_intercept_main_request(true);
+ interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_main_data(MockURLRequestInterceptor::ok_data());
TestDelegate d;
- scoped_ptr<URLRequest> req(context->CreateRequest(
- GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, NULL));
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ base::SupportsUserData::Data* user_data0 = new base::SupportsUserData::Data();
+ base::SupportsUserData::Data* user_data1 = new base::SupportsUserData::Data();
+ base::SupportsUserData::Data* user_data2 = new base::SupportsUserData::Data();
+ req->SetUserData(nullptr, user_data0);
+ req->SetUserData(&user_data1, user_data1);
+ req->SetUserData(&user_data2, user_data2);
+ req->set_method("GET");
req->Start();
base::RunLoop().Run();
- LoadTimingInfo resulting_load_timing;
- req->GetLoadTimingInfo(&resulting_load_timing);
+ // Make sure we can retrieve our specific user data.
+ EXPECT_EQ(user_data0, req->GetUserData(nullptr));
+ EXPECT_EQ(user_data1, req->GetUserData(&user_data1));
+ EXPECT_EQ(user_data2, req->GetUserData(&user_data2));
- // None of these should be modified by the URLRequest.
- EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused);
- EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id);
- EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start);
- EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end);
- EXPECT_EQ(job_load_timing.receive_headers_end,
- resulting_load_timing.receive_headers_end);
+ // Check that we got one good response.
+ EXPECT_TRUE(req->status().is_success());
+ EXPECT_EQ(200, req->response_headers()->response_code());
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+}
- return resulting_load_timing;
+TEST_F(URLRequestInterceptorTest, InterceptRedirect) {
+ // Intercept the main request and respond with a redirect.
+ interceptor()->set_intercept_main_request(true);
+ interceptor()->set_main_headers(
+ MockURLRequestInterceptor::redirect_headers());
+ interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data());
+
+ // Intercept that redirect and respond with a final OK response.
+ interceptor()->set_intercept_redirect(true);
+ interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_intercept_main());
+ EXPECT_TRUE(interceptor()->did_intercept_redirect());
+
+ // Check that we got one good response.
+ EXPECT_TRUE(req->status().is_success());
+ if (req->status().is_success())
+ EXPECT_EQ(200, req->response_headers()->response_code());
+
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptServerError) {
+ // Intercept the main request to generate a server error response.
+ interceptor()->set_intercept_main_request(true);
+ interceptor()->set_main_headers(MockURLRequestInterceptor::error_headers());
+ interceptor()->set_main_data(MockURLRequestInterceptor::error_data());
+
+ // Intercept that error and respond with an OK response.
+ interceptor()->set_intercept_final_response(true);
+ interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_intercept_main());
+ EXPECT_TRUE(interceptor()->did_intercept_final());
+
+ // Check that we got one good response.
+ EXPECT_TRUE(req->status().is_success());
+ EXPECT_EQ(200, req->response_headers()->response_code());
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptNetworkError) {
+ // Intercept the main request to simulate a network error.
+ interceptor()->set_simulate_main_network_error(true);
+
+ // Intercept that error and respond with an OK response.
+ interceptor()->set_intercept_final_response(true);
+ interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_simulate_error_main());
+ EXPECT_TRUE(interceptor()->did_intercept_final());
+
+ // Check that we received one good response.
+ EXPECT_TRUE(req->status().is_success());
+ EXPECT_EQ(200, req->response_headers()->response_code());
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptRestartRequired) {
+ // Restart the main request.
+ interceptor()->set_restart_main_request(true);
+
+ // then intercept the new main request and respond with an OK response
+ interceptor()->set_intercept_main_request(true);
+ interceptor()->set_main_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_main_data(MockURLRequestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_restart_main());
+ EXPECT_TRUE(interceptor()->did_intercept_main());
+
+ // Check that we received one good response.
+ EXPECT_TRUE(req->status().is_success());
+ if (req->status().is_success())
+ EXPECT_EQ(200, req->response_headers()->response_code());
+
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelMain) {
+ // Intercept the main request and cancel from within the restarted job.
+ interceptor()->set_cancel_main_request(true);
+
+ // Set up to intercept the final response and override it with an OK response.
+ interceptor()->set_intercept_final_response(true);
+ interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_cancel_main());
+ EXPECT_FALSE(interceptor()->did_intercept_final());
+
+ // Check that we see a canceled request.
+ EXPECT_FALSE(req->status().is_success());
+ EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelRedirect) {
+ // Intercept the main request and respond with a redirect.
+ interceptor()->set_intercept_main_request(true);
+ interceptor()->set_main_headers(
+ MockURLRequestInterceptor::redirect_headers());
+ interceptor()->set_main_data(MockURLRequestInterceptor::redirect_data());
+
+ // Intercept the redirect and cancel from within that job.
+ interceptor()->set_cancel_redirect_request(true);
+
+ // Set up to intercept the final response and override it with an OK response.
+ interceptor()->set_intercept_final_response(true);
+ interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_intercept_main());
+ EXPECT_TRUE(interceptor()->did_cancel_redirect());
+ EXPECT_FALSE(interceptor()->did_intercept_final());
+
+ // Check that we see a canceled request.
+ EXPECT_FALSE(req->status().is_success());
+ EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelFinal) {
+ // Intercept the main request to simulate a network error.
+ interceptor()->set_simulate_main_network_error(true);
+
+ // Set up to intercept final the response and cancel from within that job.
+ interceptor()->set_cancel_final_request(true);
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_simulate_error_main());
+ EXPECT_TRUE(interceptor()->did_cancel_final());
+
+ // Check that we see a canceled request.
+ EXPECT_FALSE(req->status().is_success());
+ EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
+}
+
+TEST_F(URLRequestInterceptorTest, InterceptRespectsCancelInRestart) {
+ // Intercept the main request and cancel then restart from within that job.
+ interceptor()->set_cancel_then_restart_main_request(true);
+
+ // Set up to intercept the final response and override it with an OK response.
+ interceptor()->set_intercept_final_response(true);
+ interceptor()->set_final_headers(TestInterceptor::ok_headers());
+ interceptor()->set_final_data(TestInterceptor::ok_data());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ // Check that the interceptor got called as expected.
+ EXPECT_TRUE(interceptor()->did_cancel_then_restart_main());
+ EXPECT_FALSE(interceptor()->did_intercept_final());
+
+ // Check that we see a canceled request.
+ EXPECT_FALSE(req->status().is_success());
+ EXPECT_EQ(URLRequestStatus::CANCELED, req->status().status());
}
// "Normal" LoadTimingInfo as returned by a job. Everything is in order, not
@@ -1649,14 +2213,41 @@ LoadTimingInfo NormalLoadTimingInfoReused(base::TimeTicks now,
return load_timing;
}
+LoadTimingInfo RunURLRequestInterceptorLoadTimingTest(
+ const LoadTimingInfo& job_load_timing,
+ const URLRequestContext& context,
+ MockURLRequestInterceptor* interceptor) {
+ interceptor->set_intercept_main_request(true);
+ interceptor->set_main_request_load_timing_info(job_load_timing);
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(context.CreateRequest(
+ GURL("http://test_intercept/foo"), DEFAULT_PRIORITY, &d, nullptr));
+ req->Start();
+ base::RunLoop().Run();
+
+ LoadTimingInfo resulting_load_timing;
+ req->GetLoadTimingInfo(&resulting_load_timing);
+
+ // None of these should be modified by the URLRequest.
+ EXPECT_EQ(job_load_timing.socket_reused, resulting_load_timing.socket_reused);
+ EXPECT_EQ(job_load_timing.socket_log_id, resulting_load_timing.socket_log_id);
+ EXPECT_EQ(job_load_timing.send_start, resulting_load_timing.send_start);
+ EXPECT_EQ(job_load_timing.send_end, resulting_load_timing.send_end);
+ EXPECT_EQ(job_load_timing.receive_headers_end,
+ resulting_load_timing.receive_headers_end);
+
+ return resulting_load_timing;
+}
+
// Basic test that the intercept + load timing tests work.
-TEST_F(URLRequestTest, InterceptLoadTiming) {
+TEST_F(URLRequestInterceptorTest, InterceptLoadTiming) {
base::TimeTicks now = base::TimeTicks::Now();
LoadTimingInfo job_load_timing =
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, false);
LoadTimingInfo load_timing_result =
- RunLoadTimingTest(job_load_timing, &default_context_);
+ RunURLRequestInterceptorLoadTimingTest(
+ job_load_timing, default_context(), interceptor());
// Nothing should have been changed by the URLRequest.
EXPECT_EQ(job_load_timing.proxy_resolve_start,
@@ -1681,13 +2272,14 @@ TEST_F(URLRequestTest, InterceptLoadTiming) {
}
// Another basic test, with proxy and SSL times, but no DNS times.
-TEST_F(URLRequestTest, InterceptLoadTimingProxy) {
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingProxy) {
base::TimeTicks now = base::TimeTicks::Now();
LoadTimingInfo job_load_timing =
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, true);
LoadTimingInfo load_timing_result =
- RunLoadTimingTest(job_load_timing, &default_context_);
+ RunURLRequestInterceptorLoadTimingTest(
+ job_load_timing, default_context(), interceptor());
// Nothing should have been changed by the URLRequest.
EXPECT_EQ(job_load_timing.proxy_resolve_start,
@@ -1718,7 +2310,7 @@ TEST_F(URLRequestTest, InterceptLoadTimingProxy) {
// reused in this test (May be a preconnect).
//
// To mix things up from the test above, assumes DNS times but no SSL times.
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) {
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyProxyResolution) {
base::TimeTicks now = base::TimeTicks::Now();
LoadTimingInfo job_load_timing =
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_DNS_TIMES, true);
@@ -1732,7 +2324,8 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) {
now - base::TimeDelta::FromDays(1);
LoadTimingInfo load_timing_result =
- RunLoadTimingTest(job_load_timing, &default_context_);
+ RunURLRequestInterceptorLoadTimingTest(
+ job_load_timing, default_context(), interceptor());
// Proxy times, connect times, and DNS times should all be replaced with
// request_start.
@@ -1755,14 +2348,16 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolution) {
}
// Same as above, but in the reused case.
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolutionReused) {
+TEST_F(URLRequestInterceptorTest,
+ InterceptLoadTimingEarlyProxyResolutionReused) {
base::TimeTicks now = base::TimeTicks::Now();
LoadTimingInfo job_load_timing = NormalLoadTimingInfoReused(now, true);
job_load_timing.proxy_resolve_start = now - base::TimeDelta::FromDays(4);
job_load_timing.proxy_resolve_end = now - base::TimeDelta::FromDays(3);
LoadTimingInfo load_timing_result =
- RunLoadTimingTest(job_load_timing, &default_context_);
+ RunURLRequestInterceptorLoadTimingTest(
+ job_load_timing, default_context(), interceptor());
// Proxy times and connect times should all be replaced with request_start.
EXPECT_EQ(load_timing_result.request_start,
@@ -1779,7 +2374,7 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyProxyResolutionReused) {
// not considered reused in this test (May be a preconnect).
//
// To mix things up, the request has SSL times, but no DNS times.
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) {
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnect) {
base::TimeTicks now = base::TimeTicks::Now();
LoadTimingInfo job_load_timing =
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_SSL_TIMES, false);
@@ -1791,7 +2386,8 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) {
now - base::TimeDelta::FromDays(4);
LoadTimingInfo load_timing_result =
- RunLoadTimingTest(job_load_timing, &default_context_);
+ RunURLRequestInterceptorLoadTimingTest(
+ job_load_timing, default_context(), interceptor());
// Connect times, and SSL times should be replaced with request_start.
EXPECT_EQ(load_timing_result.request_start,
@@ -1813,7 +2409,7 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnect) {
// test (May be a preconnect).
//
// In this test, there are no SSL or DNS times.
-TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnectWithProxy) {
+TEST_F(URLRequestInterceptorTest, InterceptLoadTimingEarlyConnectWithProxy) {
base::TimeTicks now = base::TimeTicks::Now();
LoadTimingInfo job_load_timing =
NormalLoadTimingInfo(now, CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY, true);
@@ -1823,7 +2419,8 @@ TEST_F(URLRequestTest, InterceptLoadTimingEarlyConnectWithProxy) {
now - base::TimeDelta::FromDays(2);
LoadTimingInfo load_timing_result =
- RunLoadTimingTest(job_load_timing, &default_context_);
+ RunURLRequestInterceptorLoadTimingTest(
+ job_load_timing, default_context(), interceptor());
// Connect times should be replaced with proxy_resolve_end.
EXPECT_EQ(load_timing_result.proxy_resolve_end,
@@ -2665,6 +3262,11 @@ class URLRequestTestHTTP : public URLRequestTest {
return is_success;
}
+ LocalHttpTestServer* test_server() {
+ return &test_server_;
+ }
+
+ protected:
LocalHttpTestServer test_server_;
};
@@ -5166,7 +5768,7 @@ TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictDataRedirects) {
EXPECT_FALSE(data_protocol_handler.IsSafeRedirectTarget(data_url));
// Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
- EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(data_url));
+ EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(data_url));
}
#if !defined(DISABLE_FILE_SUPPORT)
@@ -5177,7 +5779,7 @@ TEST_F(URLRequestTestHTTP, ProtocolHandlerAndFactoryRestrictFileRedirects) {
EXPECT_FALSE(file_protocol_handler.IsSafeRedirectTarget(file_url));
// Test URLRequestJobFactoryImpl::IsSafeRedirectTarget().
- EXPECT_FALSE(job_factory_.IsSafeRedirectTarget(file_url));
+ EXPECT_FALSE(job_factory_->IsSafeRedirectTarget(file_url));
}
TEST_F(URLRequestTestHTTP, RestrictFileRedirects) {
@@ -6446,6 +7048,124 @@ TEST_F(URLRequestTestHTTP, NetworkSuspendTestNoCache) {
EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, req->status().error());
}
+class URLRequestInterceptorTestHTTP : public URLRequestTestHTTP {
+ public:
+ // TODO(bengr): Merge this with the URLRequestInterceptorHTTPTest fixture,
+ // ideally remove the dependency on URLRequestTestJob, and maybe move these
+ // tests into the factory tests.
+ URLRequestInterceptorTestHTTP() : URLRequestTestHTTP(), interceptor_(NULL) {
+ }
+
+ void SetUpFactory() override {
+ interceptor_ = new MockURLRequestInterceptor();
+ job_factory_.reset(new URLRequestInterceptingJobFactory(
+ job_factory_.Pass(), make_scoped_ptr(interceptor_)));
+ }
+
+ MockURLRequestInterceptor* interceptor() const {
+ return interceptor_;
+ }
+
+ private:
+ MockURLRequestInterceptor* interceptor_;
+};
+
+TEST_F(URLRequestInterceptorTestHTTP,
+ NetworkDelegateNotificationOnRedirectIntercept) {
+ interceptor()->set_intercept_redirect(true);
+ interceptor()->set_redirect_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_redirect_data(MockURLRequestInterceptor::ok_data());
+
+ ASSERT_TRUE(test_server()->Start());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ test_server()->GetURL("files/redirect-test.html"), DEFAULT_PRIORITY,
+ &d, nullptr));
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_TRUE(interceptor()->did_intercept_redirect());
+ // Check we got one good response
+ EXPECT_TRUE(req->status().is_success());
+ if (req->status().is_success())
+ EXPECT_EQ(200, req->response_headers()->response_code());
+
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+
+ EXPECT_EQ(1, default_network_delegate()->created_requests());
+ EXPECT_EQ(1, default_network_delegate()->before_send_headers_count());
+ EXPECT_EQ(1, default_network_delegate()->headers_received_count());
+}
+
+TEST_F(URLRequestInterceptorTestHTTP,
+ NetworkDelegateNotificationOnErrorIntercept) {
+ // Intercept that error and respond with an OK response.
+ interceptor()->set_intercept_final_response(true);
+ interceptor()->set_final_headers(MockURLRequestInterceptor::ok_headers());
+ interceptor()->set_final_data(MockURLRequestInterceptor::ok_data());
+ default_network_delegate()->set_can_be_intercepted_on_error(true);
+
+ ASSERT_TRUE(test_server()->Start());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ test_server()->GetURL("files/two-content-lengths.html"), DEFAULT_PRIORITY,
+ &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_TRUE(interceptor()->did_intercept_final());
+
+ // Check we received one good response.
+ EXPECT_TRUE(req->status().is_success());
+ if (req->status().is_success())
+ EXPECT_EQ(200, req->response_headers()->response_code());
+ EXPECT_EQ(MockURLRequestInterceptor::ok_data(), d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+
+ EXPECT_EQ(1, default_network_delegate()->created_requests());
+ EXPECT_EQ(1, default_network_delegate()->before_send_headers_count());
+ EXPECT_EQ(0, default_network_delegate()->headers_received_count());
+}
+
+TEST_F(URLRequestInterceptorTestHTTP,
+ NetworkDelegateNotificationOnResponseIntercept) {
+ // Intercept that error and respond with an OK response.
+ interceptor()->set_intercept_final_response(true);
+
+ // Intercept with a real URLRequestHttpJob.
+ interceptor()->set_use_url_request_http_job(true);
+
+ ASSERT_TRUE(test_server()->Start());
+
+ TestDelegate d;
+ scoped_ptr<URLRequest> req(default_context().CreateRequest(
+ test_server()->GetURL("files/simple.html"), DEFAULT_PRIORITY,
+ &d, nullptr));
+ req->set_method("GET");
+ req->Start();
+ base::RunLoop().Run();
+
+ EXPECT_TRUE(interceptor()->did_intercept_final());
+
+ // Check we received one good response.
+ EXPECT_TRUE(req->status().is_success());
+ if (req->status().is_success())
+ EXPECT_EQ(200, req->response_headers()->response_code());
+ EXPECT_EQ("hello", d.data_received());
+ EXPECT_EQ(1, d.response_started_count());
+ EXPECT_EQ(0, d.received_redirect_count());
+
+ EXPECT_EQ(1, default_network_delegate()->created_requests());
+ EXPECT_EQ(2, default_network_delegate()->before_send_headers_count());
+ EXPECT_EQ(2, default_network_delegate()->headers_received_count());
+}
+
class HTTPSRequestTest : public testing::Test {
public:
HTTPSRequestTest() : default_context_(true) {