Index: content/browser/loader/intercepting_resource_handler_unittest.cc |
diff --git a/content/browser/loader/mime_type_resource_handler_unittest.cc b/content/browser/loader/intercepting_resource_handler_unittest.cc |
similarity index 55% |
rename from content/browser/loader/mime_type_resource_handler_unittest.cc |
rename to content/browser/loader/intercepting_resource_handler_unittest.cc |
index 6bed3a84943e687afdae7da24ee34929042361b8..7c1086a99dbd7f2b1e337a91de13a1a61239b143 100644 |
--- a/content/browser/loader/mime_type_resource_handler_unittest.cc |
+++ b/content/browser/loader/intercepting_resource_handler_unittest.cc |
@@ -1,8 +1,8 @@ |
-// Copyright 2014 The Chromium Authors. All rights reserved. |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "content/browser/loader/mime_type_resource_handler.h" |
+#include "content/browser/loader/intercepting_resource_handler.h" |
#include <stdint.h> |
@@ -48,9 +48,7 @@ class TestResourceHandler : public ResourceHandler { |
return false; |
} |
- bool OnWillStart(const GURL& url, bool* defer) override { |
- return false; |
- } |
+ bool OnWillStart(const GURL& url, bool* defer) override { return false; } |
bool OnBeforeNetworkStart(const GURL& url, bool* defer) override { |
NOTREACHED(); |
@@ -71,23 +69,74 @@ class TestResourceHandler : public ResourceHandler { |
void OnResponseCompleted(const net::URLRequestStatus& status, |
const std::string& security_info, |
+ bool* defer) override {} |
+ |
+ void OnDataDownloaded(int bytes_downloaded) override { NOTREACHED(); } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(TestResourceHandler); |
+}; |
+ |
+class TestResourceHandlerWithBuffer : public ResourceHandler { |
+ public: |
+ TestResourceHandlerWithBuffer() |
+ : ResourceHandler(nullptr), buffer_(new net::IOBuffer(2048)) {} |
+ ~TestResourceHandlerWithBuffer() override {} |
+ |
+ void SetController(ResourceController* controller) override {} |
+ |
+ bool OnRequestRedirected(const net::RedirectInfo& redirect_info, |
+ ResourceResponse* response, |
bool* defer) override { |
+ NOTREACHED(); |
+ return false; |
+ } |
+ |
+ bool OnResponseStarted(ResourceResponse* response, bool* defer) override { |
+ return true; |
} |
- void OnDataDownloaded(int bytes_downloaded) override { |
+ bool OnWillStart(const GURL& url, bool* defer) override { return false; } |
+ |
+ bool OnBeforeNetworkStart(const GURL& url, bool* defer) override { |
NOTREACHED(); |
+ return false; |
+ } |
+ |
+ bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, |
+ int* buf_size, |
+ int min_size) override { |
+ *buf = buffer_; |
+ *buf_size = 2048; |
+ return true; |
+ } |
+ |
+ bool OnReadCompleted(int bytes_read, bool* defer) override { |
+ DCHECK_LT(bytes_read, 2048); |
+ return true; |
} |
+ void OnResponseCompleted(const net::URLRequestStatus& status, |
+ const std::string& security_info, |
+ bool* defer) override {} |
+ |
+ void OnDataDownloaded(int bytes_downloaded) override { NOTREACHED(); } |
+ |
+ scoped_refptr<net::IOBuffer> buffer() { return buffer_; } |
+ |
private: |
- DISALLOW_COPY_AND_ASSIGN(TestResourceHandler); |
+ scoped_refptr<net::IOBuffer> buffer_; |
+ DISALLOW_COPY_AND_ASSIGN(TestResourceHandlerWithBuffer); |
}; |
class TestResourceDispatcherHost : public ResourceDispatcherHostImpl { |
public: |
- explicit TestResourceDispatcherHost(bool stream_has_handler) |
+ TestResourceDispatcherHost(bool stream_has_handler, bool use_buffer) |
: stream_has_handler_(stream_has_handler), |
intercepted_as_stream_(false), |
- intercepted_as_stream_count_(0) {} |
+ intercepted_as_stream_count_(0), |
+ last_resource_handler_(nullptr), |
+ use_buffer_(use_buffer) {} |
bool intercepted_as_stream() const { return intercepted_as_stream_; } |
@@ -95,7 +144,7 @@ class TestResourceDispatcherHost : public ResourceDispatcherHostImpl { |
net::URLRequest* request, |
bool is_content_initiated, |
bool must_download) override { |
- return std::unique_ptr<ResourceHandler>(new TestResourceHandler); |
+ return CreateNewResourceHandler(); |
} |
std::unique_ptr<ResourceHandler> MaybeInterceptAsStream( |
@@ -106,9 +155,9 @@ class TestResourceDispatcherHost : public ResourceDispatcherHostImpl { |
intercepted_as_stream_count_++; |
if (stream_has_handler_) { |
intercepted_as_stream_ = true; |
- return std::unique_ptr<ResourceHandler>(new TestResourceHandler); |
+ return CreateNewResourceHandler(); |
} else { |
- return std::unique_ptr<ResourceHandler>(); |
+ return CreateNewResourceHandler(); |
} |
} |
@@ -116,7 +165,23 @@ class TestResourceDispatcherHost : public ResourceDispatcherHostImpl { |
return intercepted_as_stream_count_; |
} |
+ TestResourceHandlerWithBuffer* last_resource_handler() const { |
+ return last_resource_handler_; |
+ } |
+ |
private: |
+ std::unique_ptr<ResourceHandler> CreateNewResourceHandler() { |
+ std::unique_ptr<ResourceHandler> new_resource_handler; |
+ if (use_buffer_) { |
+ new_resource_handler.reset(new TestResourceHandlerWithBuffer()); |
+ last_resource_handler_ = static_cast<TestResourceHandlerWithBuffer*>( |
+ new_resource_handler.get()); |
+ } else { |
+ new_resource_handler.reset(new TestResourceHandler()); |
+ } |
+ return new_resource_handler; |
+ } |
+ |
// Whether the URL request should be intercepted as a stream. |
bool stream_has_handler_; |
@@ -126,14 +191,21 @@ class TestResourceDispatcherHost : public ResourceDispatcherHostImpl { |
// Count of number of times MaybeInterceptAsStream function get called in a |
// test. |
int intercepted_as_stream_count_; |
+ |
+ // The last TestResourceHandlerWithBuffer created by this |
+ // TestResourceDispatcherHost. |
+ TestResourceHandlerWithBuffer* last_resource_handler_; |
+ |
+ // Whether to create TestResourceHandlerWithBuffer instead of |
+ // TestResourceHandlers. |
+ bool use_buffer_; |
}; |
class TestResourceDispatcherHostDelegate |
: public ResourceDispatcherHostDelegate { |
public: |
TestResourceDispatcherHostDelegate(bool must_download) |
- : must_download_(must_download) { |
- } |
+ : must_download_(must_download) {} |
bool ShouldForceDownloadResource(const GURL& url, |
const std::string& mime_type) override { |
@@ -148,17 +220,11 @@ class TestResourceController : public ResourceController { |
public: |
void Cancel() override {} |
- void CancelAndIgnore() override { |
- NOTREACHED(); |
- } |
+ void CancelAndIgnore() override { NOTREACHED(); } |
- void CancelWithError(int error_code) override { |
- NOTREACHED(); |
- } |
+ void CancelWithError(int error_code) override { NOTREACHED(); } |
- void Resume() override { |
- NOTREACHED(); |
- } |
+ void Resume() override { NOTREACHED(); } |
}; |
class TestFakePluginService : public FakePluginService { |
@@ -202,9 +268,9 @@ class TestFakePluginService : public FakePluginService { |
DISALLOW_COPY_AND_ASSIGN(TestFakePluginService); |
}; |
-class MimeTypeResourceHandlerTest : public testing::Test { |
+class InterceptingResourceHandlerTest : public testing::Test { |
public: |
- MimeTypeResourceHandlerTest() |
+ InterceptingResourceHandlerTest() |
: stream_has_handler_(false), |
plugin_available_(false), |
plugin_stale_(false) {} |
@@ -223,11 +289,6 @@ class MimeTypeResourceHandlerTest : public testing::Test { |
bool must_download, |
ResourceType request_resource_type); |
- std::string TestAcceptHeaderSetting(ResourceType request_resource_type); |
- std::string TestAcceptHeaderSettingWithURLRequest( |
- ResourceType request_resource_type, |
- net::URLRequest* request); |
- |
private: |
// Whether the URL request should be intercepted as a stream. |
bool stream_has_handler_; |
@@ -237,7 +298,7 @@ class MimeTypeResourceHandlerTest : public testing::Test { |
TestBrowserThreadBundle thread_bundle_; |
}; |
-bool MimeTypeResourceHandlerTest::TestStreamIsIntercepted( |
+bool InterceptingResourceHandlerTest::TestStreamIsIntercepted( |
bool allow_download, |
bool must_download, |
ResourceType request_resource_type) { |
@@ -245,130 +306,46 @@ bool MimeTypeResourceHandlerTest::TestStreamIsIntercepted( |
std::unique_ptr<net::URLRequest> request(context.CreateRequest( |
GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); |
bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME; |
- ResourceRequestInfo::AllocateForTesting( |
- request.get(), |
- request_resource_type, |
- nullptr, // context |
- 0, // render_process_id |
- 0, // render_view_id |
- 0, // render_frame_id |
- is_main_frame, // is_main_frame |
- false, // parent_is_main_frame |
- allow_download, // allow_download |
- true, // is_async |
- false); // is_using_lofi |
- |
- TestResourceDispatcherHost host(stream_has_handler_); |
+ ResourceRequestInfo::AllocateForTesting(request.get(), request_resource_type, |
+ nullptr, // context |
+ 0, // render_process_id |
+ 0, // render_view_id |
+ 0, // render_frame_id |
+ is_main_frame, // is_main_frame |
+ false, // parent_is_main_frame |
+ allow_download, // allow_download |
+ true, // is_async |
+ false); // is_using_lofi |
+ |
+ TestResourceDispatcherHost host(stream_has_handler_, false); |
TestResourceDispatcherHostDelegate host_delegate(must_download); |
host.SetDelegate(&host_delegate); |
TestFakePluginService plugin_service(plugin_available_, plugin_stale_); |
- std::unique_ptr<ResourceHandler> mime_sniffing_handler( |
- new MimeTypeResourceHandler( |
+ std::unique_ptr<ResourceHandler> intercepting_handler( |
+ new InterceptingResourceHandler( |
std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host, |
&plugin_service, request.get())); |
+ |
TestResourceController resource_controller; |
- mime_sniffing_handler->SetController(&resource_controller); |
+ intercepting_handler->SetController(&resource_controller); |
scoped_refptr<ResourceResponse> response(new ResourceResponse); |
// The MIME type isn't important but it shouldn't be empty. |
response->head.mime_type = "application/pdf"; |
bool defer = false; |
- mime_sniffing_handler->OnResponseStarted(response.get(), &defer); |
+ intercepting_handler->OnResponseStarted(response.get(), &defer); |
content::RunAllPendingInMessageLoop(); |
EXPECT_LT(host.intercepted_as_stream_count(), 2); |
return host.intercepted_as_stream(); |
} |
-std::string MimeTypeResourceHandlerTest::TestAcceptHeaderSetting( |
- ResourceType request_resource_type) { |
- net::URLRequestContext context; |
- std::unique_ptr<net::URLRequest> request(context.CreateRequest( |
- GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); |
- return TestAcceptHeaderSettingWithURLRequest( |
- request_resource_type, request.get()); |
-} |
- |
-std::string MimeTypeResourceHandlerTest::TestAcceptHeaderSettingWithURLRequest( |
- ResourceType request_resource_type, |
- net::URLRequest* request) { |
- bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME; |
- ResourceRequestInfo::AllocateForTesting( |
- request, |
- request_resource_type, |
- nullptr, // context |
- 0, // render_process_id |
- 0, // render_view_id |
- 0, // render_frame_id |
- is_main_frame, // is_main_frame |
- false, // parent_is_main_frame |
- false, // allow_download |
- true, // is_async |
- false); // is_using_lofi |
- |
- TestResourceDispatcherHost host(stream_has_handler_); |
- TestResourceDispatcherHostDelegate host_delegate(false); |
- host.SetDelegate(&host_delegate); |
- |
- std::unique_ptr<ResourceHandler> mime_sniffing_handler( |
- new MimeTypeResourceHandler( |
- std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host, |
- nullptr, request)); |
- |
- bool defer = false; |
- mime_sniffing_handler->OnWillStart(request->url(), &defer); |
- content::RunAllPendingInMessageLoop(); |
- |
- std::string accept_header; |
- request->extra_request_headers().GetHeader("Accept", &accept_header); |
- return accept_header; |
-} |
- |
-// Test that the proper Accept: header is set based on the ResourceType |
-TEST_F(MimeTypeResourceHandlerTest, AcceptHeaders) { |
- EXPECT_EQ( |
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp," |
- "*/*;q=0.8", |
- TestAcceptHeaderSetting(RESOURCE_TYPE_MAIN_FRAME)); |
- EXPECT_EQ( |
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp," |
- "*/*;q=0.8", |
- TestAcceptHeaderSetting(RESOURCE_TYPE_SUB_FRAME)); |
- EXPECT_EQ("text/css,*/*;q=0.1", |
- TestAcceptHeaderSetting(RESOURCE_TYPE_STYLESHEET)); |
- EXPECT_EQ("*/*", |
- TestAcceptHeaderSetting(RESOURCE_TYPE_SCRIPT)); |
- EXPECT_EQ("image/webp,image/*,*/*;q=0.8", |
- TestAcceptHeaderSetting(RESOURCE_TYPE_IMAGE)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_FONT_RESOURCE)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SUB_RESOURCE)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_OBJECT)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_MEDIA)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_WORKER)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SHARED_WORKER)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PREFETCH)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_FAVICON)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_XHR)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PING)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SERVICE_WORKER)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_CSP_REPORT)); |
- EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PLUGIN_RESOURCE)); |
- |
- // Ensure that if an Accept header is already set, it is not overwritten. |
- net::URLRequestContext context; |
- std::unique_ptr<net::URLRequest> request(context.CreateRequest( |
- GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); |
- request->SetExtraRequestHeaderByName("Accept", "*", true); |
- EXPECT_EQ("*", |
- TestAcceptHeaderSettingWithURLRequest(RESOURCE_TYPE_XHR, request.get())); |
-} |
- |
// Test that stream requests are correctly intercepted under the right |
// circumstances. Test is not relevent when plugins are disabled. |
#if defined(ENABLE_PLUGINS) |
-TEST_F(MimeTypeResourceHandlerTest, StreamHandling) { |
+TEST_F(InterceptingResourceHandlerTest, StreamHandling) { |
bool allow_download; |
bool must_download; |
ResourceType resource_type; |
@@ -432,12 +409,6 @@ TEST_F(MimeTypeResourceHandlerTest, StreamHandling) { |
EXPECT_FALSE( |
TestStreamIsIntercepted(allow_download, must_download, resource_type)); |
- allow_download = true; |
- must_download = false; |
- resource_type = RESOURCE_TYPE_MAIN_FRAME; |
- EXPECT_FALSE( |
- TestStreamIsIntercepted(allow_download, must_download, resource_type)); |
- |
// Test the cases where the stream handled by MaybeInterceptAsStream |
// with plugin not available. This is the case when intercepting streams for |
// the streamsPrivate extensions API. |
@@ -461,6 +432,116 @@ TEST_F(MimeTypeResourceHandlerTest, StreamHandling) { |
} |
#endif |
+// Tests that the data received is transmitted to the newly created |
+// ResourceHandler. |
+TEST_F(InterceptingResourceHandlerTest, ResponseBodyHandling) { |
+ net::URLRequestContext context; |
+ std::unique_ptr<net::URLRequest> request(context.CreateRequest( |
+ GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); |
+ ResourceRequestInfo::AllocateForTesting(request.get(), |
+ RESOURCE_TYPE_MAIN_FRAME, |
+ nullptr, // context |
+ 0, // render_process_id |
+ 0, // render_view_id |
+ 0, // render_frame_id |
+ true, // is_main_frame |
+ false, // parent_is_main_frame |
+ true, // allow_download |
+ true, // is_async |
+ false); // is_using_lofi |
+ |
+ TestResourceDispatcherHost host(false, true); |
+ TestResourceDispatcherHostDelegate host_delegate(false); |
+ host.SetDelegate(&host_delegate); |
+ |
+ std::unique_ptr<ResourceHandler> old_handler( |
+ new TestResourceHandlerWithBuffer()); |
+ scoped_refptr<net::IOBuffer> old_buffer = |
+ static_cast<TestResourceHandlerWithBuffer*>(old_handler.get())->buffer(); |
+ TestFakePluginService plugin_service(false, false); |
+ std::unique_ptr<ResourceHandler> intercepting_handler( |
+ new InterceptingResourceHandler(std::move(old_handler), &host, |
+ &plugin_service, request.get())); |
+ |
+ TestResourceController resource_controller; |
+ intercepting_handler->SetController(&resource_controller); |
+ |
+ scoped_refptr<ResourceResponse> response(new ResourceResponse); |
+ // The MIME type isn't important but it shouldn't be empty. |
+ response->head.mime_type = "application/pdf"; |
+ |
+ // Simulate the MimeSniffingResourceHandler buffering the data. |
+ scoped_refptr<net::IOBuffer> read_buffer; |
+ int buf_size = 0; |
+ intercepting_handler->OnWillRead(&read_buffer, &buf_size, -1); |
+ |
+ char data[] = "The data"; |
+ CHECK_EQ(read_buffer.get(), old_buffer.get()); |
+ memcpy(read_buffer->data(), data, sizeof(data)); |
+ |
+ // The response is received. A new ResourceHandler should be created to |
+ // handle the download. |
+ bool defer = false; |
+ intercepting_handler->OnResponseStarted(response.get(), &defer); |
+ EXPECT_FALSE(defer); |
+ TestResourceHandlerWithBuffer* new_handler = host.last_resource_handler(); |
+ CHECK(new_handler); |
+ |
+ // It should not have received the download data yet. |
+ EXPECT_FALSE(!memcmp(data, new_handler->buffer()->data(), sizeof(data))); |
+ |
+ // The read is replayed by the MimeSniffingResourceHandler. The data should |
+ // have been received by the new handler. |
+ intercepting_handler->OnReadCompleted(sizeof(data), &defer); |
+ EXPECT_FALSE(defer); |
+ EXPECT_TRUE(!memcmp(data, new_handler->buffer()->data(), sizeof(data))); |
+} |
+ |
+// Tests that 304s do not trigger a change in handlers. |
+TEST_F(InterceptingResourceHandlerTest, 304Handling) { |
+ net::URLRequestContext context; |
+ std::unique_ptr<net::URLRequest> request(context.CreateRequest( |
+ GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); |
+ ResourceRequestInfo::AllocateForTesting(request.get(), |
+ RESOURCE_TYPE_MAIN_FRAME, |
+ nullptr, // context |
+ 0, // render_process_id |
+ 0, // render_view_id |
+ 0, // render_frame_id |
+ true, // is_main_frame |
+ false, // parent_is_main_frame |
+ true, // allow_download |
+ true, // is_async |
+ false); // is_using_lofi |
+ |
+ TestResourceDispatcherHost host(false, true); |
+ TestResourceDispatcherHostDelegate host_delegate(false); |
+ host.SetDelegate(&host_delegate); |
+ |
+ TestFakePluginService plugin_service(false, false); |
+ std::unique_ptr<ResourceHandler> intercepting_handler( |
+ new InterceptingResourceHandler( |
+ std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host, |
+ &plugin_service, request.get())); |
+ |
+ TestResourceController resource_controller; |
+ intercepting_handler->SetController(&resource_controller); |
+ |
+ // Simulate a 304 response. |
+ scoped_refptr<ResourceResponse> response(new ResourceResponse); |
+ // The MIME type isn't important but it shouldn't be empty. |
+ response->head.mime_type = "application/pdf"; |
+ response->head.headers = new net::HttpResponseHeaders("HTTP/1.x 304 OK"); |
+ |
+ // The response is received. No new ResourceHandler should be created to |
+ // handle the download. |
+ bool defer = false; |
+ intercepting_handler->OnResponseStarted(response.get(), &defer); |
+ EXPECT_FALSE(defer); |
+ TestResourceHandlerWithBuffer* new_handler = host.last_resource_handler(); |
+ EXPECT_TRUE(!new_handler); |
+} |
+ |
} // namespace |
} // namespace content |