summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorsclittle <sclittle@chromium.org>2015-09-02 12:40:36 -0700
committerCommit bot <commit-bot@chromium.org>2015-09-02 19:41:05 +0000
commitbe1ccf63461b881b8542975e086a0e682600e2b2 (patch)
treecd2e395dcf62e2fd9541e6dbb5974d5d55facf3c /net
parentd080cd6fa5d274b132f1ba3f1ab9153b2e9800a0 (diff)
downloadchromium_src-be1ccf63461b881b8542975e086a0e682600e2b2.zip
chromium_src-be1ccf63461b881b8542975e086a0e682600e2b2.tar.gz
chromium_src-be1ccf63461b881b8542975e086a0e682600e2b2.tar.bz2
Added and implemented HttpStream::GetTotalSentBytes for basic streams.
Added HttpStream::GetTotalSentBytes, which counts the number of bytes sent over the network, similar to HttpStream::GetTotalReceivedBytes. This CL implements this method for basic HTTP streams; implementations for SPDY and QUIC streams will be added in later CLs. BUG=518897 Review URL: https://codereview.chromium.org/1314783007 Cr-Commit-Position: refs/heads/master@{#346996}
Diffstat (limited to 'net')
-rw-r--r--net/http/http_basic_stream.cc6
-rw-r--r--net/http/http_basic_stream.h4
-rw-r--r--net/http/http_network_transaction_unittest.cc12
-rw-r--r--net/http/http_response_body_drainer_unittest.cc3
-rw-r--r--net/http/http_stream.h5
-rw-r--r--net/http/http_stream_factory_impl_unittest.cc3
-rw-r--r--net/http/http_stream_parser.cc3
-rw-r--r--net/http/http_stream_parser.h7
-rw-r--r--net/http/http_stream_parser_unittest.cc234
-rw-r--r--net/http/proxy_connect_redirect_http_stream.cc4
-rw-r--r--net/http/proxy_connect_redirect_http_stream.h3
-rw-r--r--net/quic/quic_http_stream.cc5
-rw-r--r--net/quic/quic_http_stream.h3
-rw-r--r--net/socket/socket_test_util.cc14
-rw-r--r--net/socket/socket_test_util.h8
-rw-r--r--net/spdy/spdy_http_stream.cc5
-rw-r--r--net/spdy/spdy_http_stream.h3
-rw-r--r--net/url_request/url_request_http_job_unittest.cc3
-rw-r--r--net/websockets/websocket_basic_handshake_stream.cc4
-rw-r--r--net/websockets/websocket_basic_handshake_stream.h3
20 files changed, 331 insertions, 1 deletions
diff --git a/net/http/http_basic_stream.cc b/net/http/http_basic_stream.cc
index 795e299..42a2592 100644
--- a/net/http/http_basic_stream.cc
+++ b/net/http/http_basic_stream.cc
@@ -83,6 +83,12 @@ int64 HttpBasicStream::GetTotalReceivedBytes() const {
return 0;
}
+int64_t HttpBasicStream::GetTotalSentBytes() const {
+ if (parser())
+ return parser()->sent_bytes();
+ return 0;
+}
+
bool HttpBasicStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
return state_.connection()->GetLoadTimingInfo(IsConnectionReused(),
diff --git a/net/http/http_basic_stream.h b/net/http/http_basic_stream.h
index b3d8301..55b0efd4 100644
--- a/net/http/http_basic_stream.h
+++ b/net/http/http_basic_stream.h
@@ -9,6 +9,8 @@
#ifndef NET_HTTP_HTTP_BASIC_STREAM_H_
#define NET_HTTP_HTTP_BASIC_STREAM_H_
+#include <stdint.h>
+
#include <string>
#include "base/basictypes.h"
@@ -64,6 +66,8 @@ class HttpBasicStream : public HttpStream {
int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
+
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
void GetSSLInfo(SSLInfo* ssl_info) override;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 452ba6b..14bda39 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -6,6 +6,8 @@
#include <math.h> // ceil
#include <stdarg.h>
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -13363,6 +13365,11 @@ class FakeStream : public HttpStream,
return 0;
}
+ int64_t GetTotalSentBytes() const override {
+ ADD_FAILURE();
+ return 0;
+ }
+
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
ADD_FAILURE();
return false;
@@ -13574,6 +13581,11 @@ class FakeWebSocketBasicHandshakeStream : public WebSocketHandshakeStreamBase {
return 0;
}
+ int64_t GetTotalSentBytes() const override {
+ NOTREACHED();
+ return 0;
+ }
+
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
NOTREACHED();
return false;
diff --git a/net/http/http_response_body_drainer_unittest.cc b/net/http/http_response_body_drainer_unittest.cc
index f34f57f..b2defb0a 100644
--- a/net/http/http_response_body_drainer_unittest.cc
+++ b/net/http/http_response_body_drainer_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_response_body_drainer.h"
+#include <stdint.h>
+
#include <cstring>
#include "base/bind.h"
@@ -100,6 +102,7 @@ class MockHttpStream : public HttpStream {
void SetConnectionReused() override {}
bool CanReuseConnection() const override { return false; }
int64 GetTotalReceivedBytes() const override { return 0; }
+ int64_t GetTotalSentBytes() const override { return 0; }
void GetSSLInfo(SSLInfo* ssl_info) override {}
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override {}
diff --git a/net/http/http_stream.h b/net/http/http_stream.h
index 2bfc5b6..5762339 100644
--- a/net/http/http_stream.h
+++ b/net/http/http_stream.h
@@ -11,6 +11,8 @@
#ifndef NET_HTTP_HTTP_STREAM_H_
#define NET_HTTP_HTTP_STREAM_H_
+#include <stdint.h>
+
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/completion_callback.h"
@@ -118,6 +120,9 @@ class NET_EXPORT_PRIVATE HttpStream {
// Get the total number of bytes received from network for this stream.
virtual int64 GetTotalReceivedBytes() const = 0;
+ // Get the total number of bytes sent over the network for this stream.
+ virtual int64_t GetTotalSentBytes() const = 0;
+
// Populates the connection establishment part of |load_timing_info|, and
// socket ID. |load_timing_info| must have all null times when called.
// Returns false and does nothing if there is no underlying connection, either
diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc
index ad3b5ec..11cf98d 100644
--- a/net/http/http_stream_factory_impl_unittest.cc
+++ b/net/http/http_stream_factory_impl_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_stream_factory_impl.h"
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -85,6 +87,7 @@ class MockWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
void SetConnectionReused() override {}
bool CanReuseConnection() const override { return false; }
int64 GetTotalReceivedBytes() const override { return 0; }
+ int64_t GetTotalSentBytes() const override { return 0; }
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
return false;
}
diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc
index 953635b..9ddae48 100644
--- a/net/http/http_stream_parser.cc
+++ b/net/http/http_stream_parser.cc
@@ -208,6 +208,7 @@ HttpStreamParser::HttpStreamParser(ClientSocketHandle* connection,
read_buf_unused_offset_(0),
response_header_start_offset_(-1),
received_bytes_(0),
+ sent_bytes_(0),
response_(nullptr),
response_body_length_(-1),
response_body_read_(0),
@@ -475,6 +476,7 @@ int HttpStreamParser::DoSendHeadersComplete(int result) {
return result;
}
+ sent_bytes_ += result;
request_headers_->DidConsume(result);
if (request_headers_->BytesRemaining() > 0) {
io_state_ = STATE_SEND_HEADERS;
@@ -532,6 +534,7 @@ int HttpStreamParser::DoSendBodyComplete(int result) {
return result;
}
+ sent_bytes_ += result;
request_body_send_buf_->DidConsume(result);
io_state_ = STATE_SEND_BODY;
diff --git a/net/http/http_stream_parser.h b/net/http/http_stream_parser.h
index cb18cc8..548460c 100644
--- a/net/http/http_stream_parser.h
+++ b/net/http/http_stream_parser.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_HTTP_STREAM_PARSER_H_
#define NET_HTTP_HTTP_STREAM_PARSER_H_
+#include <stdint.h>
+
#include <string>
#include "base/basictypes.h"
@@ -85,6 +87,8 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
int64 received_bytes() const { return received_bytes_; }
+ int64_t sent_bytes() const { return sent_bytes_; }
+
void GetSSLInfo(SSLInfo* ssl_info);
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
@@ -209,6 +213,9 @@ class NET_EXPORT_PRIVATE HttpStreamParser {
// value may be bigger than final.
int64 received_bytes_;
+ // The amount of sent data.
+ int64_t sent_bytes_;
+
// The parsed response headers. Owned by the caller of SendRequest. This
// cannot be safely accessed after reading the final set of headers, as the
// caller of SendRequest may have been destroyed - this happens in the case an
diff --git a/net/http/http_stream_parser_unittest.cc b/net/http/http_stream_parser_unittest.cc
index 76f998a..0129606 100644
--- a/net/http/http_stream_parser_unittest.cc
+++ b/net/http/http_stream_parser_unittest.cc
@@ -4,6 +4,8 @@
#include "net/http/http_stream_parser.h"
+#include <stdint.h>
+
#include <algorithm>
#include <string>
#include <vector>
@@ -199,6 +201,208 @@ TEST(HttpStreamParser, ShouldMergeRequestHeadersAndBody_LargeBodyInMemory) {
"some header", body.get()));
}
+TEST(HttpStreamParser, SentBytesNoHeaders) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n\r\n"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", HttpRequestHeaders(),
+ &response, callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesWithHeaders) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0,
+ "GET / HTTP/1.1\r\n"
+ "Host: localhost\r\n"
+ "Connection: Keep-Alive\r\n\r\n"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Host", "localhost");
+ headers.SetHeader("Connection", "Keep-Alive");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesWithHeadersMultiWrite) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"),
+ MockWrite(SYNCHRONOUS, 2, "Connection: Keep-Alive\r\n\r\n"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Host", "localhost");
+ headers.SetHeader("Connection", "Keep-Alive");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+
+ EXPECT_EQ(OK, parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesWithErrorWritingHeaders) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Host: localhost\r\n"),
+ MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET, 2),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("http://localhost");
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Host", "localhost");
+ headers.SetHeader("Connection", "Keep-Alive");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_CONNECTION_RESET,
+ parser.SendRequest("GET / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesPost) {
+ MockWrite writes[] = {
+ MockWrite(SYNCHRONOUS, 0, "POST / HTTP/1.1\r\n"),
+ MockWrite(SYNCHRONOUS, 1, "Content-Length: 12\r\n\r\n"),
+ MockWrite(SYNCHRONOUS, 2, "hello world!"),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ ScopedVector<UploadElementReader> element_readers;
+ element_readers.push_back(new UploadBytesElementReader("hello world!", 12));
+ ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
+ ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://localhost");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Content-Length", "12");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(OK, parser.SendRequest("POST / HTTP/1.1\r\n", headers, &response,
+ callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
+TEST(HttpStreamParser, SentBytesChunkedPostError) {
+ static const char kChunk[] = "Chunk 1";
+
+ MockWrite writes[] = {
+ MockWrite(ASYNC, 0, "POST / HTTP/1.1\r\n"),
+ MockWrite(ASYNC, 1, "Transfer-Encoding: chunked\r\n\r\n"),
+ MockWrite(ASYNC, 2, "7\r\nChunk 1\r\n"),
+ MockWrite(SYNCHRONOUS, ERR_FAILED, 3),
+ };
+
+ SequencedSocketData data(nullptr, 0, writes, arraysize(writes));
+ scoped_ptr<ClientSocketHandle> socket_handle =
+ CreateConnectedSocketHandle(&data);
+
+ ChunkedUploadDataStream upload_data_stream(0);
+ ASSERT_EQ(OK, upload_data_stream.Init(TestCompletionCallback().callback()));
+
+ HttpRequestInfo request;
+ request.method = "POST";
+ request.url = GURL("http://localhost");
+ request.upload_data_stream = &upload_data_stream;
+
+ scoped_refptr<GrowableIOBuffer> read_buffer(new GrowableIOBuffer);
+ HttpStreamParser parser(socket_handle.get(), &request, read_buffer.get(),
+ BoundNetLog());
+
+ HttpRequestHeaders headers;
+ headers.SetHeader("Transfer-Encoding", "chunked");
+
+ HttpResponseInfo response;
+ TestCompletionCallback callback;
+ EXPECT_EQ(ERR_IO_PENDING, parser.SendRequest("POST / HTTP/1.1\r\n", headers,
+ &response, callback.callback()));
+
+ base::RunLoop().RunUntilIdle();
+ upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false);
+
+ base::RunLoop().RunUntilIdle();
+ // This write should fail.
+ upload_data_stream.AppendData(kChunk, arraysize(kChunk) - 1, false);
+ EXPECT_EQ(ERR_FAILED, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+}
+
// Test to ensure the HttpStreamParser state machine does not get confused
// when sending a request with a chunked body with only one chunk that becomes
// available asynchronously.
@@ -269,6 +473,9 @@ TEST(HttpStreamParser, AsyncSingleChunkAndAsyncSocket) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -336,6 +543,9 @@ TEST(HttpStreamParser, SyncSingleChunkAndAsyncSocket) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -426,6 +636,9 @@ TEST(HttpStreamParser, AsyncChunkAndAsyncSocketWithMultipleChunks) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -493,6 +706,9 @@ TEST(HttpStreamParser, AsyncEmptyChunkedUpload) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
// Test to ensure the HttpStreamParser state machine does not get confused
@@ -559,6 +775,9 @@ TEST(HttpStreamParser, SyncEmptyChunkedUpload) {
parser.ReadResponseBody(body_buffer.get(), kBodySize,
callback.callback()));
ASSERT_EQ(kBodySize, callback.WaitForResult());
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
TEST(HttpStreamParser, TruncatedHeaders) {
@@ -640,16 +859,21 @@ TEST(HttpStreamParser, TruncatedHeaders) {
&response_info, callback.callback()));
int rv = parser.ReadResponseHeaders(callback.callback());
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)),
+ parser.sent_bytes());
if (i == arraysize(reads) - 1) {
EXPECT_EQ(OK, rv);
EXPECT_TRUE(response_info.headers.get());
+ EXPECT_EQ(CountReadBytes(reads[i], 2), parser.received_bytes());
} else {
if (protocol == HTTP) {
EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
EXPECT_TRUE(response_info.headers.get());
+ EXPECT_EQ(CountReadBytes(reads[i], 2), parser.received_bytes());
} else {
EXPECT_EQ(ERR_RESPONSE_HEADERS_TRUNCATED, rv);
EXPECT_FALSE(response_info.headers.get());
+ EXPECT_EQ(0, parser.received_bytes());
}
}
}
@@ -700,6 +924,11 @@ TEST(HttpStreamParser, Websocket101Response) {
EXPECT_EQ("a fake websocket frame",
base::StringPiece(read_buffer->StartOfBuffer(),
read_buffer->capacity()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)) -
+ static_cast<int64_t>(strlen("a fake websocket frame")),
+ parser.received_bytes());
}
// Helper class for constructing HttpStreamParser and running GET requests.
@@ -1017,7 +1246,7 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
const int kBodySize = 1;
MockRead reads[] = {
MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
- MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n\r\n"),
+ MockRead(SYNCHRONOUS, 2, "Content-Length: 1\r\n"),
MockRead(SYNCHRONOUS, 3, "Connection: Keep-Alive\r\n\r\n"),
MockRead(SYNCHRONOUS, 4, "1"),
MockRead(SYNCHRONOUS, 0, 5), // EOF
@@ -1051,6 +1280,9 @@ TEST(HttpStreamParser, ReadAfterUnownedObjectsDestroyed) {
scoped_refptr<IOBuffer> body_buffer(new IOBuffer(kBodySize));
ASSERT_EQ(kBodySize, parser.ReadResponseBody(
body_buffer.get(), kBodySize, callback.callback()));
+
+ EXPECT_EQ(CountWriteBytes(writes, arraysize(writes)), parser.sent_bytes());
+ EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), parser.received_bytes());
}
} // namespace
diff --git a/net/http/proxy_connect_redirect_http_stream.cc b/net/http/proxy_connect_redirect_http_stream.cc
index 3b16607..8f66b82 100644
--- a/net/http/proxy_connect_redirect_http_stream.cc
+++ b/net/http/proxy_connect_redirect_http_stream.cc
@@ -75,6 +75,10 @@ int64 ProxyConnectRedirectHttpStream::GetTotalReceivedBytes() const {
return 0;
}
+int64_t ProxyConnectRedirectHttpStream::GetTotalSentBytes() const {
+ return 0;
+}
+
bool ProxyConnectRedirectHttpStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
if (!has_load_timing_info_)
diff --git a/net/http/proxy_connect_redirect_http_stream.h b/net/http/proxy_connect_redirect_http_stream.h
index e268ebf..352f3cb 100644
--- a/net/http/proxy_connect_redirect_http_stream.h
+++ b/net/http/proxy_connect_redirect_http_stream.h
@@ -5,6 +5,8 @@
#ifndef NET_HTTP_PROXY_CONNECT_REDIRECT_HTTP_STREAM_H_
#define NET_HTTP_PROXY_CONNECT_REDIRECT_HTTP_STREAM_H_
+#include <stdint.h>
+
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "net/base/load_timing_info.h"
@@ -47,6 +49,7 @@ class ProxyConnectRedirectHttpStream : public HttpStream {
bool CanReuseConnection() const override;
int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
// This function may be called.
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc
index d434d41..d28eac9 100644
--- a/net/quic/quic_http_stream.cc
+++ b/net/quic/quic_http_stream.cc
@@ -260,6 +260,11 @@ int64 QuicHttpStream::GetTotalReceivedBytes() const {
return closed_stream_received_bytes_;
}
+int64_t QuicHttpStream::GetTotalSentBytes() const {
+ // TODO(sclittle): Implement this for real. http://crbug.com/518897.
+ return 0;
+}
+
bool QuicHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
// TODO(mmenke): Figure out what to do here.
return true;
diff --git a/net/quic/quic_http_stream.h b/net/quic/quic_http_stream.h
index 3b627dd..ac2ba05dbc 100644
--- a/net/quic/quic_http_stream.h
+++ b/net/quic/quic_http_stream.h
@@ -5,6 +5,8 @@
#ifndef NET_QUIC_QUIC_HTTP_STREAM_H_
#define NET_QUIC_QUIC_HTTP_STREAM_H_
+#include <stdint.h>
+
#include <list>
#include "build/build_config.h"
@@ -64,6 +66,7 @@ class NET_EXPORT_PRIVATE QuicHttpStream
void SetConnectionReused() override;
bool CanReuseConnection() const override;
int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
void GetSSLInfo(SSLInfo* ssl_info) override;
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 98bf322..1d5da04 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -2038,4 +2038,18 @@ const char kSOCKS5OkResponse[] =
{ 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
const int kSOCKS5OkResponseLength = arraysize(kSOCKS5OkResponse);
+int64_t CountReadBytes(const MockRead reads[], size_t reads_size) {
+ int64_t total = 0;
+ for (const MockRead* read = reads; read != reads + reads_size; ++read)
+ total += read->data_len;
+ return total;
+}
+
+int64_t CountWriteBytes(const MockWrite writes[], size_t writes_size) {
+ int64_t total = 0;
+ for (const MockWrite* write = writes; write != writes + writes_size; ++write)
+ total += write->data_len;
+ return total;
+}
+
} // namespace net
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index bd9725c..523e9ac 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -5,6 +5,8 @@
#ifndef NET_SOCKET_SOCKET_TEST_UTIL_H_
#define NET_SOCKET_SOCKET_TEST_UTIL_H_
+#include <stdint.h>
+
#include <cstring>
#include <deque>
#include <string>
@@ -1237,6 +1239,12 @@ extern const int kSOCKS5OkRequestLength;
extern const char kSOCKS5OkResponse[];
extern const int kSOCKS5OkResponseLength;
+// Helper function to get the total data size of the MockReads in |reads|.
+int64_t CountReadBytes(const MockRead reads[], size_t reads_size);
+
+// Helper function to get the total data size of the MockWrites in |writes|.
+int64_t CountWriteBytes(const MockWrite writes[], size_t writes_size);
+
} // namespace net
#endif // NET_SOCKET_SOCKET_TEST_UTIL_H_
diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc
index f8546ec..f07686f 100644
--- a/net/spdy/spdy_http_stream.cc
+++ b/net/spdy/spdy_http_stream.cc
@@ -183,6 +183,11 @@ int64 SpdyHttpStream::GetTotalReceivedBytes() const {
return stream_->raw_received_bytes();
}
+int64_t SpdyHttpStream::GetTotalSentBytes() const {
+ // TODO(sclittle): Implement this for real. http://crbug.com/518897.
+ return 0;
+}
+
bool SpdyHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
if (stream_closed_) {
if (!closed_stream_has_load_timing_info_)
diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h
index b5ed813..a3b906c 100644
--- a/net/spdy/spdy_http_stream.h
+++ b/net/spdy/spdy_http_stream.h
@@ -5,6 +5,8 @@
#ifndef NET_SPDY_SPDY_HTTP_STREAM_H_
#define NET_SPDY_SPDY_HTTP_STREAM_H_
+#include <stdint.h>
+
#include <list>
#include "base/basictypes.h"
@@ -65,6 +67,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate,
void SetConnectionReused() override;
bool CanReuseConnection() const override;
int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
void GetSSLInfo(SSLInfo* ssl_info) override;
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index 5022d61..50557ec 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -4,6 +4,8 @@
#include "net/url_request/url_request_http_job.h"
+#include <stdint.h>
+
#include <cstddef>
#include "base/compiler_specific.h"
@@ -609,6 +611,7 @@ class FakeWebSocketHandshakeStream : public WebSocketHandshakeStreamBase {
bool CanReuseConnection() const override { return false; }
int64 GetTotalReceivedBytes() const override { return 0; }
+ int64_t GetTotalSentBytes() const override { return 0; }
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override {
return false;
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc
index 5b2b031..da64386 100644
--- a/net/websockets/websocket_basic_handshake_stream.cc
+++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -478,6 +478,10 @@ int64 WebSocketBasicHandshakeStream::GetTotalReceivedBytes() const {
return 0;
}
+int64_t WebSocketBasicHandshakeStream::GetTotalSentBytes() const {
+ return 0;
+}
+
bool WebSocketBasicHandshakeStream::GetLoadTimingInfo(
LoadTimingInfo* load_timing_info) const {
return state_.connection()->GetLoadTimingInfo(IsConnectionReused(),
diff --git a/net/websockets/websocket_basic_handshake_stream.h b/net/websockets/websocket_basic_handshake_stream.h
index 239b96b..9352d30 100644
--- a/net/websockets/websocket_basic_handshake_stream.h
+++ b/net/websockets/websocket_basic_handshake_stream.h
@@ -5,6 +5,8 @@
#ifndef NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_
#define NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_
+#include <stdint.h>
+
#include <string>
#include <vector>
@@ -56,6 +58,7 @@ class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
void SetConnectionReused() override;
bool CanReuseConnection() const override;
int64 GetTotalReceivedBytes() const override;
+ int64_t GetTotalSentBytes() const override;
bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
void GetSSLInfo(SSLInfo* ssl_info) override;
void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;