summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorsimonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-20 22:17:03 +0000
committersimonjam@chromium.org <simonjam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-12-20 22:17:03 +0000
commit837c4f559f45a1b66c1e6af28924ce51a1133c03 (patch)
tree15d3465f40abd57ccebae87c9df0c05bdc2668f0 /net/http
parent096fa7b6ccf1c147a4c510516c6aa93419bb4d0a (diff)
downloadchromium_src-837c4f559f45a1b66c1e6af28924ce51a1133c03.zip
chromium_src-837c4f559f45a1b66c1e6af28924ce51a1133c03.tar.gz
chromium_src-837c4f559f45a1b66c1e6af28924ce51a1133c03.tar.bz2
Add HTTP pipelining to net-internals:
- Make HttpPipelinedConnection its own NetLog::Source - Report when pipelines are constructed and deleted - Report pipelining feedback - Add a HTTP Pipelining tab with status, active pipelines, and known hosts. BUG=None TEST=chrome://net-internals Review URL: http://codereview.chromium.org/8947012 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@115197 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_pipelined_connection.h2
-rw-r--r--net/http/http_pipelined_connection_impl.cc110
-rw-r--r--net/http/http_pipelined_connection_impl.h12
-rw-r--r--net/http/http_pipelined_connection_impl_unittest.cc11
-rw-r--r--net/http/http_pipelined_host.h9
-rw-r--r--net/http/http_pipelined_host_impl.cc26
-rw-r--r--net/http/http_pipelined_host_impl.h8
-rw-r--r--net/http/http_pipelined_host_impl_unittest.cc6
-rw-r--r--net/http/http_pipelined_host_pool.cc14
-rw-r--r--net/http/http_pipelined_host_pool.h8
-rw-r--r--net/http/http_pipelined_host_pool_unittest.cc1
-rw-r--r--net/http/http_stream_factory.h9
-rw-r--r--net/http/http_stream_factory_impl.cc4
-rw-r--r--net/http/http_stream_factory_impl.h1
14 files changed, 201 insertions, 20 deletions
diff --git a/net/http/http_pipelined_connection.h b/net/http/http_pipelined_connection.h
index 4a27a52..c5db438 100644
--- a/net/http/http_pipelined_connection.h
+++ b/net/http/http_pipelined_connection.h
@@ -14,6 +14,7 @@ namespace net {
class BoundNetLog;
class ClientSocketHandle;
+class HostPortPair;
class HttpPipelinedStream;
class ProxyInfo;
struct SSLConfig;
@@ -47,6 +48,7 @@ class NET_EXPORT_PRIVATE HttpPipelinedConnection {
virtual HttpPipelinedConnection* CreateNewPipeline(
ClientSocketHandle* connection,
Delegate* delegate,
+ const HostPortPair& origin,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
const BoundNetLog& net_log,
diff --git a/net/http/http_pipelined_connection_impl.cc b/net/http/http_pipelined_connection_impl.cc
index 8699273..e8a3e78 100644
--- a/net/http/http_pipelined_connection_impl.cc
+++ b/net/http/http_pipelined_connection_impl.cc
@@ -6,6 +6,7 @@
#include "base/message_loop.h"
#include "base/stl_util.h"
+#include "base/values.h"
#include "net/base/io_buffer.h"
#include "net/http/http_pipelined_stream.h"
#include "net/http/http_request_info.h"
@@ -15,11 +16,54 @@
#include "net/http/http_version.h"
#include "net/socket/client_socket_handle.h"
+using base::DictionaryValue;
+using base::Value;
+
namespace net {
+namespace {
+
+class ReceivedHeadersParameters : public NetLog::EventParameters {
+ public:
+ ReceivedHeadersParameters(const NetLog::Source& source,
+ const std::string& feedback)
+ : source_(source), feedback_(feedback) {}
+
+ virtual Value* ToValue() const OVERRIDE {
+ DictionaryValue* dict = new DictionaryValue;
+ dict->Set("source_dependency", source_.ToValue());
+ dict->SetString("feedback", feedback_);
+ return dict;
+ }
+
+ private:
+ const NetLog::Source source_;
+ const std::string feedback_;
+};
+
+class StreamClosedParameters : public NetLog::EventParameters {
+ public:
+ StreamClosedParameters(const NetLog::Source& source, bool not_reusable)
+ : source_(source), not_reusable_(not_reusable) {}
+
+ virtual Value* ToValue() const OVERRIDE {
+ DictionaryValue* dict = new DictionaryValue;
+ dict->Set("source_dependency", source_.ToValue());
+ dict->SetBoolean("not_reusable", not_reusable_);
+ return dict;
+ }
+
+ private:
+ const NetLog::Source source_;
+ const bool not_reusable_;
+};
+
+} // anonymous namespace
+
HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
ClientSocketHandle* connection,
HttpPipelinedConnection::Delegate* delegate,
+ const HostPortPair& origin,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
const BoundNetLog& net_log,
@@ -29,7 +73,8 @@ HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
connection_(connection),
used_ssl_config_(used_ssl_config),
used_proxy_info_(used_proxy_info),
- net_log_(net_log),
+ net_log_(BoundNetLog::Make(net_log.net_log(),
+ NetLog::SOURCE_HTTP_PIPELINED_CONNECTION)),
was_npn_negotiated_(was_npn_negotiated),
protocol_negotiated_(protocol_negotiated),
read_buf_(new GrowableIOBuffer()),
@@ -48,6 +93,10 @@ HttpPipelinedConnectionImpl::HttpPipelinedConnectionImpl(
ALLOW_THIS_IN_INITIALIZER_LIST(read_io_callback_(
this, &HttpPipelinedConnectionImpl::OnReadIOCallback)) {
CHECK(connection_.get());
+ net_log_.BeginEvent(
+ NetLog::TYPE_HTTP_PIPELINED_CONNECTION,
+ make_scoped_refptr(new NetLogStringParameter(
+ "host_and_port", origin.ToString())));
}
HttpPipelinedConnectionImpl::~HttpPipelinedConnectionImpl() {
@@ -63,6 +112,7 @@ HttpPipelinedConnectionImpl::~HttpPipelinedConnectionImpl() {
connection_->socket()->Disconnect();
}
connection_->Reset();
+ net_log_.EndEvent(NetLog::TYPE_HTTP_PIPELINED_CONNECTION, NULL);
}
HttpPipelinedStream* HttpPipelinedConnectionImpl::CreateNewStream() {
@@ -81,7 +131,8 @@ void HttpPipelinedConnectionImpl::InitializeParser(
CHECK(!stream_info_map_[pipeline_id].parser.get());
stream_info_map_[pipeline_id].state = STREAM_BOUND;
stream_info_map_[pipeline_id].parser.reset(new HttpStreamParser(
- connection_.get(), request, read_buf_.get(), net_log));
+ connection_.get(), request, read_buf_.get(), net_log_));
+ stream_info_map_[pipeline_id].source = net_log.source();
// In case our first stream doesn't SendRequest() immediately, we should still
// allow others to use this pipeline.
@@ -237,6 +288,11 @@ int HttpPipelinedConnectionImpl::DoSendComplete(int result) {
request_order_.push(active_send_request_->pipeline_id);
stream_info_map_[active_send_request_->pipeline_id].state = STREAM_SENT;
+ net_log_.AddEvent(
+ NetLog::TYPE_HTTP_PIPELINED_CONNECTION_SENT_REQUEST,
+ make_scoped_refptr(new NetLogSourceParameter(
+ "source_dependency",
+ stream_info_map_[active_send_request_->pipeline_id].source)));
if (result == ERR_SOCKET_NOT_CONNECTED && completed_one_request_) {
result = ERR_PIPELINE_EVICTION;
@@ -428,7 +484,7 @@ int HttpPipelinedConnectionImpl::DoReadHeadersComplete(int result) {
usable_ = false;
}
- CheckHeadersForPipelineCompatibility(result, active_read_id_);
+ CheckHeadersForPipelineCompatibility(active_read_id_, result);
if (!read_still_on_call_stack_) {
QueueUserCallback(active_read_id_,
@@ -485,6 +541,10 @@ int HttpPipelinedConnectionImpl::DoEvictPendingReadHeaders(int result) {
void HttpPipelinedConnectionImpl::Close(int pipeline_id,
bool not_reusable) {
CHECK(ContainsKey(stream_info_map_, pipeline_id));
+ net_log_.AddEvent(
+ NetLog::TYPE_HTTP_PIPELINED_CONNECTION_STREAM_CLOSED,
+ make_scoped_refptr(new StreamClosedParameters(
+ stream_info_map_[pipeline_id].source, not_reusable)));
switch (stream_info_map_[pipeline_id].state) {
case STREAM_CREATED:
stream_info_map_[pipeline_id].state = STREAM_UNUSED;
@@ -631,8 +691,8 @@ void HttpPipelinedConnectionImpl::Drain(HttpPipelinedStream* stream,
}
void HttpPipelinedConnectionImpl::CheckHeadersForPipelineCompatibility(
- int result,
- int pipeline_id) {
+ int pipeline_id,
+ int result) {
if (result < OK) {
switch (result) {
// TODO(simonjam): Ignoring specific errors like this may not work.
@@ -643,23 +703,55 @@ void HttpPipelinedConnectionImpl::CheckHeadersForPipelineCompatibility(
break;
default:
- delegate_->OnPipelineFeedback(this, PIPELINE_SOCKET_ERROR);
+ ReportPipelineFeedback(pipeline_id, PIPELINE_SOCKET_ERROR);
return;
}
}
HttpResponseInfo* info = GetResponseInfo(pipeline_id);
const HttpVersion required_version(1, 1);
if (info->headers->GetParsedHttpVersion() < required_version) {
- delegate_->OnPipelineFeedback(this, OLD_HTTP_VERSION);
+ ReportPipelineFeedback(pipeline_id, OLD_HTTP_VERSION);
return;
}
if (!info->headers->IsKeepAlive() || !CanFindEndOfResponse(pipeline_id)) {
usable_ = false;
- delegate_->OnPipelineFeedback(this, MUST_CLOSE_CONNECTION);
+ ReportPipelineFeedback(pipeline_id, MUST_CLOSE_CONNECTION);
return;
}
// TODO(simonjam): We should also check for, and work around, authentication.
- delegate_->OnPipelineFeedback(this, OK);
+ ReportPipelineFeedback(pipeline_id, OK);
+}
+
+void HttpPipelinedConnectionImpl::ReportPipelineFeedback(int pipeline_id,
+ Feedback feedback) {
+ std::string feedback_str;
+ switch (feedback) {
+ case OK:
+ feedback_str = "OK";
+ break;
+
+ case PIPELINE_SOCKET_ERROR:
+ feedback_str = "PIPELINE_SOCKET_ERROR";
+ break;
+
+ case OLD_HTTP_VERSION:
+ feedback_str = "OLD_HTTP_VERSION";
+ break;
+
+ case MUST_CLOSE_CONNECTION:
+ feedback_str = "MUST_CLOSE_CONNECTION";
+ break;
+
+ default:
+ NOTREACHED();
+ feedback_str = "UNKNOWN";
+ break;
+ }
+ net_log_.AddEvent(
+ NetLog::TYPE_HTTP_PIPELINED_CONNECTION_RECEIVED_HEADERS,
+ make_scoped_refptr(new ReceivedHeadersParameters(
+ stream_info_map_[pipeline_id].source, feedback_str)));
+ delegate_->OnPipelineFeedback(this, feedback);
}
void HttpPipelinedConnectionImpl::QueueUserCallback(
diff --git a/net/http/http_pipelined_connection_impl.h b/net/http/http_pipelined_connection_impl.h
index 4fd0538..d0d62d0 100644
--- a/net/http/http_pipelined_connection_impl.h
+++ b/net/http/http_pipelined_connection_impl.h
@@ -28,6 +28,7 @@ namespace net {
class ClientSocketHandle;
class GrowableIOBuffer;
+class HostPortPair;
class HttpNetworkSession;
class HttpRequestHeaders;
class HttpResponseInfo;
@@ -47,6 +48,7 @@ class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl
public:
HttpPipelinedConnectionImpl(ClientSocketHandle* connection,
Delegate* delegate,
+ const HostPortPair& origin,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
const BoundNetLog& net_log,
@@ -175,6 +177,7 @@ class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl
OldCompletionCallback* read_headers_callback;
OldCompletionCallback* pending_user_callback;
StreamState state;
+ NetLog::Source source;
};
typedef std::map<int, StreamInfo> StreamInfoMap;
@@ -258,9 +261,12 @@ class NET_EXPORT_PRIVATE HttpPipelinedConnectionImpl
// HttpPipelinedSockets indicates the connection was suddenly closed.
int DoEvictPendingReadHeaders(int result);
- // Reports back to |delegate_| whether pipelining will work. This is called
- // every time we receive headers.
- void CheckHeadersForPipelineCompatibility(int result, int pipeline_id);
+ // Determines if the response headers indicate pipelining will work. This is
+ // called every time we receive headers.
+ void CheckHeadersForPipelineCompatibility(int pipeline_id, int result);
+
+ // Reports back to |delegate_| whether pipelining will work.
+ void ReportPipelineFeedback(int pipeline_id, Feedback feedback);
// Posts a task to fire the user's callback in response to SendRequest() or
// ReadResponseHeaders() completing on an underlying parser. This might be
diff --git a/net/http/http_pipelined_connection_impl_unittest.cc b/net/http/http_pipelined_connection_impl_unittest.cc
index 12a7d05..81d1391 100644
--- a/net/http/http_pipelined_connection_impl_unittest.cc
+++ b/net/http/http_pipelined_connection_impl_unittest.cc
@@ -68,7 +68,8 @@ class HttpPipelinedConnectionImplTest : public testing::Test {
public:
HttpPipelinedConnectionImplTest()
: histograms_("a"),
- pool_(1, 1, &histograms_, &factory_) {
+ pool_(1, 1, &histograms_, &factory_),
+ origin_("host", 123) {
}
void TearDown() {
@@ -88,10 +89,9 @@ class HttpPipelinedConnectionImplTest : public testing::Test {
ClientSocketHandle* connection = new ClientSocketHandle;
connection->Init("a", params, MEDIUM, CompletionCallback(), &pool_,
BoundNetLog());
- pipeline_.reset(
- new HttpPipelinedConnectionImpl(connection, &delegate_, ssl_config_,
- proxy_info_, BoundNetLog(), false,
- SSLClientSocket::kProtoUnknown));
+ pipeline_.reset(new HttpPipelinedConnectionImpl(
+ connection, &delegate_, origin_, ssl_config_, proxy_info_,
+ BoundNetLog(), false, SSLClientSocket::kProtoUnknown));
}
HttpRequestInfo* GetRequestInfo(const std::string& filename) {
@@ -145,6 +145,7 @@ class HttpPipelinedConnectionImplTest : public testing::Test {
MockTransportClientSocketPool pool_;
scoped_refptr<DeterministicSocketData> data_;
+ HostPortPair origin_;
SSLConfig ssl_config_;
ProxyInfo proxy_info_;
NiceMock<MockPipelineDelegate> delegate_;
diff --git a/net/http/http_pipelined_host.h b/net/http/http_pipelined_host.h
index c41289e..14c0f09 100644
--- a/net/http/http_pipelined_host.h
+++ b/net/http/http_pipelined_host.h
@@ -10,6 +10,10 @@
#include "net/http/http_pipelined_connection.h"
#include "net/http/http_pipelined_host_capability.h"
+namespace base {
+class Value;
+}
+
namespace net {
class BoundNetLog;
@@ -73,6 +77,11 @@ class NET_EXPORT_PRIVATE HttpPipelinedHost {
// Returns the host and port associated with this class.
virtual const HostPortPair& origin() const = 0;
+
+ // Creates a Value summary of this host's pipelines. Caller assumes
+ // ownership of the returned Value.
+ virtual base::Value* PipelineInfoToValue() const = 0;
+
};
} // namespace net
diff --git a/net/http/http_pipelined_host_impl.cc b/net/http/http_pipelined_host_impl.cc
index 43fab69..4927447 100644
--- a/net/http/http_pipelined_host_impl.cc
+++ b/net/http/http_pipelined_host_impl.cc
@@ -5,9 +5,14 @@
#include "net/http/http_pipelined_host_impl.h"
#include "base/stl_util.h"
+#include "base/values.h"
#include "net/http/http_pipelined_connection_impl.h"
#include "net/http/http_pipelined_stream.h"
+using base::DictionaryValue;
+using base::ListValue;
+using base::Value;
+
namespace net {
// TODO(simonjam): Run experiments to see what value minimizes evictions without
@@ -20,12 +25,13 @@ class HttpPipelinedConnectionImplFactory :
HttpPipelinedConnection* CreateNewPipeline(
ClientSocketHandle* connection,
HttpPipelinedConnection::Delegate* delegate,
+ const HostPortPair& origin,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
const BoundNetLog& net_log,
bool was_npn_negotiated,
SSLClientSocket::NextProto protocol_negotiated) OVERRIDE {
- return new HttpPipelinedConnectionImpl(connection, delegate,
+ return new HttpPipelinedConnectionImpl(connection, delegate, origin,
used_ssl_config, used_proxy_info,
net_log, was_npn_negotiated,
protocol_negotiated);
@@ -61,7 +67,7 @@ HttpPipelinedStream* HttpPipelinedHostImpl::CreateStreamOnNewPipeline(
return NULL;
}
HttpPipelinedConnection* pipeline = factory_->CreateNewPipeline(
- connection, this, used_ssl_config, used_proxy_info, net_log,
+ connection, this, origin_, used_ssl_config, used_proxy_info, net_log,
was_npn_negotiated, protocol_negotiated);
PipelineInfo info;
pipelines_.insert(std::make_pair(pipeline, info));
@@ -190,6 +196,22 @@ void HttpPipelinedHostImpl::NotifyAllPipelinesHaveCapacity() {
}
}
+Value* HttpPipelinedHostImpl::PipelineInfoToValue() const {
+ ListValue* list_value = new ListValue();
+ for (PipelineInfoMap::const_iterator it = pipelines_.begin();
+ it != pipelines_.end(); ++it) {
+ DictionaryValue* pipeline_dict = new DictionaryValue;
+ pipeline_dict->SetString("host", origin_.ToString());
+ pipeline_dict->SetInteger("depth", it->first->depth());
+ pipeline_dict->SetInteger("capacity", GetPipelineCapacity());
+ pipeline_dict->SetBoolean("usable", it->first->usable());
+ pipeline_dict->SetBoolean("active", it->first->active());
+ pipeline_dict->SetInteger("source_id", it->first->net_log().source().id);
+ list_value->Append(pipeline_dict);
+ }
+ return list_value;
+}
+
HttpPipelinedHostImpl::PipelineInfo::PipelineInfo()
: num_successes(0) {
}
diff --git a/net/http/http_pipelined_host_impl.h b/net/http/http_pipelined_host_impl.h
index 6fe088a..926ccb8 100644
--- a/net/http/http_pipelined_host_impl.h
+++ b/net/http/http_pipelined_host_impl.h
@@ -17,6 +17,10 @@
#include "net/http/http_pipelined_host.h"
#include "net/http/http_pipelined_host_capability.h"
+namespace base {
+class Value;
+}
+
namespace net {
class BoundNetLog;
@@ -64,6 +68,10 @@ class NET_EXPORT_PRIVATE HttpPipelinedHostImpl
virtual const HostPortPair& origin() const OVERRIDE;
+ // Creates a Value summary of this host's |pipelines_|. Caller assumes
+ // ownership of the returned Value.
+ virtual base::Value* PipelineInfoToValue() const OVERRIDE;
+
// Returns the maximum number of in-flight pipelined requests we'll allow on a
// single connection.
static int max_pipeline_depth() { return 3; }
diff --git a/net/http/http_pipelined_host_impl_unittest.cc b/net/http/http_pipelined_host_impl_unittest.cc
index 62fc36f..28850e4 100644
--- a/net/http/http_pipelined_host_impl_unittest.cc
+++ b/net/http/http_pipelined_host_impl_unittest.cc
@@ -37,9 +37,10 @@ class MockHostDelegate : public HttpPipelinedHost::Delegate {
class MockPipelineFactory : public HttpPipelinedConnection::Factory {
public:
- MOCK_METHOD7(CreateNewPipeline, HttpPipelinedConnection*(
+ MOCK_METHOD8(CreateNewPipeline, HttpPipelinedConnection*(
ClientSocketHandle* connection,
HttpPipelinedConnection::Delegate* delegate,
+ const HostPortPair& origin,
const SSLConfig& used_ssl_config,
const ProxyInfo& used_proxy_info,
const BoundNetLog& net_log,
@@ -79,6 +80,8 @@ class MockPipeline : public HttpPipelinedConnection {
bool active_;
};
+MATCHER_P(MatchesOrigin, expected, "") { return expected.Equals(arg); }
+
class HttpPipelinedHostImplTest : public testing::Test {
public:
HttpPipelinedHostImplTest()
@@ -97,6 +100,7 @@ class HttpPipelinedHostImplTest : public testing::Test {
MockPipeline* AddTestPipeline(int depth, bool usable, bool active) {
MockPipeline* pipeline = new MockPipeline(depth, usable, active);
EXPECT_CALL(*factory_, CreateNewPipeline(kDummyConnection, host_.get(),
+ MatchesOrigin(origin_),
Ref(ssl_config_), Ref(proxy_info_),
Ref(net_log_), true,
SSLClientSocket::kProtoSPDY2))
diff --git a/net/http/http_pipelined_host_pool.cc b/net/http/http_pipelined_host_pool.cc
index 7c3ee6a..116c5bb 100644
--- a/net/http/http_pipelined_host_pool.cc
+++ b/net/http/http_pipelined_host_pool.cc
@@ -6,10 +6,14 @@
#include "base/logging.h"
#include "base/stl_util.h"
+#include "base/values.h"
#include "net/http/http_pipelined_host_capability.h"
#include "net/http/http_pipelined_host_impl.h"
#include "net/http/http_server_properties.h"
+using base::ListValue;
+using base::Value;
+
namespace net {
class HttpPipelinedHostImplFactory : public HttpPipelinedHost::Factory {
@@ -121,4 +125,14 @@ void HttpPipelinedHostPool::OnHostDeterminedCapability(
http_server_properties_->SetPipelineCapability(host->origin(), capability);
}
+Value* HttpPipelinedHostPool::PipelineInfoToValue() const {
+ ListValue* list = new ListValue();
+ for (HostMap::const_iterator it = host_map_.begin();
+ it != host_map_.end(); ++it) {
+ Value* value = it->second->PipelineInfoToValue();
+ list->Append(value);
+ }
+ return list;
+}
+
} // namespace net
diff --git a/net/http/http_pipelined_host_pool.h b/net/http/http_pipelined_host_pool.h
index 98a9bd2..7cebbfe 100644
--- a/net/http/http_pipelined_host_pool.h
+++ b/net/http/http_pipelined_host_pool.h
@@ -14,6 +14,10 @@
#include "net/http/http_pipelined_host.h"
#include "net/http/http_pipelined_host_capability.h"
+namespace base {
+class Value;
+}
+
namespace net {
class HostPortPair;
@@ -72,6 +76,10 @@ class NET_EXPORT_PRIVATE HttpPipelinedHostPool
HttpPipelinedHost* host,
HttpPipelinedHostCapability capability) OVERRIDE;
+ // Creates a Value summary of this pool's |host_map_|. Caller assumes
+ // ownership of the returned Value.
+ base::Value* PipelineInfoToValue() const;
+
private:
typedef std::map<const HostPortPair, HttpPipelinedHost*> HostMap;
diff --git a/net/http/http_pipelined_host_pool_unittest.cc b/net/http/http_pipelined_host_pool_unittest.cc
index 27f9bd4..beb5807 100644
--- a/net/http/http_pipelined_host_pool_unittest.cc
+++ b/net/http/http_pipelined_host_pool_unittest.cc
@@ -56,6 +56,7 @@ class MockHost : public HttpPipelinedHost {
SSLClientSocket::NextProto protocol_negotiated));
MOCK_METHOD0(CreateStreamOnExistingPipeline, HttpPipelinedStream*());
MOCK_CONST_METHOD0(IsExistingPipelineAvailable, bool());
+ MOCK_CONST_METHOD0(PipelineInfoToValue, base::Value*());
virtual const HostPortPair& origin() const OVERRIDE { return origin_; }
diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h
index 0db35af..21e9379 100644
--- a/net/http/http_stream_factory.h
+++ b/net/http/http_stream_factory.h
@@ -19,6 +19,10 @@
class GURL;
+namespace base {
+class Value;
+}
+
namespace net {
class AuthCredentials;
@@ -179,6 +183,11 @@ class NET_EXPORT HttpStreamFactory {
virtual void AddTLSIntolerantServer(const HostPortPair& server) = 0;
virtual bool IsTLSIntolerantServer(const HostPortPair& server) const = 0;
+ // If pipelining is supported, creates a Value summary of the currently active
+ // pipelines. Caller assumes ownership of the returned value. Otherwise,
+ // returns an empty Value.
+ virtual base::Value* PipelineInfoToValue() const = 0;
+
// Static settings
// Reset all static settings to initialized values. Used to init test suite.
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc
index d98ab0f..9ef81b1 100644
--- a/net/http/http_stream_factory_impl.cc
+++ b/net/http/http_stream_factory_impl.cc
@@ -127,6 +127,10 @@ bool HttpStreamFactoryImpl::IsTLSIntolerantServer(
return ContainsKey(tls_intolerant_servers_, server);
}
+base::Value* HttpStreamFactoryImpl::PipelineInfoToValue() const {
+ return http_pipelined_host_pool_.PipelineInfoToValue();
+}
+
bool HttpStreamFactoryImpl::GetAlternateProtocolRequestFor(
const GURL& original_url,
GURL* alternate_url) const {
diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h
index 7b30777..ea895db 100644
--- a/net/http/http_stream_factory_impl.h
+++ b/net/http/http_stream_factory_impl.h
@@ -44,6 +44,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl :
const BoundNetLog& net_log) OVERRIDE;
virtual void AddTLSIntolerantServer(const HostPortPair& server) OVERRIDE;
virtual bool IsTLSIntolerantServer(const HostPortPair& server) const OVERRIDE;
+ virtual base::Value* PipelineInfoToValue() const OVERRIDE;
// HttpPipelinedHostPool::Delegate interface
virtual void OnHttpPipelinedHostHasAdditionalCapacity(