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 |