Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Unified Diff: content/browser/loader/mime_sniffing_resource_handler_unittest.cc

Issue 2743723003: Add buffering to MimeSniffingResourceHandler.
Patch Set: Remove unused 'first_call' variable. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/loader/mime_sniffing_resource_handler_unittest.cc
diff --git a/content/browser/loader/mime_sniffing_resource_handler_unittest.cc b/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
index 4045a55c1a734d61c12a35e9de9f968142fe8515..5b2260feda01581bf6b8d0ff32ac799fe5e0885a 100644
--- a/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
+++ b/content/browser/loader/mime_sniffing_resource_handler_unittest.cc
@@ -6,6 +6,7 @@
#include <stdint.h>
+#include <algorithm>
#include <memory>
#include "base/files/file_path.h"
@@ -191,7 +192,9 @@ class MimeSniffingResourceHandlerTest : public testing::Test {
bool will_read,
bool defer_will_read,
bool read_completed,
- bool defer_read_completed);
+ bool defer_read_completed,
+ int read_chunk_size,
+ int downstream_handler_buffer_size);
// Tests the operation of the MimeSniffingHandler when it doesn't buffer
// data (example case: the response is text/html).
@@ -200,7 +203,9 @@ class MimeSniffingResourceHandlerTest : public testing::Test {
bool will_read,
bool defer_will_read,
bool read_completed,
- bool defer_read_completed);
+ bool defer_read_completed,
+ int read_chunk_size,
+ int downstream_handler_buffer_size);
private:
// Whether the URL request should be intercepted as a stream.
@@ -316,7 +321,9 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
bool will_read,
bool defer_will_read,
bool read_completed,
- bool defer_read_completed) {
+ bool defer_read_completed,
+ int read_chunk_size,
+ int downstream_handler_buffer_size) {
net::URLRequestContext context;
std::unique_ptr<net::URLRequest> request(context.CreateRequest(
GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
@@ -349,6 +356,7 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
scoped_test_handler->set_defer_on_will_read(defer_will_read);
scoped_test_handler->set_on_read_completed_result(read_completed);
scoped_test_handler->set_defer_on_read_completed(defer_read_completed);
+ scoped_test_handler->SetBufferSize(downstream_handler_buffer_size);
TestResourceHandler* test_handler = scoped_test_handler.get();
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
@@ -369,18 +377,38 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
ASSERT_EQ(MockResourceLoader::Status::IDLE,
mock_loader.OnResponseStarted(std::move(response)));
- // Read some data to sniff the mime type. This will ask the next
- // ResourceHandler for a buffer.
- mock_loader.OnWillRead();
+ // Read some data to sniff the mime type.
+ // Simulate an HTML page. The mime sniffer will identify the MimeType and
+ // proceed with replay.
+ const char kData[] = "!DOCTYPE html\n<head>\n<title>Foo</title>\n</head>";
+ size_t string_pos = 0u;
+ do {
+ mock_loader.OnWillRead();
- if (!will_read) {
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
+
+ size_t amount_to_write = std::min(sizeof(kData) - string_pos,
+ static_cast<size_t>(read_chunk_size));
+
+ // Construct StringPiece manually, as the terminal null needs to be
+ // included, so it's sniffed as binary (Not important that it's sniffed
+ // as binary, but this gaurantees it's sniffed as something, without
+ // waiting for more data).
+ mock_loader.OnReadCompleted(
+ base::StringPiece(kData + string_pos, amount_to_write));
+ string_pos += amount_to_write;
+ } while (string_pos != sizeof(kData));
+
+ // If the next handler cancels the response start, the caller of
+ // MimeSniffingHandler::OnReadCompleted should be notified immediately.
+ if (!response_started) {
EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status());
EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
EXPECT_EQ(1, test_handler->on_will_start_called());
EXPECT_EQ(0, test_handler->on_request_redirected_called());
- EXPECT_EQ(0, test_handler->on_response_started_called());
- EXPECT_EQ(1, test_handler->on_will_read_called());
+ EXPECT_EQ(1, test_handler->on_response_started_called());
+ EXPECT_EQ(0, test_handler->on_will_read_called());
EXPECT_EQ(0, test_handler->on_read_completed_called());
// Process all messages to ensure proper test teardown.
@@ -388,29 +416,19 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
return;
}
- if (defer_will_read) {
+ if (defer_response_started) {
ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
mock_loader.status());
- EXPECT_EQ(MimeSniffingResourceHandler::STATE_WAITING_FOR_BUFFER,
+ EXPECT_EQ(MimeSniffingResourceHandler::STATE_REPLAYING_RESPONSE_RECEIVED,
mime_sniffing_handler.state_);
test_handler->Resume();
// MimeSniffingResourceHandler may not synchronously resume the request.
base::RunLoop().RunUntilIdle();
}
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
-
- // Simulate an HTML page. The mime sniffer will identify the MimeType and
- // proceed with replay.
- const char kData[] = "!DOCTYPE html\n<head>\n<title>Foo</title>\n</head>";
- // Construct StringPiece manually, as the terminal null needs to be included,
- // so it's sniffed as binary (Not important that it's sniffed as binary, but
- // this gaurantees it's sniffed as something, without waiting for more data).
- mock_loader.OnReadCompleted(base::StringPiece(kData, sizeof(kData)));
-
- // If the next handler cancels the response start, the caller of
- // MimeSniffingHandler::OnReadCompleted should be notified immediately.
- if (!response_started) {
+ // This is the point at which the replay will happen, which will allocate
+ // a buffer and give the downstream handler a chance to cancel.
+ if (!will_read) {
EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status());
EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
@@ -425,10 +443,10 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
return;
}
- if (defer_response_started) {
+ if (defer_will_read) {
ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
mock_loader.status());
- EXPECT_EQ(MimeSniffingResourceHandler::STATE_REPLAYING_RESPONSE_RECEIVED,
+ EXPECT_EQ(MimeSniffingResourceHandler::STATE_REPLAYING_WAIT_FOR_WILL_READ,
mime_sniffing_handler.state_);
test_handler->Resume();
// MimeSniffingResourceHandler may not synchronously resume the request.
@@ -446,16 +464,25 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
return;
}
- EXPECT_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
- mime_sniffing_handler.state_);
-
// The request may be deferred by the next handler once the read is done.
if (defer_read_completed) {
+ // The replay isn't considered complete until the downstream handler
+ // finishes the read completed....
+ EXPECT_EQ(MimeSniffingResourceHandler::STATE_REPLAYING_RESPONSE_RECEIVED,
+ mime_sniffing_handler.state_);
ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
mock_loader.status());
test_handler->Resume();
- // MimeSniffingResourceHandler may not synchronously resume the request.
+
+ // (MimeSniffingResourceHandler may not synchronously resume the request.)
base::RunLoop().RunUntilIdle();
+
+ // ... which should be now.
+ EXPECT_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
+ mime_sniffing_handler.state_);
+ } else {
+ EXPECT_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
+ mime_sniffing_handler.state_);
}
EXPECT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
@@ -465,8 +492,10 @@ void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
EXPECT_EQ(1, test_handler->on_will_start_called());
EXPECT_EQ(0, test_handler->on_request_redirected_called());
EXPECT_EQ(1, test_handler->on_response_started_called());
- EXPECT_EQ(1, test_handler->on_will_read_called());
- EXPECT_EQ(1, test_handler->on_read_completed_called());
+ EXPECT_LE(1, test_handler->on_will_read_called());
+ EXPECT_LE(1, test_handler->on_read_completed_called());
+ // Include trailing null in expected value.
+ EXPECT_EQ(std::string(kData, strlen(kData) + 1), test_handler->body());
// Process all messages to ensure proper test teardown.
content::RunAllPendingInMessageLoop();
@@ -478,7 +507,9 @@ void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
bool will_read,
bool defer_will_read,
bool read_completed,
- bool defer_read_completed) {
+ bool defer_read_completed,
+ int read_chunk_size,
+ int downstream_handler_buffer_size) {
net::URLRequestContext context;
std::unique_ptr<net::URLRequest> request(context.CreateRequest(
GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
@@ -511,6 +542,7 @@ void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
scoped_test_handler->set_defer_on_will_read(defer_will_read);
scoped_test_handler->set_on_read_completed_result(read_completed);
scoped_test_handler->set_defer_on_read_completed(defer_read_completed);
+ scoped_test_handler->SetBufferSize(downstream_handler_buffer_size);
TestResourceHandler* test_handler = scoped_test_handler.get();
MimeSniffingResourceHandler mime_sniffing_handler(
std::move(scoped_test_handler), &host, &plugin_service,
@@ -555,55 +587,75 @@ void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
base::RunLoop().RunUntilIdle();
}
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
-
- // The MimeSniffingResourceHandler should be acting as a pass-through
- // ResourceHandler.
- mock_loader.OnWillRead();
-
- if (!will_read) {
- EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status());
- EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
+ const std::string input(std::string(2000, 'a'));
+ const char* to_read = input.c_str();
+ int read_cycles = 1;
+ do {
+ // The MimeSniffingResourceHandler should be acting as a pass-through
+ // ResourceHandler.
+ mock_loader.OnWillRead();
+
+ // Only relevant the first time through the loop.
+ if (!will_read) {
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status());
+ EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
+
+ EXPECT_EQ(1, test_handler->on_will_start_called());
+ EXPECT_EQ(0, test_handler->on_request_redirected_called());
+ EXPECT_EQ(1, test_handler->on_response_started_called());
+ EXPECT_EQ(1, test_handler->on_will_read_called());
+ EXPECT_EQ(0, test_handler->on_read_completed_called());
+
+ // Process all messages to ensure proper test teardown.
+ content::RunAllPendingInMessageLoop();
+ return;
+ }
+
+ if (defer_will_read) {
+ defer_will_read = false; // Only a single will read is deferred.
+ ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
+ mock_loader.status());
+ EXPECT_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
+ mime_sniffing_handler.state_);
+ test_handler->Resume();
+ // MimeSniffingResourceHandler may not synchronously resume the request.
+ base::RunLoop().RunUntilIdle();
+ }
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
+
+ ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
+ int amount_to_read =
+ std::min(static_cast<int>(strlen(to_read)),
+ std::min(mock_loader.io_buffer_size(), read_chunk_size));
+
+ mock_loader.OnReadCompleted(std::string(to_read, amount_to_read));
+ to_read += amount_to_read;
EXPECT_EQ(1, test_handler->on_will_start_called());
EXPECT_EQ(0, test_handler->on_request_redirected_called());
EXPECT_EQ(1, test_handler->on_response_started_called());
- EXPECT_EQ(1, test_handler->on_will_read_called());
- EXPECT_EQ(0, test_handler->on_read_completed_called());
+ EXPECT_EQ(read_cycles, test_handler->on_will_read_called());
+ EXPECT_EQ(read_cycles, test_handler->on_read_completed_called());
- // Process all messages to ensure proper test teardown.
- content::RunAllPendingInMessageLoop();
- return;
- }
+ // Only relevant first time through.
+ if (!read_completed) {
+ EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status());
+ EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
- if (defer_will_read) {
- ASSERT_EQ(MockResourceLoader::Status::CALLBACK_PENDING,
- mock_loader.status());
- EXPECT_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
- mime_sniffing_handler.state_);
- test_handler->Resume();
- // MimeSniffingResourceHandler may not synchronously resume the request.
- base::RunLoop().RunUntilIdle();
- }
+ // Process all messages to ensure proper test teardown.
+ content::RunAllPendingInMessageLoop();
+ return;
+ }
- ASSERT_EQ(MockResourceLoader::Status::IDLE, mock_loader.status());
+ if (mock_loader.status() == MockResourceLoader::Status::CALLBACK_PENDING) {
+ test_handler->Resume();
+ // MimeSniffingResourceHandler may not synchronously resume the request.
+ base::RunLoop().RunUntilIdle();
+ }
- mock_loader.OnReadCompleted(std::string(2000, 'a'));
-
- EXPECT_EQ(1, test_handler->on_will_start_called());
- EXPECT_EQ(0, test_handler->on_request_redirected_called());
- EXPECT_EQ(1, test_handler->on_response_started_called());
- EXPECT_EQ(1, test_handler->on_will_read_called());
- EXPECT_EQ(1, test_handler->on_read_completed_called());
-
- if (!read_completed) {
- EXPECT_EQ(MockResourceLoader::Status::CANCELED, mock_loader.status());
- EXPECT_EQ(net::ERR_ABORTED, mock_loader.error_code());
-
- // Process all messages to ensure proper test teardown.
- content::RunAllPendingInMessageLoop();
- return;
- }
+ ++read_cycles;
+ } while (strlen(to_read) > 0);
if (mock_loader.status() == MockResourceLoader::Status::CALLBACK_PENDING) {
test_handler->Resume();
@@ -754,49 +806,59 @@ TEST_F(MimeSniffingResourceHandlerTest, NoSniffing) {
TestHandlerNoSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- true /* read_completed_succeeds */, false /* defer_read_completed */);
+ true /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
// Test deferral.
TestHandlerNoSniffing(
true /* response_started_succeeds */, true /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- true /* read_completed_succeeds */, false /* defer_read_completed */);
+ true /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerNoSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, true /* defer_will_read */,
- true /* read_completed_succeeds */, false /* defer_read_completed */);
+ true /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerNoSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- true /* read_completed_succeeds */, true /* defer_read_completed */);
+ true /* read_completed_succeeds */, true /* defer_read_completed */, 2048,
+ 2048);
TestHandlerNoSniffing(
true /* response_started_succeeds */, true /* defer_response_started */,
true /* will_read_succeeds */, true /* defer_will_read */,
- true /* read_completed_succeeds */, true /* defer_read_completed */);
+ true /* read_completed_succeeds */, true /* defer_read_completed */, 2048,
+ 2048);
// Test cancel in OnResponseStarted, OnWillRead, OnReadCompleted.
TestHandlerNoSniffing(
false /* response_started_succeeds */, false /* defer_response_started */,
false /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerNoSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
false /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerNoSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
// Test cancel after deferral.
TestHandlerNoSniffing(
true /* response_started_succeeds */, true /* defer_response_started */,
false /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerNoSniffing(
true /* response_started_succeeds */, true /* defer_response_started */,
true /* defer_will_read */, true /* will_read_succeeds */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
content::RunAllPendingInMessageLoop();
}
@@ -809,49 +871,59 @@ TEST_F(MimeSniffingResourceHandlerTest, Sniffing) {
TestHandlerSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- true /* read_completed_succeeds */, false /* defer_read_completed */);
+ true /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
// Test deferral.
TestHandlerSniffing(
true /* response_started_succeeds */, true /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- true /* read_completed_succeeds */, false /* defer_read_completed */);
- TestHandlerSniffing(
- true /* response_started_succeeds */, false /* defer_response_started */,
- true /* will_read_succeeds */, true /* defer_will_read */,
- true /* read_completed_succeeds */, false /* defer_read_completed */);
+ true /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
+ TestHandlerSniffing(true /* response_started_succeeds */,
+ false /* defer_response_started */,
+ true /* will_read_succeeds */, true /* defer_will_read */,
+ true /* read_completed_succeeds */,
+ false /* defer_read_completed */, 2048, 2048);
TestHandlerSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- true /* read_completed_succeeds */, true /* defer_read_completed */);
- TestHandlerSniffing(
- true /* response_started_succeeds */, true /* defer_response_started */,
- true /* will_read_succeeds */, true /* defer_will_read */,
- true /* read_completed_succeeds */, true /* defer_read_completed */);
+ true /* read_completed_succeeds */, true /* defer_read_completed */, 2048,
+ 2048);
+ TestHandlerSniffing(true /* response_started_succeeds */,
+ true /* defer_response_started */,
+ true /* will_read_succeeds */, true /* defer_will_read */,
+ true /* read_completed_succeeds */,
+ true /* defer_read_completed */, 2048, 2048);
// Test cancel in OnResponseStarted, OnWillRead, OnReadCompleted.
TestHandlerSniffing(
false /* response_started_succeeds */, false /* defer_response_started */,
false /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
false /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
TestHandlerSniffing(
true /* response_started_succeeds */, false /* defer_response_started */,
true /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
// Test cancel after deferral.
TestHandlerSniffing(
true /* response_started_succeeds */, true /* defer_response_started */,
false /* will_read_succeeds */, false /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
- TestHandlerSniffing(
- true /* response_started_succeeds */, true /* defer_response_started */,
- true /* will_read_succeeds */, true /* defer_will_read */,
- false /* read_completed_succeeds */, false /* defer_read_completed */);
+ false /* read_completed_succeeds */, false /* defer_read_completed */,
+ 2048, 2048);
+ TestHandlerSniffing(true /* response_started_succeeds */,
+ true /* defer_response_started */,
+ true /* will_read_succeeds */, true /* defer_will_read */,
+ false /* read_completed_succeeds */,
+ false /* defer_read_completed */, 2048, 2048);
content::RunAllPendingInMessageLoop();
}
@@ -958,4 +1030,18 @@ TEST_F(MimeSniffingResourceHandlerTest, FetchShouldDisableMimeSniffing) {
content::RunAllPendingInMessageLoop();
}
+TEST_F(MimeSniffingResourceHandlerTest, SmallReturnedBuffer) {
+ TestHandlerSniffing(true /* response_started_succeeds */,
+ true /* defer_response_started */,
+ true /* will_read_succeeds */, true /* defer_will_read */,
+ true /* read_completed_succeeds */,
+ true /* defer_read_completed */, 1, 1);
+
+ TestHandlerNoSniffing(
+ true /* response_started_succeeds */, true /* defer_response_started */,
+ true /* will_read_succeeds */, true /* defer_will_read */,
+ true /* read_completed_succeeds */, true /* defer_read_completed */, 1,
+ 1);
+}
+
} // namespace content
« no previous file with comments | « content/browser/loader/mime_sniffing_resource_handler.cc ('k') | content/browser/loader/mojo_async_resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698