summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/net_internals/main.js
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/resources/net_internals/main.js')
-rw-r--r--chrome/browser/resources/net_internals/main.js374
1 files changed, 163 insertions, 211 deletions
diff --git a/chrome/browser/resources/net_internals/main.js b/chrome/browser/resources/net_internals/main.js
index 8333761..af44622 100644
--- a/chrome/browser/resources/net_internals/main.js
+++ b/chrome/browser/resources/net_internals/main.js
@@ -3,7 +3,7 @@
// found in the LICENSE file.
/**
- * Dictionary of constants (initialized by browser).
+ * Dictionary of constants (initialized by browser, updated on load log).
*/
var LogEventType = null;
var LogEventPhase = null;
@@ -14,6 +14,9 @@ var NetError = null;
var LoadFlag = null;
var AddressFamily = null;
+// Dictionary of all constants, used for saving log files.
+var Constants = null;
+
/**
* Object to communicate between the renderer and the browser.
* @type {!BrowserBridge}
@@ -71,14 +74,17 @@ function onLoaded() {
'hostResolverCacheTTLSuccess',
'hostResolverCacheTTLFailure');
- // Create a view which will display import/export options to control the
+ // Create a view which will display save/load options to control the
// captured data.
var dataView = new DataView('dataTabContent', 'dataViewDownloadIframe',
- 'exportToFile', 'securityStrippingCheckbox',
+ 'dataViewSaveLogFile', 'dataViewSaveStatusText',
+ 'securityStrippingCheckbox',
'byteLoggingCheckbox', 'passivelyCapturedCount',
'activelyCapturedCount', 'dataViewDeleteAll',
- 'dataViewDumpDataDiv', 'dataViewLoadDataDiv',
- 'dataViewLoadLogFile',
+ 'dataViewDumpDataDiv',
+ 'dataViewLoadedDiv',
+ 'dataViewLoadedClientInfoText',
+ 'dataViewLoadLogFile', 'dataViewLoadStatusText',
'dataViewCapturingTextSpan',
'dataViewLoggingTextSpan');
@@ -115,25 +121,19 @@ function onLoaded() {
'spdySessionLinkSpan',
'spdySessionDiv');
- var serviceView;
- if (g_browser.isPlatformWindows()) {
- serviceView = new ServiceProvidersView('serviceProvidersTab',
- 'serviceProvidersTabContent',
- 'serviceProvidersTbody',
- 'namespaceProvidersTbody');
- }
+ var serviceView = new ServiceProvidersView('serviceProvidersTab',
+ 'serviceProvidersTabContent',
+ 'serviceProvidersTbody',
+ 'namespaceProvidersTbody');
var httpThrottlingView = new HttpThrottlingView(
'httpThrottlingTabContent', 'enableHttpThrottlingCheckbox');
- var logsView;
- if (g_browser.isChromeOS()) {
- logsView = new LogsView('logsTabContent',
- 'logTable',
- 'logsGlobalShowBtn',
- 'logsGlobalHideBtn',
- 'logsRefreshBtn');
- }
+ var logsView = new LogsView('logsTabContent',
+ 'logTable',
+ 'logsGlobalShowBtn',
+ 'logsGlobalHideBtn',
+ 'logsRefreshBtn');
var prerenderView = new PrerenderView('prerenderTabContent',
'prerenderEnabledSpan',
@@ -144,22 +144,25 @@ function onLoaded() {
var categoryTabSwitcher = new TabSwitcherView('categoryTabHandles');
g_browser.setTabSwitcher(categoryTabSwitcher);
- // Populate the main tabs.
- categoryTabSwitcher.addTab('eventsTab', eventsView, false);
- 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())
- categoryTabSwitcher.addTab('serviceProvidersTab', serviceView, false);
- categoryTabSwitcher.addTab('testTab', testView, false);
- categoryTabSwitcher.addTab('hstsTab', hstsView, false);
- categoryTabSwitcher.addTab('httpThrottlingTab', httpThrottlingView, false);
- if (g_browser.isChromeOS())
- categoryTabSwitcher.addTab('logsTab', logsView, false);
- categoryTabSwitcher.addTab('prerenderTab', prerenderView, false);
+ // Populate the main tabs. Even tabs that don't contain information for the
+ // running OS should be created, so they can load log dumps from other
+ // OSes.
+ categoryTabSwitcher.addTab('eventsTab', eventsView, false, true);
+ categoryTabSwitcher.addTab('proxyTab', proxyView, false, true);
+ categoryTabSwitcher.addTab('dnsTab', dnsView, false, true);
+ categoryTabSwitcher.addTab('socketsTab', socketsView, false, true);
+ categoryTabSwitcher.addTab('spdyTab', spdyView, false, true);
+ categoryTabSwitcher.addTab('httpCacheTab', httpCacheView, false, true);
+ categoryTabSwitcher.addTab('dataTab', dataView, false, true);
+ categoryTabSwitcher.addTab('serviceProvidersTab', serviceView, false,
+ g_browser.isPlatformWindows());
+ categoryTabSwitcher.addTab('testTab', testView, false, true);
+ categoryTabSwitcher.addTab('hstsTab', hstsView, false, true);
+ categoryTabSwitcher.addTab('httpThrottlingTab', httpThrottlingView, false,
+ true);
+ categoryTabSwitcher.addTab('logsTab', logsView, false,
+ g_browser.isChromeOS());
+ categoryTabSwitcher.addTab('prerenderTab', prerenderView, false, true);
// Build a map from the anchor name of each tab handle to its "tab ID".
// We will consider navigations to the #hash as a switch tab request.
@@ -184,9 +187,6 @@ function onLoaded() {
// Select the initial view based on the current URL.
window.onhashchange();
- // Inform observers a log file is not currently being displayed.
- g_browser.setIsViewingLogFile_(false);
-
// Tell the browser that we are ready to start receiving log events.
g_browser.sendReady();
}
@@ -204,6 +204,10 @@ function BrowserBridge() {
this.hstsObservers_ = [];
this.httpThrottlingObservers_ = [];
+ // This is set to true when a log file is being viewed to block all
+ // communication with the browser.
+ this.isViewingLogFile_ = false;
+
this.pollableDataHelpers_ = {};
this.pollableDataHelpers_.proxySettings =
new PollableDataHelper('onProxySettingsChanged',
@@ -247,11 +251,6 @@ function BrowserBridge() {
// Needed to simplify deletion, identify associated GUI elements, etc.
this.nextSourcelessEventId_ = -1;
- // True when viewing a log file rather than actively logged events.
- // When viewing a log file, all tabs are hidden except the event view,
- // and all received events are ignored.
- this.isViewingLogFile_ = false;
-
// True when cookies and authentication information should be removed from
// displayed events. When true, such information should be hidden from
// all pages.
@@ -290,6 +289,47 @@ function onUrlHashChange(anchorMap, categoryTabSwitcher) {
}
/**
+ * Returns true if |constants| appears to be a valid constants object.
+ */
+BrowserBridge.prototype.areValidConstants = function(constants) {
+ return typeof(constants) == 'object' &&
+ typeof(constants.logEventTypes) == 'object' &&
+ typeof(constants.clientInfo) == 'object' &&
+ typeof(constants.logEventPhase) == 'object' &&
+ typeof(constants.logSourceType) == 'object' &&
+ typeof(constants.logLevelType) == 'object' &&
+ typeof(constants.loadFlag) == 'object' &&
+ typeof(constants.netError) == 'object' &&
+ typeof(constants.addressFamily) == 'object' &&
+ typeof(constants.timeTickOffset) == 'string' &&
+ typeof(constants.logFormatVersion) == 'number';
+};
+
+/**
+ * Attempts to load all constants from |constants|. Returns false if one or
+ * more entries are missing. On failure, global dictionaries are not modified.
+ */
+BrowserBridge.prototype.loadConstants = function(constants) {
+ if (!this.areValidConstants(constants))
+ return false;
+
+ LogEventType = constants.logEventTypes;
+ ClientInfo = constants.clientInfo;
+ LogEventPhase = constants.logEventPhase;
+ LogSourceType = constants.logSourceType;
+ LogLevelType = constants.logLevelType;
+ LoadFlag = constants.loadFlag;
+ NetError = constants.netError;
+ AddressFamily = constants.addressFamily;
+ this.timeTickOffset_ = constants.timeTickOffset;
+
+ // Used for saving dumps.
+ Constants = constants;
+
+ return true;
+};
+
+/**
* Delay in milliseconds between updates of certain browser information.
*/
BrowserBridge.POLL_INTERVAL_MS = 5000;
@@ -298,8 +338,16 @@ BrowserBridge.POLL_INTERVAL_MS = 5000;
// Messages sent to the browser
//------------------------------------------------------------------------------
+/**
+ * Wraps |chrome.send|. Doesn't send anything when viewing a log file.
+ */
+BrowserBridge.prototype.send = function(value) {
+ if (!this.isViewingLogFile_)
+ chrome.send(value);
+};
+
BrowserBridge.prototype.sendReady = function() {
- chrome.send('notifyReady');
+ this.send('notifyReady');
// Some of the data we are interested is not currently exposed as a stream,
// so we will poll the browser to find out when it changes and then notify
@@ -318,155 +366,124 @@ BrowserBridge.prototype.isChromeOS = function() {
BrowserBridge.prototype.sendGetProxySettings = function() {
// The browser will call receivedProxySettings on completion.
- chrome.send('getProxySettings');
+ this.send('getProxySettings');
};
BrowserBridge.prototype.sendReloadProxySettings = function() {
- chrome.send('reloadProxySettings');
+ this.send('reloadProxySettings');
};
BrowserBridge.prototype.sendGetBadProxies = function() {
// The browser will call receivedBadProxies on completion.
- chrome.send('getBadProxies');
+ this.send('getBadProxies');
};
BrowserBridge.prototype.sendGetHostResolverInfo = function() {
// The browser will call receivedHostResolverInfo on completion.
- chrome.send('getHostResolverInfo');
+ this.send('getHostResolverInfo');
};
BrowserBridge.prototype.sendClearBadProxies = function() {
- chrome.send('clearBadProxies');
+ this.send('clearBadProxies');
};
BrowserBridge.prototype.sendClearHostResolverCache = function() {
- chrome.send('clearHostResolverCache');
+ this.send('clearHostResolverCache');
};
BrowserBridge.prototype.sendStartConnectionTests = function(url) {
- chrome.send('startConnectionTests', [url]);
+ this.send('startConnectionTests', [url]);
};
BrowserBridge.prototype.sendHSTSQuery = function(domain) {
- chrome.send('hstsQuery', [domain]);
+ this.send('hstsQuery', [domain]);
};
BrowserBridge.prototype.sendHSTSAdd = function(domain,
include_subdomains,
pins) {
- chrome.send('hstsAdd', [domain, include_subdomains, pins]);
+ this.send('hstsAdd', [domain, include_subdomains, pins]);
};
BrowserBridge.prototype.sendHSTSDelete = function(domain) {
- chrome.send('hstsDelete', [domain]);
+ this.send('hstsDelete', [domain]);
};
BrowserBridge.prototype.sendGetHttpCacheInfo = function() {
- chrome.send('getHttpCacheInfo');
+ this.send('getHttpCacheInfo');
};
BrowserBridge.prototype.sendGetSocketPoolInfo = function() {
- chrome.send('getSocketPoolInfo');
+ this.send('getSocketPoolInfo');
};
BrowserBridge.prototype.sendCloseIdleSockets = function() {
- chrome.send('closeIdleSockets');
+ this.send('closeIdleSockets');
};
BrowserBridge.prototype.sendFlushSocketPools = function() {
- chrome.send('flushSocketPools');
+ this.send('flushSocketPools');
};
BrowserBridge.prototype.sendGetSpdySessionInfo = function() {
- chrome.send('getSpdySessionInfo');
+ this.send('getSpdySessionInfo');
};
BrowserBridge.prototype.sendGetSpdyStatus = function() {
- chrome.send('getSpdyStatus');
+ this.send('getSpdyStatus');
};
BrowserBridge.prototype.sendGetSpdyAlternateProtocolMappings = function() {
- chrome.send('getSpdyAlternateProtocolMappings');
+ this.send('getSpdyAlternateProtocolMappings');
};
BrowserBridge.prototype.sendGetServiceProviders = function() {
- chrome.send('getServiceProviders');
+ this.send('getServiceProviders');
};
BrowserBridge.prototype.sendGetPrerenderInfo = function() {
- chrome.send('getPrerenderInfo');
-}
+ this.send('getPrerenderInfo');
+};
BrowserBridge.prototype.enableIPv6 = function() {
- chrome.send('enableIPv6');
+ this.send('enableIPv6');
};
BrowserBridge.prototype.setLogLevel = function(logLevel) {
- chrome.send('setLogLevel', ['' + logLevel]);
+ this.send('setLogLevel', ['' + logLevel]);
};
BrowserBridge.prototype.enableHttpThrottling = function(enable) {
- chrome.send('enableHttpThrottling', [enable]);
+ this.send('enableHttpThrottling', [enable]);
};
BrowserBridge.prototype.refreshSystemLogs = function() {
- chrome.send('refreshSystemLogs');
+ this.send('refreshSystemLogs');
};
BrowserBridge.prototype.getSystemLog = function(log_key, cellId) {
- chrome.send('getSystemLog', [log_key, cellId]);
+ this.send('getSystemLog', [log_key, cellId]);
};
//------------------------------------------------------------------------------
-// Messages received from the browser
+// Messages received from the browser.
//------------------------------------------------------------------------------
-BrowserBridge.prototype.receivedLogEntries = function(logEntries) {
+BrowserBridge.prototype.receive = function(command, params) {
// Does nothing if viewing a log file.
if (this.isViewingLogFile_)
return;
- this.addLogEntries(logEntries);
-};
-
-BrowserBridge.prototype.receivedLogEventTypeConstants = function(constantsMap) {
- LogEventType = constantsMap;
-};
-
-BrowserBridge.prototype.receivedClientInfo =
-function(info) {
- ClientInfo = info;
-};
-
-BrowserBridge.prototype.receivedLogEventPhaseConstants =
-function(constantsMap) {
- LogEventPhase = constantsMap;
+ this[command](params);
};
-BrowserBridge.prototype.receivedLogSourceTypeConstants =
-function(constantsMap) {
- LogSourceType = constantsMap;
-};
-
-BrowserBridge.prototype.receivedLogLevelConstants =
-function(constantsMap) {
- LogLevelType = constantsMap;
-};
+BrowserBridge.prototype.receivedConstants = function(constants) {
+ this.logFormatVersion_ = constants.logFormatVersion;
-BrowserBridge.prototype.receivedLoadFlagConstants = function(constantsMap) {
- LoadFlag = constantsMap;
+ this.loadConstants(constants);
};
-BrowserBridge.prototype.receivedNetErrorConstants = function(constantsMap) {
- NetError = constantsMap;
-};
-
-BrowserBridge.prototype.receivedAddressFamilyConstants =
-function(constantsMap) {
- AddressFamily = constantsMap;
-};
-
-BrowserBridge.prototype.receivedTimeTickOffset = function(timeTickOffset) {
- this.timeTickOffset_ = timeTickOffset;
+BrowserBridge.prototype.receivedLogEntries = function(logEntries) {
+ this.addLogEntries(logEntries);
};
BrowserBridge.prototype.receivedProxySettings = function(proxySettings) {
@@ -573,84 +590,33 @@ BrowserBridge.prototype.receivedPrerenderInfo = function(prerenderInfo) {
this.pollableDataHelpers_.prerenderInfo.update(prerenderInfo);
};
-BrowserBridge.prototype.loadedLogFile = function(logFileContents) {
- var match;
- // Replace carriage returns with linebreaks and then split around linebreaks.
- var lines = logFileContents.replace(/\r/g, '\n').split('\n');
- var entries = [];
- var numInvalidLines = 0;
-
- for (var i = 0; i < lines.length; ++i) {
- if (lines[i].trim().length == 0)
- continue;
- // Parse all valid lines, skipping any others.
- try {
- var entry = JSON.parse(lines[i]);
- if (entry &&
- typeof(entry) == 'object' &&
- entry.phase != undefined &&
- entry.source != undefined &&
- entry.time != undefined &&
- entry.type != undefined) {
- entries.push(entry);
- continue;
- }
- } catch (err) {
- }
- ++numInvalidLines;
- console.log('Unable to parse log line: ' + lines[i]);
- }
-
- if (entries.length == 0) {
- window.alert('Loading log file failed.');
- return;
- }
+//------------------------------------------------------------------------------
- this.deleteAllEvents();
+BrowserBridge.prototype.categoryTabSwitcher = function() {
+ return this.categoryTabSwitcher_;
+};
- this.setIsViewingLogFile_(true);
+BrowserBridge.prototype.logFormatVersion = function() {
+ return this.logFormatVersion_;
+};
- var validEntries = [];
- for (var i = 0; i < entries.length; ++i) {
- entries[i].wasPassivelyCaptured = true;
- if (LogEventType[entries[i].type] != undefined &&
- LogSourceType[entries[i].source.type] != undefined &&
- LogEventPhase[entries[i].phase] != undefined) {
- entries[i].type = LogEventType[entries[i].type];
- entries[i].source.type = LogSourceType[entries[i].source.type];
- entries[i].phase = LogEventPhase[entries[i].phase];
- validEntries.push(entries[i]);
- } else {
- // TODO(mmenke): Do something reasonable when the event type isn't
- // found, which could happen when event types are
- // removed or added between versions. Could also happen
- // with source types, but less likely.
- console.log(
- 'Unrecognized values in log entry: ' + JSON.stringify(entries[i]));
- }
- }
+BrowserBridge.prototype.isViewingLogFile = function() {
+ return this.isViewingLogFile_;
+};
- this.numPassivelyCapturedEvents_ = validEntries.length;
- this.addLogEntries(validEntries);
-
- var numInvalidEntries = entries.length - validEntries.length;
- if (numInvalidEntries > 0 || numInvalidLines > 0) {
- window.alert(
- numInvalidLines.toString() +
- ' entries could not be parsed as JSON strings, and ' +
- numInvalidEntries.toString() +
- ' entries don\'t have valid data.\n\n' +
- 'Unparseable lines may indicate log file corruption.\n' +
- 'Entries with invalid data may be caused by version differences.\n\n' +
- 'See console for more information.');
+/**
+ * Prevents receiving/sending events to/from the browser, so loaded data will
+ * not be mixed with current Chrome state. Also hides any interactive HTML
+ * elements that send messages to the browser. Cannot be undone without
+ * reloading the page.
+ */
+BrowserBridge.prototype.onLoadLogFile = function() {
+ if (!this.isViewingLogFile_) {
+ this.isViewingLogFile_ = true;
+ this.setSecurityStripping(false);
+ document.styleSheets[0].insertRule('.hideOnLoadLog { display: none; }');
}
-}
-
-BrowserBridge.prototype.getSystemLogCallback = function(result) {
- document.getElementById(result.cellId).textContent = result.log;
-}
-
-//------------------------------------------------------------------------------
+};
/**
* Sets the |categoryTabSwitcher_| of BrowserBridge. Since views depend on
@@ -766,9 +732,13 @@ BrowserBridge.prototype.addSpdyAlternateProtocolMappingsObserver =
* back when data is received, through:
*
* observer.onServiceProvidersChanged(serviceProviders)
+ *
+ * Will do nothing if on a platform other than Windows, as service providers are
+ * only present on Windows.
*/
BrowserBridge.prototype.addServiceProvidersObserver = function(observer) {
- this.pollableDataHelpers_.serviceProviders.addObserver(observer);
+ if (this.pollableDataHelpers_.serviceProviders)
+ this.pollableDataHelpers_.serviceProviders.addObserver(observer);
};
/**
@@ -822,7 +792,7 @@ BrowserBridge.prototype.addHttpThrottlingObserver = function(observer) {
*/
BrowserBridge.prototype.addPrerenderInfoObserver = function(observer) {
this.pollableDataHelpers_.prerenderInfo.addObserver(observer);
-}
+};
/**
* The browser gives us times in terms of "time ticks" in milliseconds.
@@ -938,32 +908,6 @@ BrowserBridge.prototype.getSecurityStripping = function() {
};
/**
- * Informs log observers whether or not future events will be from a log file.
- * Hides all tabs except the events and data tabs when viewing a log file, shows
- * them all otherwise.
- */
-BrowserBridge.prototype.setIsViewingLogFile_ = function(isViewingLogFile) {
- this.isViewingLogFile_ = isViewingLogFile;
- var tabIds = this.categoryTabSwitcher_.getAllTabIds();
-
- for (var i = 0; i < this.logObservers_.length; ++i)
- this.logObservers_[i].onSetIsViewingLogFile(isViewingLogFile);
-
- // Shows/hides tabs not used when viewing a log file.
- for (var i = 0; i < tabIds.length; ++i) {
- if (tabIds[i] == 'eventsTab' || tabIds[i] == 'dataTab')
- continue;
- this.categoryTabSwitcher_.showTabHandleNode(tabIds[i], !isViewingLogFile);
- }
-
- if (isViewingLogFile) {
- var activeTab = this.categoryTabSwitcher_.findActiveTab();
- if (activeTab.id != 'eventsTab')
- this.categoryTabSwitcher_.switchToTab('dataTab', null);
- }
-};
-
-/**
* Returns true if a log file is currently being viewed.
*/
BrowserBridge.prototype.isViewingLogFile = function() {
@@ -1010,6 +954,14 @@ PollableDataHelper.prototype.getObserverMethodName = function() {
return this.observerMethodName_;
};
+PollableDataHelper.prototype.isObserver = function(object) {
+ for (var i = 0; i < this.observerInfos_.length; ++i) {
+ if (this.observerInfos_[i].observer == object)
+ return true;
+ }
+ return false;
+};
+
/**
* This is a helper class used by PollableDataHelper, to keep track of
* each observer and whether or not it has received any data. The
@@ -1028,7 +980,7 @@ PollableDataHelper.prototype.addObserver = function(observer) {
PollableDataHelper.prototype.removeObserver = function(observer) {
for (var i = 0; i < this.observerInfos_.length; ++i) {
- if (this.observerInfos_[i].observer == observer) {
+ if (this.observerInfos_[i].observer === observer) {
this.observerInfos_.splice(i, 1);
return;
}