summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/dom_ui/net_internals_ui.cc33
-rw-r--r--chrome/browser/resources/net_internals/dataview.js14
-rw-r--r--chrome/browser/resources/net_internals/index.html14
-rw-r--r--chrome/browser/resources/net_internals/main.css1
-rw-r--r--chrome/browser/resources/net_internals/main.js27
-rw-r--r--chrome/browser/resources/net_internals/spdyview.js87
-rw-r--r--net/base/net_log.cc11
-rw-r--r--net/base/net_log.h4
-rw-r--r--net/http/http_network_session.cc4
-rw-r--r--net/http/http_network_session.h4
-rw-r--r--net/socket/client_socket_pool_manager.cc1
-rw-r--r--net/spdy/spdy_session.cc30
-rw-r--r--net/spdy/spdy_session.h4
-rw-r--r--net/spdy/spdy_session_pool.cc16
-rw-r--r--net/spdy/spdy_session_pool.h4
15 files changed, 238 insertions, 16 deletions
diff --git a/chrome/browser/dom_ui/net_internals_ui.cc b/chrome/browser/dom_ui/net_internals_ui.cc
index ffdb9a1..93e1262 100644
--- a/chrome/browser/dom_ui/net_internals_ui.cc
+++ b/chrome/browser/dom_ui/net_internals_ui.cc
@@ -45,11 +45,7 @@
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_network_session.h"
-#include "net/http/http_proxy_client_socket_pool.h"
#include "net/proxy/proxy_service.h"
-#include "net/socket/socks_client_socket_pool.h"
-#include "net/socket/ssl_client_socket_pool.h"
-#include "net/socket/tcp_client_socket_pool.h"
#include "net/url_request/url_request_context.h"
#ifdef OS_WIN
#include "chrome/browser/net/service_providers_win.h"
@@ -57,11 +53,6 @@
namespace {
-// Formats |t| as a decimal number, in milliseconds.
-std::string TickCountToString(const base::TimeTicks& t) {
- return base::Int64ToString((t - base::TimeTicks()).InMilliseconds());
-}
-
// Returns the HostCache for |context|'s primary HostResolver, or NULL if
// there is none.
net::HostCache* GetHostResolverCache(URLRequestContext* context) {
@@ -214,6 +205,7 @@ class NetInternalsMessageHandler::IOThreadImpl
void OnStartConnectionTests(const ListValue* list);
void OnGetHttpCacheInfo(const ListValue* list);
void OnGetSocketPoolInfo(const ListValue* list);
+ void OnGetSpdySessionInfo(const ListValue* list);
#ifdef OS_WIN
void OnGetServiceProviders(const ListValue* list);
#endif
@@ -403,6 +395,9 @@ void NetInternalsMessageHandler::RegisterMessages() {
dom_ui_->RegisterMessageCallback(
"getSocketPoolInfo",
proxy_->CreateCallback(&IOThreadImpl::OnGetSocketPoolInfo));
+ dom_ui_->RegisterMessageCallback(
+ "getSpdySessionInfo",
+ proxy_->CreateCallback(&IOThreadImpl::OnGetSpdySessionInfo));
#ifdef OS_WIN
dom_ui_->RegisterMessageCallback(
"getServiceProviders",
@@ -610,6 +605,7 @@ void NetInternalsMessageHandler::IOThreadImpl::OnRendererReady(
OnGetHostResolverInfo(NULL);
OnGetHttpCacheInfo(NULL);
OnGetSocketPoolInfo(NULL);
+ OnGetSpdySessionInfo(NULL);
#ifdef OS_WIN
OnGetServiceProviders(NULL);
#endif
@@ -654,7 +650,8 @@ void NetInternalsMessageHandler::IOThreadImpl::OnGetBadProxies(
DictionaryValue* dict = new DictionaryValue();
dict->SetString("proxy_uri", proxy_uri);
- dict->SetString("bad_until", TickCountToString(retry_info.bad_until));
+ dict->SetString("bad_until",
+ net::NetLog::TickCountToString(retry_info.bad_until));
dict_list->Append(dict);
}
@@ -715,7 +712,8 @@ void NetInternalsMessageHandler::IOThreadImpl::OnGetHostResolverInfo(
entry_dict->SetString("hostname", key.hostname);
entry_dict->SetInteger("address_family",
static_cast<int>(key.address_family));
- entry_dict->SetString("expiration", TickCountToString(entry->expiration));
+ entry_dict->SetString("expiration",
+ net::NetLog::TickCountToString(entry->expiration));
if (entry->error != net::OK) {
entry_dict->SetInteger("error", entry->error);
@@ -837,6 +835,19 @@ void NetInternalsMessageHandler::IOThreadImpl::OnGetSocketPoolInfo(
CallJavascriptFunction(L"g_browser.receivedSocketPoolInfo", socket_pool_info);
}
+void NetInternalsMessageHandler::IOThreadImpl::OnGetSpdySessionInfo(
+ const ListValue* list) {
+ net::HttpNetworkSession* http_network_session =
+ GetHttpNetworkSession(context_getter_->GetURLRequestContext());
+
+ Value* spdy_info = NULL;
+ if (http_network_session) {
+ spdy_info = http_network_session->SpdySessionPoolInfoToValue();
+ }
+
+ CallJavascriptFunction(L"g_browser.receivedSpdySessionInfo", spdy_info);
+}
+
#ifdef OS_WIN
void NetInternalsMessageHandler::IOThreadImpl::OnGetServiceProviders(
const ListValue* list) {
diff --git a/chrome/browser/resources/net_internals/dataview.js b/chrome/browser/resources/net_internals/dataview.js
index 58aaccf..2138a83 100644
--- a/chrome/browser/resources/net_internals/dataview.js
+++ b/chrome/browser/resources/net_internals/dataview.js
@@ -222,6 +222,20 @@ DataView.prototype.onUpdateAllCompleted = function(data) {
this.appendSocketPoolsAsText_(text, data.socketPoolInfo);
+ text.push('');
+ text.push('----------------------------------------------');
+ text.push(' SPDY Sessions');
+ text.push('----------------------------------------------');
+ text.push('');
+
+ if (data.spdySessionInfo == null || data.spdySessionInfo.length == 0) {
+ text.push('None');
+ } else {
+ var spdyTablePrinter =
+ SpdyView.createSessionTablePrinter(data.spdySessionInfo);
+ text.push(spdyTablePrinter.toText(2));
+ }
+
if (g_browser.isPlatformWindows()) {
text.push('');
text.push('----------------------------------------------');
diff --git a/chrome/browser/resources/net_internals/index.html b/chrome/browser/resources/net_internals/index.html
index 1ab90e6..483d932 100644
--- a/chrome/browser/resources/net_internals/index.html
+++ b/chrome/browser/resources/net_internals/index.html
@@ -25,6 +25,7 @@ found in the LICENSE file.
<script src="proxyview.js"></script>
<script src="socketpoolwrapper.js"></script>
<script src="socketsview.js"></script>
+ <script src="spdyview.js"></script>
<script src="serviceprovidersview.js"></script>
</head>
<body onload="onLoaded()">
@@ -36,6 +37,7 @@ found in the LICENSE file.
<li><a href="#events" id=eventsTab>Events</a></li>
<li><a href="#dns" id=dnsTab>DNS</a></li>
<li><a href="#sockets" id=socketsTab>Sockets</a></li>
+ <li><a href="#spdy" id=spdyTab>SPDY</a></li>
<li><a href="#httpCache" id=httpCacheTab>HTTP Cache</a></li>
<!-- Tab is only shown on Windows -->
<li><a href="#serviceProviders" id=serviceProvidersTab style="display: none;">SPIs</a></li>
@@ -131,6 +133,18 @@ found in the LICENSE file.
</div>
</p>
</div>
+ <div id=spdyTabContent>
+ <h4>SPDY sessions</h4>
+ <!-- Only one of these two are shown -->
+ <span id=spdySessionNoneSpan>None</span>
+ <span id=spdySessionLinkSpan style="display: none;">
+ <a href='#events&q=type:SPDY_SESSION%20is:active'>View live SPDY sessions</a>
+ </span>
+ <p>
+ <div id=spdySessionDiv>
+ </div>
+ </p>
+ </div>
<div id=httpCacheTabContent>
<h4>Entries</h4>
<a href="chrome://view-http-cache" target=_blank>Explore cache entries</a>
diff --git a/chrome/browser/resources/net_internals/main.css b/chrome/browser/resources/net_internals/main.css
index 0102cfb..7861a35 100644
--- a/chrome/browser/resources/net_internals/main.css
+++ b/chrome/browser/resources/net_internals/main.css
@@ -202,6 +202,7 @@ body {
#dataTabContent,
#dnsTabContent,
#socketsTabContent,
+#spdyTabContent,
#serviceProvidersTabContent,
#testTabContent {
overflow: auto;
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index 50102c6..1702085 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -89,6 +89,11 @@ function onLoaded() {
"socketPoolDiv",
"socketPoolGroupsDiv");
+ var spdyView = new SpdyView("spdyTabContent",
+ "spdySessionNoneSpan",
+ "spdySessionLinkSpan",
+ "spdySessionDiv");
+
var serviceView;
if (g_browser.isPlatformWindows()) {
@@ -107,6 +112,7 @@ function onLoaded() {
categoryTabSwitcher.addTab('proxyTab', proxyView, false);
categoryTabSwitcher.addTab('dnsTab', dnsView, false);
categoryTabSwitcher.addTab('socketsTab', socketsView, false);
+ categoryTabSwitcher.addTab('spdyTab', spdyView, false);
categoryTabSwitcher.addTab('httpCacheTab', httpCacheView, false);
categoryTabSwitcher.addTab('dataTab', dataView, false);
if (g_browser.isPlatformWindows())
@@ -167,6 +173,9 @@ function BrowserBridge() {
this.pollableDataHelpers_.socketPoolInfo =
new PollableDataHelper('onSocketPoolInfoChanged',
this.sendGetSocketPoolInfo.bind(this));
+ this.pollableDataHelpers_.spdySessionInfo =
+ new PollableDataHelper('onSpdySessionInfoChanged',
+ this.sendGetSpdySessionInfo.bind(this));
if (this.isPlatformWindows()) {
this.pollableDataHelpers_.serviceProviders =
new PollableDataHelper('onServiceProvidersChanged',
@@ -275,6 +284,10 @@ BrowserBridge.prototype.sendGetSocketPoolInfo = function() {
chrome.send('getSocketPoolInfo');
};
+BrowserBridge.prototype.sendGetSpdySessionInfo = function() {
+ chrome.send('getSpdySessionInfo');
+};
+
BrowserBridge.prototype.sendGetServiceProviders = function() {
chrome.send('getServiceProviders');
};
@@ -354,6 +367,10 @@ BrowserBridge.prototype.receivedSocketPoolInfo = function(socketPoolInfo) {
this.pollableDataHelpers_.socketPoolInfo.update(socketPoolInfo);
};
+BrowserBridge.prototype.receivedSpdySessionInfo = function(spdySessionInfo) {
+ this.pollableDataHelpers_.spdySessionInfo.update(spdySessionInfo);
+};
+
BrowserBridge.prototype.receivedServiceProviders = function(serviceProviders) {
this.pollableDataHelpers_.serviceProviders.update(serviceProviders);
};
@@ -475,6 +492,16 @@ BrowserBridge.prototype.addSocketPoolInfoObserver = function(observer) {
};
/**
+ * Adds a listener of the SPDY info. |observer| will be called back
+ * when data is received, through:
+ *
+ * observer.onSpdySessionInfoChanged(spdySessionInfo)
+ */
+BrowserBridge.prototype.addSpdySessionInfoObserver = function(observer) {
+ this.pollableDataHelpers_.spdySessionInfo.addObserver(observer);
+};
+
+/**
* Adds a listener of the service providers info. |observer| will be called
* back when data is received, through:
*
diff --git a/chrome/browser/resources/net_internals/spdyview.js b/chrome/browser/resources/net_internals/spdyview.js
new file mode 100644
index 0000000..e0d0bd2
--- /dev/null
+++ b/chrome/browser/resources/net_internals/spdyview.js
@@ -0,0 +1,87 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/**
+ * This view displays a summary of the state of each SPDY sessions, and
+ * has links to display them in the events tab.
+ *
+ * @constructor
+ */
+function SpdyView(mainBoxId, spdySessionNoneSpanId, spdySessionLinkSpanId,
+ spdySessionDivId) {
+ DivView.call(this, mainBoxId);
+ g_browser.addSpdySessionInfoObserver(this);
+
+ this.spdySessionNoneSpan_ = document.getElementById(spdySessionNoneSpanId);
+ this.spdySessionLinkSpan_ = document.getElementById(spdySessionLinkSpanId);
+ this.spdySessionDiv_ = document.getElementById(spdySessionDivId);
+}
+
+inherits(SpdyView, DivView);
+
+/**
+ * If |spdySessionInfo| is not null, displays a single table with information
+ * on each SPDY session. Otherwise, displays "None".
+ */
+SpdyView.prototype.onSpdySessionInfoChanged = function(spdySessionInfo) {
+ this.spdySessionDiv_.innerHTML = '';
+
+ var hasNoSession = (spdySessionInfo == null || spdySessionInfo.length == 0);
+ setNodeDisplay(this.spdySessionNoneSpan_, hasNoSession);
+ setNodeDisplay(this.spdySessionLinkSpan_, !hasNoSession);
+
+ if (hasNoSession)
+ return;
+
+ var tablePrinter = SpdyView.createSessionTablePrinter(spdySessionInfo);
+ tablePrinter.toHTML(this.spdySessionDiv_, 'styledTable');
+};
+
+/**
+ * Creates a table printer to print out the state of list of SPDY sessions.
+ */
+SpdyView.createSessionTablePrinter = function(spdySessions) {
+ var tablePrinter = new TablePrinter();
+ tablePrinter.addHeaderCell('Host');
+ tablePrinter.addHeaderCell('Proxy');
+ tablePrinter.addHeaderCell('ID');
+ tablePrinter.addHeaderCell('Active streams');
+ tablePrinter.addHeaderCell('Unclaimed pushed');
+ tablePrinter.addHeaderCell('Max');
+ tablePrinter.addHeaderCell('Initiated');
+ tablePrinter.addHeaderCell('Pushed');
+ tablePrinter.addHeaderCell('Pushed and claimed');
+ tablePrinter.addHeaderCell('Abandoned');
+ tablePrinter.addHeaderCell('Received frames');
+ tablePrinter.addHeaderCell('Secure');
+ tablePrinter.addHeaderCell('Sent settings');
+ tablePrinter.addHeaderCell('Received settings');
+ tablePrinter.addHeaderCell('Error');
+
+ for (var i = 0; i < spdySessions.length; i++) {
+ var session = spdySessions[i];
+ tablePrinter.addRow();
+
+ tablePrinter.addCell(session.host_port_pair);
+ tablePrinter.addCell(session.proxy);
+
+ var idCell = tablePrinter.addCell(session.source_id);
+ idCell.link = '#events&q=id:' + session.source_id;
+
+ tablePrinter.addCell(session.active_streams);
+ tablePrinter.addCell(session.unclaimed_pushed_streams);
+ tablePrinter.addCell(session.max_concurrent_streams);
+ tablePrinter.addCell(session.streams_initiated_count);
+ tablePrinter.addCell(session.streams_pushed_count);
+ tablePrinter.addCell(session.streams_pushed_and_claimed_count);
+ tablePrinter.addCell(session.streams_abandoned_count);
+ tablePrinter.addCell(session.frames_received);
+ tablePrinter.addCell(session.is_secure);
+ tablePrinter.addCell(session.sent_settings);
+ tablePrinter.addCell(session.received_settings);
+ tablePrinter.addCell(session.error);
+ }
+ return tablePrinter;
+};
+
diff --git a/net/base/net_log.cc b/net/base/net_log.cc
index 2cc149f..f9f31c7 100644
--- a/net/base/net_log.cc
+++ b/net/base/net_log.cc
@@ -19,6 +19,12 @@ Value* NetLog::Source::ToValue() const {
}
// static
+std::string NetLog::TickCountToString(const base::TimeTicks& time) {
+ int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
+ return base::Int64ToString(delta_time);
+}
+
+// static
const char* NetLog::EventTypeToString(EventType event) {
switch (event) {
#define EVENT_TYPE(label) case TYPE_ ## label: return #label;
@@ -71,10 +77,7 @@ Value* NetLog::EntryToDictionaryValue(net::NetLog::EventType type,
bool use_strings) {
DictionaryValue* entry_dict = new DictionaryValue();
- // Set the entry time. (Note that we send it as a string since integers
- // might overflow).
- int64 delta_time = (time - base::TimeTicks()).InMilliseconds();
- entry_dict->SetString("time", base::Int64ToString(delta_time));
+ entry_dict->SetString("time", TickCountToString(time));
// Set the entry source.
DictionaryValue* source_dict = new DictionaryValue();
diff --git a/net/base/net_log.h b/net/base/net_log.h
index c97eb1a..f240105 100644
--- a/net/base/net_log.h
+++ b/net/base/net_log.h
@@ -130,6 +130,10 @@ class NetLog {
// and saving expensive log entries.
virtual LogLevel GetLogLevel() const = 0;
+ // Converts a time to the string format that the NetLog uses to represent
+ // times. Strings are used since integers may overflow.
+ static std::string TickCountToString(const base::TimeTicks& time);
+
// Returns a C-String symbolic name for |event_type|.
static const char* EventTypeToString(EventType event_type);
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index 4613629..056feaf 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -64,4 +64,8 @@ void HttpNetworkSession::RemoveResponseDrainer(
response_drainers_.erase(drainer);
}
+Value* HttpNetworkSession::SpdySessionPoolInfoToValue() const {
+ return spdy_session_pool_->SpdySessionPoolInfoToValue();
+}
+
} // namespace net
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 0cfe08f..e23ecd6 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -126,6 +126,10 @@ class HttpNetworkSession : public base::RefCounted<HttpNetworkSession>,
return socket_pool_manager_.SocketPoolInfoToValue();
}
+ // Creates a Value summary of the state of the SPDY sessions. The caller is
+ // responsible for deleting the returned value.
+ Value* SpdySessionPoolInfoToValue() const;
+
void FlushSocketPools() {
socket_pool_manager_.FlushSocketPools();
}
diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc
index 264cdf8..0fca83d 100644
--- a/net/socket/client_socket_pool_manager.cc
+++ b/net/socket/client_socket_pool_manager.cc
@@ -41,7 +41,6 @@ static void AddSocketPoolsToList(ListValue* list,
const MapType& socket_pools,
const std::string& type,
bool include_nested_pools) {
- typename MapType::const_iterator socket_pool_it = socket_pools.begin();
for (typename MapType::const_iterator it = socket_pools.begin();
it != socket_pools.end(); it++) {
list->Append(it->second->GetInfoAsValue(it->first.ToString(),
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc
index a360c52..d0ebff9 100644
--- a/net/spdy/spdy_session.cc
+++ b/net/spdy/spdy_session.cc
@@ -839,6 +839,36 @@ void SpdySession::CloseSessionOnError(net::Error err, bool remove_from_pool) {
}
}
+Value* SpdySession::GetInfoAsValue() const {
+ DictionaryValue* dict = new DictionaryValue();
+
+ dict->SetInteger("source_id", net_log_.source().id);
+
+ dict->SetString("host_port_pair", host_port_proxy_pair_.first.ToString());
+ dict->SetString("proxy", host_port_proxy_pair_.second.ToURI());
+
+ dict->SetInteger("active_streams", active_streams_.size());
+
+ dict->SetInteger("unclaimed_pushed_streams",
+ unclaimed_pushed_streams_.size());
+
+ dict->SetBoolean("is_secure", is_secure_);
+
+ dict->SetInteger("error", error_);
+ dict->SetInteger("max_concurrent_streams", max_concurrent_streams_);
+
+ dict->SetInteger("streams_initiated_count", streams_initiated_count_);
+ dict->SetInteger("streams_pushed_count", streams_pushed_count_);
+ dict->SetInteger("streams_pushed_and_claimed_count",
+ streams_pushed_and_claimed_count_);
+ dict->SetInteger("streams_abandoned_count", streams_abandoned_count_);
+ dict->SetInteger("frames_received", frames_received_);
+
+ dict->SetBoolean("sent_settings", sent_settings_);
+ dict->SetBoolean("received_settings", received_settings_);
+ return dict;
+}
+
void SpdySession::ActivateStream(SpdyStream* stream) {
const spdy::SpdyStreamId id = stream->stream_id();
DCHECK(!IsStreamActive(id));
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h
index de5f0e2..f90907d 100644
--- a/net/spdy/spdy_session.h
+++ b/net/spdy/spdy_session.h
@@ -155,6 +155,10 @@ class SpdySession : public base::RefCounted<SpdySession>,
// session pool.
void CloseSessionOnError(net::Error err, bool remove_from_pool);
+ // Retrieves information on the current state of the SPDY session as a
+ // Value. Caller takes possession of the returned value.
+ Value* GetInfoAsValue() const;
+
// Indicates whether the session is being reused after having successfully
// used to send/receive data in the past.
bool IsReused() const {
diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc
index 086fa9f..fe2a310 100644
--- a/net/spdy/spdy_session_pool.cc
+++ b/net/spdy/spdy_session_pool.cc
@@ -5,6 +5,7 @@
#include "net/spdy/spdy_session_pool.h"
#include "base/logging.h"
+#include "base/values.h"
#include "net/http/http_network_session.h"
#include "net/spdy/spdy_session.h"
@@ -109,6 +110,21 @@ void SpdySessionPool::Remove(const scoped_refptr<SpdySession>& session) {
RemoveSessionList(session->host_port_proxy_pair());
}
+Value* SpdySessionPool::SpdySessionPoolInfoToValue() {
+ ListValue* list = new ListValue();
+
+ SpdySessionsMap::const_iterator spdy_session_pool_it = sessions_.begin();
+ for (SpdySessionsMap::const_iterator it = sessions_.begin();
+ it != sessions_.end(); it++) {
+ SpdySessionList* sessions = it->second;
+ for (SpdySessionList::const_iterator session = sessions->begin();
+ session != sessions->end(); session++) {
+ list->Append(session->get()->GetInfoAsValue());
+ }
+ }
+ return list;
+}
+
void SpdySessionPool::OnIPAddressChanged() {
CloseCurrentSessions();
}
diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h
index 49f9e45..6b346f6 100644
--- a/net/spdy/spdy_session_pool.h
+++ b/net/spdy/spdy_session_pool.h
@@ -88,6 +88,10 @@ class SpdySessionPool
// by SpdySession, because otherwise session->state_ is not set to CLOSED.
void Remove(const scoped_refptr<SpdySession>& session);
+ // Creates a Value summary of the state of the spdy session pool. The caller
+ // responsible for deleting the returned value.
+ Value* SpdySessionPoolInfoToValue();
+
// NetworkChangeNotifier::Observer methods:
// We flush all idle sessions and release references to the active ones so