Skip to content

Commit

Permalink
[DevTools] Always report encodedDataLength in Network.ResponseReceived.
Browse files Browse the repository at this point in the history
Currently, we only send encodedDataLength for redirects. However, we
already know how much we read when sending ResponseReceived. This will
improve reporting for failed requests, as they don't get loadingFinished
with full encodedDataLength.

Previous CL: https://codereview.chromium.org/2101073002
BUG=622018

Review-Url: https://codereview.chromium.org/2167853003
Cr-Commit-Position: refs/heads/master@{#417506}
  • Loading branch information
allada authored and Commit bot committed Sep 9, 2016
1 parent fa697bc commit 71b2efb
Show file tree
Hide file tree
Showing 24 changed files with 775 additions and 33 deletions.
5 changes: 5 additions & 0 deletions content/browser/loader/async_resource_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ bool AsyncResourceHandler::OnResponseStarted(ResourceResponse* response,
}

NetLogObserver::PopulateResponseInfo(request(), response);
response->head.encoded_data_length = request()->raw_header_size();

const HostZoomMapImpl* host_zoom_map =
static_cast<const HostZoomMapImpl*>(info->filter()->GetHostZoomMap());
Expand Down Expand Up @@ -442,7 +443,11 @@ bool AsyncResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
return false;

int encoded_data_length = CalculateEncodedDataLengthToReport();
if (!first_chunk_read_)
encoded_data_length -= request()->raw_header_size();

int encoded_body_length = CalculateEncodedBodyLengthToReport();
first_chunk_read_ = true;

// Return early if InliningHelper handled the received data.
if (inlining_helper_->SendInlinedDataIfApplicable(
Expand Down
2 changes: 2 additions & 0 deletions content/browser/loader/async_resource_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ class CONTENT_EXPORT AsyncResourceHandler : public ResourceHandler,

int allocation_size_;

bool first_chunk_read_ = false;

bool did_defer_;

bool has_checked_for_sufficient_resources_;
Expand Down
6 changes: 3 additions & 3 deletions content/browser/loader/async_resource_handler_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ TEST_F(AsyncResourceHandlerTest, OneChunkLengths) {
ResourceMsg_DataReceived::Read(messages[2].get(), &params);

int encoded_data_length = std::get<3>(params);
EXPECT_EQ(4157, encoded_data_length);
EXPECT_EQ(4096, encoded_data_length);
int encoded_body_length = std::get<4>(params);
EXPECT_EQ(4096, encoded_body_length);
}
Expand All @@ -278,7 +278,7 @@ TEST_F(AsyncResourceHandlerTest, InlinedChunkLengths) {
ResourceMsg_InlinedDataChunkReceived::Read(messages[1].get(), &params);

int encoded_data_length = std::get<2>(params);
EXPECT_EQ(66, encoded_data_length);
EXPECT_EQ(8, encoded_data_length);
int encoded_body_length = std::get<3>(params);
EXPECT_EQ(8, encoded_body_length);
}
Expand All @@ -293,7 +293,7 @@ TEST_F(AsyncResourceHandlerTest, TwoChunksLengths) {
ResourceMsg_DataReceived::Read(messages[2].get(), &params);

int encoded_data_length = std::get<3>(params);
EXPECT_EQ(32830, encoded_data_length);
EXPECT_EQ(32768, encoded_data_length);
int encoded_body_length = std::get<4>(params);
EXPECT_EQ(32768, encoded_body_length);

Expand Down
164 changes: 162 additions & 2 deletions net/quic/chromium/quic_network_transaction_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
#include "net/test/cert_test_util.h"
#include "net/test/gtest_util.h"
#include "net/test/test_data_directory.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
Expand Down Expand Up @@ -2530,8 +2533,8 @@ TEST_P(QuicNetworkTransactionTest, QuicServerPush) {
mock_quic_data.AddWrite(ConstructClientAckPacket(3, 4, 3, 1));
mock_quic_data.AddRead(ConstructServerDataPacket(
5, kServerDataStreamId1, false, true, 0, "and hello!"));
mock_quic_data.AddWrite(
ConstructClientAckAndRstPacket(4, 4, QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
mock_quic_data.AddWrite(ConstructClientAckAndRstPacket(
4, kServerDataStreamId1, QUIC_RST_ACKNOWLEDGEMENT, 5, 5, 1));
mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
mock_quic_data.AddRead(ASYNC, 0); // EOF
mock_quic_data.AddSocketDataToFactory(&socket_factory_);
Expand Down Expand Up @@ -2610,6 +2613,163 @@ TEST_P(QuicNetworkTransactionTest, QuicForceHolBlocking) {
SendRequestAndExpectQuicResponse("hello!");
}

class QuicURLRequestContext : public URLRequestContext {
public:
QuicURLRequestContext(std::unique_ptr<HttpNetworkSession> session,
MockClientSocketFactory* socket_factory)
: storage_(this) {
socket_factory_ = socket_factory;
storage_.set_host_resolver(
std::unique_ptr<HostResolver>(new MockHostResolver));
storage_.set_cert_verifier(base::WrapUnique(new MockCertVerifier));
storage_.set_transport_security_state(
base::WrapUnique(new TransportSecurityState));
storage_.set_proxy_service(ProxyService::CreateDirect());
storage_.set_ssl_config_service(new SSLConfigServiceDefaults);
storage_.set_http_auth_handler_factory(
HttpAuthHandlerFactory::CreateDefault(host_resolver()));
storage_.set_http_server_properties(
std::unique_ptr<HttpServerProperties>(new HttpServerPropertiesImpl()));
storage_.set_job_factory(base::WrapUnique(new URLRequestJobFactoryImpl()));
storage_.set_http_network_session(std::move(session));
storage_.set_http_transaction_factory(base::WrapUnique(
new HttpCache(storage_.http_network_session(),
HttpCache::DefaultBackend::InMemory(0), false)));
}

~QuicURLRequestContext() override { AssertNoURLRequests(); }

MockClientSocketFactory& socket_factory() { return *socket_factory_; }

private:
MockClientSocketFactory* socket_factory_;
URLRequestContextStorage storage_;
};

TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullRequest) {
params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));

MockQuicData mock_quic_data;
SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
headers["user-agent"] = "";
headers["accept-encoding"] = "gzip, deflate";
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
1, kClientDataStreamId1, true, true, std::move(headers)));

QuicStreamOffset expected_raw_header_response_size = 0;
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK"),
&expected_raw_header_response_size));

mock_quic_data.AddRead(ConstructServerDataPacket(
2, kClientDataStreamId1, false, true, 0, "Main Resource Data"));
mock_quic_data.AddWrite(ConstructClientAckPacket(2, 1));

mock_quic_data.AddRead(ASYNC, 0); // EOF

CreateSession();

TestDelegate delegate;
QuicURLRequestContext quic_url_request_context(std::move(session_),
&socket_factory_);

mock_quic_data.AddSocketDataToFactory(
&quic_url_request_context.socket_factory());
TestNetworkDelegate network_delegate;
quic_url_request_context.set_network_delegate(&network_delegate);

std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate));
quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
&ssl_data_);

request->Start();
base::RunLoop().Run();

EXPECT_LT(0, request->GetTotalSentBytes());
EXPECT_LT(0, request->GetTotalReceivedBytes());
EXPECT_EQ(network_delegate.total_network_bytes_sent(),
request->GetTotalSentBytes());
EXPECT_EQ(network_delegate.total_network_bytes_received(),
request->GetTotalReceivedBytes());
EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
request->raw_header_size());
EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
}

TEST_P(QuicNetworkTransactionTest, RawHeaderSizeSuccessfullPushHeadersFirst) {
params_.origins_to_force_quic_on.insert(
HostPortPair::FromString("mail.example.org:443"));

MockQuicData mock_quic_data;
SpdyHeaderBlock headers(GetRequestHeaders("GET", "https", "/"));
headers["user-agent"] = "";
headers["accept-encoding"] = "gzip, deflate";
mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
1, kClientDataStreamId1, true, true, std::move(headers)));

QuicStreamOffset server_header_offset = 0;
QuicStreamOffset expected_raw_header_response_size = 0;

mock_quic_data.AddRead(ConstructServerPushPromisePacket(
1, kClientDataStreamId1, kServerDataStreamId1, false,
GetRequestHeaders("GET", "https", "/pushed.jpg"), &server_header_offset,
&server_maker_));

expected_raw_header_response_size = server_header_offset;
mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
2, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK"),
&server_header_offset));
expected_raw_header_response_size =
server_header_offset - expected_raw_header_response_size;

mock_quic_data.AddWrite(ConstructClientAckPacket(2, 2, 1, 1));

mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
3, kServerDataStreamId1, false, false, GetResponseHeaders("200 OK"),
&server_header_offset));
mock_quic_data.AddRead(ConstructServerDataPacket(
4, kServerDataStreamId1, false, true, 0, "Pushed Resource Data"));

mock_quic_data.AddWrite(ConstructClientAckPacket(3, 4, 3, 1));
mock_quic_data.AddRead(ConstructServerDataPacket(
5, kClientDataStreamId1, false, true, 0, "Main Resource Data"));

mock_quic_data.AddRead(ConstructServerConnectionClosePacket(6));

CreateSession();

TestDelegate delegate;
QuicURLRequestContext quic_url_request_context(std::move(session_),
&socket_factory_);

mock_quic_data.AddSocketDataToFactory(
&quic_url_request_context.socket_factory());
TestNetworkDelegate network_delegate;
quic_url_request_context.set_network_delegate(&network_delegate);

std::unique_ptr<URLRequest> request(quic_url_request_context.CreateRequest(
GURL("https://mail.example.org/"), DEFAULT_PRIORITY, &delegate));
quic_url_request_context.socket_factory().AddSSLSocketDataProvider(
&ssl_data_);

request->Start();
base::RunLoop().Run();

EXPECT_LT(0, request->GetTotalSentBytes());
EXPECT_LT(0, request->GetTotalReceivedBytes());
EXPECT_EQ(network_delegate.total_network_bytes_sent(),
request->GetTotalSentBytes());
EXPECT_EQ(network_delegate.total_network_bytes_received(),
request->GetTotalReceivedBytes());
EXPECT_EQ(static_cast<int>(expected_raw_header_response_size),
request->raw_header_size());
EXPECT_TRUE(mock_quic_data.AllReadDataConsumed());
EXPECT_TRUE(mock_quic_data.AllWriteDataConsumed());
}

class QuicNetworkTransactionWithDestinationTest
: public PlatformTest,
public ::testing::WithParamInterface<PoolingTestParams> {
Expand Down
126 changes: 124 additions & 2 deletions net/spdy/spdy_network_transaction_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2106,6 +2106,128 @@ TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
helper.VerifyDataConsumed();
}

TEST_F(SpdyNetworkTransactionTest, TestRawHeaderSizeSuccessfullRequest) {
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
headers["user-agent"] = "";
headers["accept-encoding"] = "gzip, deflate";

SpdySerializedFrame req(
spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
MockWrite writes[] = {
CreateMockWrite(req, 0),
};

SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));

SpdySerializedFrame response_body_frame(
spdy_util_.ConstructSpdyDataFrame(1, "should not include", 18, true));

MockRead response_headers(CreateMockRead(resp, 1));
MockRead reads[] = {
response_headers, CreateMockRead(response_body_frame, 2),
MockRead(ASYNC, 0, 0, 3) // EOF
};
SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));

TestDelegate delegate;
SpdyURLRequestContext spdy_url_request_context;
TestNetworkDelegate network_delegate;
spdy_url_request_context.set_network_delegate(&network_delegate);
SSLSocketDataProvider ssl_data(ASYNC, OK);
ssl_data.next_proto = kProtoHTTP2;

std::unique_ptr<URLRequest> request(spdy_url_request_context.CreateRequest(
GURL(kDefaultUrl), DEFAULT_PRIORITY, &delegate));
spdy_url_request_context.socket_factory().AddSSLSocketDataProvider(&ssl_data);
spdy_url_request_context.socket_factory().AddSocketDataProvider(&data);

request->Start();
base::RunLoop().Run();

EXPECT_LT(0, request->GetTotalSentBytes());
EXPECT_LT(0, request->GetTotalReceivedBytes());
EXPECT_EQ(network_delegate.total_network_bytes_sent(),
request->GetTotalSentBytes());
EXPECT_EQ(network_delegate.total_network_bytes_received(),
request->GetTotalReceivedBytes());
EXPECT_EQ(response_headers.data_len, request->raw_header_size());
EXPECT_TRUE(data.AllReadDataConsumed());
EXPECT_TRUE(data.AllWriteDataConsumed());
}

TEST_F(SpdyNetworkTransactionTest,
TestRawHeaderSizeSuccessfullPushHeadersFirst) {
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
headers["user-agent"] = "";
headers["accept-encoding"] = "gzip, deflate";

SpdySerializedFrame req(
spdy_util_.ConstructSpdyHeaders(1, std::move(headers), LOWEST, true));
MockWrite writes[] = {
CreateMockWrite(req, 0),
};

SpdySerializedFrame resp(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1));
SpdySerializedFrame response_body_frame(
spdy_util_.ConstructSpdyDataFrame(1, "should not include", 18, true));

SpdyHeaderBlock push_headers;
spdy_util_.AddUrlToHeaderBlock(std::string(kDefaultUrl) + "b.dat",
&push_headers);

SpdySerializedFrame push_init_frame(
spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 2, 1));

SpdySerializedFrame push_headers_frame(
spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0));

SpdySerializedFrame push_body_frame(spdy_util_.ConstructSpdyDataFrame(
2, "should not include either", 25, false));

MockRead push_init_read(CreateMockRead(push_init_frame, 1));
MockRead response_headers(CreateMockRead(resp, 4));
// raw_header_size() will contain the size of the push promise frame
// initialization.
int expected_response_headers_size =
response_headers.data_len + push_init_read.data_len;

MockRead reads[] = {
push_init_read,
CreateMockRead(push_headers_frame, 2),
CreateMockRead(push_body_frame, 3),
response_headers,
CreateMockRead(response_body_frame, 5),
MockRead(ASYNC, 0, 6) // EOF
};

SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes));

TestDelegate delegate;
SpdyURLRequestContext spdy_url_request_context;
TestNetworkDelegate network_delegate;
spdy_url_request_context.set_network_delegate(&network_delegate);
SSLSocketDataProvider ssl_data(ASYNC, OK);
ssl_data.next_proto = kProtoHTTP2;

std::unique_ptr<URLRequest> request(spdy_url_request_context.CreateRequest(
GURL(kDefaultUrl), DEFAULT_PRIORITY, &delegate));
spdy_url_request_context.socket_factory().AddSSLSocketDataProvider(&ssl_data);
spdy_url_request_context.socket_factory().AddSocketDataProvider(&data);

request->Start();
base::RunLoop().Run();

EXPECT_LT(0, request->GetTotalSentBytes());
EXPECT_LT(0, request->GetTotalReceivedBytes());
EXPECT_EQ(network_delegate.total_network_bytes_sent(),
request->GetTotalSentBytes());
EXPECT_EQ(network_delegate.total_network_bytes_received(),
request->GetTotalReceivedBytes());
EXPECT_EQ(expected_response_headers_size, request->raw_header_size());
EXPECT_TRUE(data.AllReadDataConsumed());
EXPECT_TRUE(data.AllWriteDataConsumed());
}

// Send a spdy request to www.example.org that gets redirected to www.foo.com.
TEST_F(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) {
SpdyHeaderBlock headers(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl));
Expand Down Expand Up @@ -2166,7 +2288,7 @@ TEST_F(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) {
base::RunLoop().Run();
EXPECT_EQ(1, d.response_started_count());
EXPECT_FALSE(d.received_data_before_response());
EXPECT_EQ(URLRequestStatus::SUCCESS, r->status().status());
EXPECT_EQ(OK, r->status().error());
std::string contents("hello!");
EXPECT_EQ(contents, d.data_received());
}
Expand Down Expand Up @@ -2252,7 +2374,7 @@ TEST_F(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) {
base::RunLoop().Run();
EXPECT_EQ(1, d2.response_started_count());
EXPECT_FALSE(d2.received_data_before_response());
EXPECT_EQ(URLRequestStatus::SUCCESS, r2->status().status());
EXPECT_EQ(OK, r2->status().error());
std::string contents2("hello!");
EXPECT_EQ(contents2, d2.data_received());
}
Expand Down
Loading

0 comments on commit 71b2efb

Please sign in to comment.