| Index: chrome/browser/resources/net_internals/bandwidth_view.js
|
| diff --git a/chrome/browser/resources/net_internals/bandwidth_view.js b/chrome/browser/resources/net_internals/bandwidth_view.js
|
| index 9f0e4e61cb95a1d8f67fee60365adb2352f5d267..6167d53fc323bf2f7848ad0201271bbc36b37784 100644
|
| --- a/chrome/browser/resources/net_internals/bandwidth_view.js
|
| +++ b/chrome/browser/resources/net_internals/bandwidth_view.js
|
| @@ -21,6 +21,15 @@ var BandwidthView = (function() {
|
| g_browser.addSessionNetworkStatsObserver(this, true);
|
| g_browser.addHistoricNetworkStatsObserver(this, true);
|
|
|
| + // Register to receive data reduction proxy info.
|
| + g_browser.addDataReductionProxyInfoObserver(this, true);
|
| +
|
| + // Register to receive proxy settings.
|
| + g_browser.addProxySettingsObserver(this, true);
|
| +
|
| + // Register to receive bad proxy info.
|
| + g_browser.addBadProxiesObserver(this, true);
|
| +
|
| this.sessionNetworkStats_ = null;
|
| this.historicNetworkStats_ = null;
|
| }
|
| @@ -31,6 +40,16 @@ var BandwidthView = (function() {
|
|
|
| // IDs for special HTML elements in bandwidth_view.html
|
| BandwidthView.MAIN_BOX_ID = 'bandwidth-view-tab-content';
|
| + BandwidthView.ENABLED_ID = 'data-reduction-proxy-enabled';
|
| + BandwidthView.PRIMARY_PROXY_ID = 'data-reduction-proxy-primary';
|
| + BandwidthView.SECONDARY_PROXY_ID = 'data-reduction-proxy-secondary';
|
| + BandwidthView.CANARY_STATUS_ID = 'data-reduction-proxy-canary-status';
|
| + BandwidthView.BYPASS_STATE_ID = 'data-reduction-proxy-bypass-state';
|
| + BandwidthView.BYPASS_STATE_CONTAINER_ID =
|
| + 'data-reduction-proxy-bypass-state-container';
|
| + BandwidthView.EVENTS_TBODY_ID = 'data-reduction-proxy-view-events-tbody';
|
| + BandwidthView.EVENTS_UL = 'data-reduction-proxy-view-events-list';
|
| + BandwidthView.STATS_BOX_ID = 'bandwidth-stats-table';
|
|
|
| cr.addSingletonGetter(BandwidthView);
|
|
|
| @@ -38,6 +57,11 @@ var BandwidthView = (function() {
|
| // Inherit the superclass's methods.
|
| __proto__: superClass.prototype,
|
|
|
| + data_reduction_proxy_config_: null,
|
| + last_bypass_event_: null,
|
| + proxy_config_: null,
|
| + bad_proxy_config_: null,
|
| +
|
| onLoadLogFinish: function(data) {
|
| // Even though this information is included in log dumps, there's no real
|
| // reason to display it when debugging a loaded log file.
|
| @@ -61,6 +85,97 @@ var BandwidthView = (function() {
|
| return this.updateBandwidthUsageTable_();
|
| },
|
|
|
| + onDataReductionProxyInfoChanged: function(info) {
|
| + $(BandwidthView.EVENTS_TBODY_ID).innerHTML = '';
|
| +
|
| + if (!info) {
|
| + return false;
|
| + }
|
| +
|
| + if (info.enabled == 'true') {
|
| + $(BandwidthView.ENABLED_ID).innerText = 'Enabled';
|
| + if (info.canary != null) {
|
| + $(BandwidthView.CANARY_STATUS_ID).innerText = info.canary;
|
| + }
|
| + if (info.last_bypass != null) {
|
| + this.last_bypass_ = this.parseBypassEvent_(info.last_bypass);
|
| + }
|
| + this.data_reduction_proxy_config_ = info.proxy_config.params;
|
| + } else {
|
| + $(BandwidthView.ENABLED_ID).innerText = 'Disabled';
|
| + $(BandwidthView.CANARY_STATUS_ID).innerText = 'N/A';
|
| + this.data_reduction_proxy_config_ = null;
|
| + }
|
| +
|
| + this.updateDataReductionProxyConfig_();
|
| +
|
| + for (var eventIndex in info.events) {
|
| + var event = info.events[eventIndex];
|
| + var headerRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
|
| + var detailsRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
|
| +
|
| + var timeCell = addNode(headerRow, 'td');
|
| + var actionCell = addNode(headerRow, 'td');
|
| + var detailsCell = addNode(detailsRow, 'td');
|
| + detailsCell.colSpan = 2;
|
| + detailsCell.className = 'data-reduction-proxy-view-events-details';
|
| + var eventTime = timeutil.convertTimeTicksToDate(event.time);
|
| + timeutil.addNodeWithDate(timeCell, eventTime);
|
| +
|
| + switch (event.type) {
|
| + case EventType.DATA_REDUCTION_PROXY_ENABLED:
|
| + this.buildEnabledRow_(event, actionCell, detailsCell);
|
| + break;
|
| + case EventType.DATA_REDUCTION_PROXY_CANARY_REQUEST:
|
| + this.buildCanaryRow_(event, actionCell, detailsCell);
|
| + break;
|
| + case EventType.DATA_REDUCTION_PROXY_CANARY_RESPONSE_RECEIVED:
|
| + this.buildCanaryResponseRow_(event, actionCell, detailsCell);
|
| + break;
|
| + case EventType.DATA_REDUCTION_PROXY_BYPASS_REQUESTED:
|
| + this.buildBypassRow_(event, actionCell, detailsCell);
|
| + break;
|
| + case EventType.DATA_REDUCTION_PROXY_FALLBACK:
|
| + this.buildFallbackRow_(event, actionCell, detailsCell);
|
| + break;
|
| + }
|
| + }
|
| + },
|
| +
|
| + onProxySettingsChanged: function(proxySettings) {
|
| + var newProxySettings = [];
|
| + var effectiveSettings = proxySettings.effective;
|
| + if (effectiveSettings && effectiveSettings.proxy_per_scheme) {
|
| + for (var scheme in effectiveSettings.proxy_per_scheme) {
|
| + var schemeSettings = effectiveSettings.proxy_per_scheme[scheme];
|
| + if (scheme != 'fallback') {
|
| + for (var i = 0; i < schemeSettings.length; ++i) {
|
| + var proxyUri = schemeSettings[i];
|
| + if (proxyUri != 'direct://') {
|
| + newProxySettings.push(proxyUri);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + }
|
| + this.proxy_config_ = newProxySettings;
|
| + this.updateDataReductionProxyConfig_();
|
| + },
|
| +
|
| + onBadProxiesChanged: function(badProxies) {
|
| + var newBadProxies = [];
|
| + if (badProxies.length == 0) {
|
| + this.last_bypass_ = null;
|
| + } else {
|
| + for (var i = 0; i < badProxies.length; ++i) {
|
| + var entry = badProxies[i];
|
| + newBadProxies[entry.proxy_uri] = entry.bad_until;
|
| + }
|
| + }
|
| + this.bad_proxy_config_ = newBadProxies;
|
| + this.updateDataReductionProxyConfig_();
|
| + },
|
| +
|
| /**
|
| * Update the bandwidth usage table. Returns false on failure.
|
| */
|
| @@ -103,8 +218,265 @@ var BandwidthView = (function() {
|
| });
|
|
|
| var input = new JsEvalContext({rows: rows});
|
| - jstProcess(input, $(BandwidthView.MAIN_BOX_ID));
|
| + jstProcess(input, $(BandwidthView.STATS_BOX_ID));
|
| return true;
|
| + },
|
| +
|
| + buildEnabledRow_: function(event, actionCell, detailsCell) {
|
| + if (event.params.enabled == 1) {
|
| + addTextNode(actionCell, 'Proxy: Enabled');
|
| + var proxyWrapper = addNode(detailsCell, 'div');
|
| + addNodeWithText(proxyWrapper, 'div', 'Proxy configuration:');
|
| +
|
| + if (event.params.primary_origin != null &&
|
| + event.params.primary_origin.trim() != '') {
|
| + var proxyText = 'Primary: ' + event.params.primary_origin;
|
| + if (event.params.primary_restricted != null &&
|
| + event.params.primary_restricted) {
|
| + proxyText += ' (restricted)';
|
| + }
|
| + addNodeWithText(proxyWrapper, 'div', proxyText);
|
| + }
|
| +
|
| + if (event.params.fallback_origin != null &&
|
| + event.params.fallback_origin.trim() != '') {
|
| + var proxyText = 'Fallback: ' + event.params.fallback_origin;
|
| + if (event.params.fallback_restricted != null &&
|
| + event.params.fallback_restricted) {
|
| + proxyText += ' (restricted)';
|
| + }
|
| + addNodeWithText(proxyWrapper, 'div', proxyText);
|
| + }
|
| +
|
| + if (event.params.ssl_origin != null &&
|
| + event.params.ssl_origin.trim() != '') {
|
| + addNodeWithText(proxyWrapper, 'div',
|
| + 'SSL: ' + event.params.ssl_origin);
|
| + }
|
| + } else {
|
| + addTextNode(actionCell, 'Proxy: Disabled');
|
| + }
|
| + },
|
| +
|
| + buildCanaryRow_: function(event, actionCell, detailsCell) {
|
| + if (event.phase == EventPhase.PHASE_BEGIN) {
|
| + addTextNode(actionCell, 'Canary request sent');
|
| + addTextNode(detailsCell, 'URL: ' + event.params.url);
|
| + } else if (event.phase == EventPhase.PHASE_END) {
|
| + addTextNode(actionCell, 'Canary request completed');
|
| + if (event.params.net_error == 0) {
|
| + addTextNode(detailsCell, 'Result: OK');
|
| + } else {
|
| + addTextNode(detailsCell,
|
| + 'Result: ' + netErrorToString(event.params.net_error));
|
| + }
|
| + }
|
| + },
|
| +
|
| + buildCanaryResponseRow_: function(event, actionCell, detailsCell) {
|
| + addTextNode(actionCell, 'Canary response received');
|
| + },
|
| +
|
| + buildBypassRow_: function(event, actionCell, detailsCell) {
|
| + var parsedBypass = this.parseBypassEvent_(event);
|
| +
|
| + addTextNode(actionCell,
|
| + 'Bypass received (' + parsedBypass.bypass_reason + ')');
|
| + var bypassWrapper = addNode(detailsCell, 'div');
|
| + addNodeWithText(bypassWrapper, 'div', 'URL: ' + parsedBypass.origin_url);
|
| + addNodeWithText(
|
| + bypassWrapper, 'div',
|
| + 'Bypassed for ' + parsedBypass.bypass_duration_seconds + ' seconds.');
|
| + },
|
| +
|
| + buildFallbackRow_: function(event, actionCell, detailsCell) {
|
| + addTextNode(actionCell, 'Proxy fallback');
|
| + },
|
| +
|
| + parseBypassEvent_: function(event) {
|
| + var reason;
|
| + if (event.params.action != null) {
|
| + reason = event.params.action;
|
| + } else {
|
| + switch (event.params.bypass_type) {
|
| + case 0:
|
| + reason = 'Bypass current request';
|
| + break;
|
| + case 1:
|
| + reason = 'Bypass for short period';
|
| + break;
|
| + case 2:
|
| + reason = 'Bypass for medium period';
|
| + break;
|
| + case 3:
|
| + reason = 'Bypass for long period';
|
| + break;
|
| + case 4:
|
| + reason = 'Missing Via Header 4xx';
|
| + break;
|
| + case 5:
|
| + reason = 'Missing Via Header non-4xx';
|
| + break;
|
| + case 6:
|
| + reason = '407';
|
| + break;
|
| + case 7:
|
| + reason = '500';
|
| + break;
|
| + case 8:
|
| + reason = '502';
|
| + break;
|
| + case 9:
|
| + reason = '503';
|
| + break;
|
| + case 10:
|
| + reason = 'Network error';
|
| + break;
|
| + default:
|
| + reason = 'Unknown error';
|
| + break;
|
| + }
|
| + }
|
| +
|
| + var parsedBypass = {
|
| + bypass_reason: reason,
|
| + origin_url: event.params.url,
|
| + bypass_duration_seconds: event.params.bypass_duration_seconds,
|
| + bypass_expiration: event.params.expiration,
|
| + };
|
| +
|
| + return parsedBypass;
|
| + },
|
| +
|
| + updateDataReductionProxyConfig_: function() {
|
| + $(BandwidthView.PRIMARY_PROXY_ID).innerHTML = '';
|
| + $(BandwidthView.SECONDARY_PROXY_ID).innerHTML = '';
|
| + setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), false);
|
| +
|
| + if (this.data_reduction_proxy_config_) {
|
| + var primaryProxy = '';
|
| + var secondaryProxy = '';
|
| + var now = timeutil.getCurrentTimeTicks();
|
| +
|
| + if (this.last_bypass_ && +this.last_bypass_.bypass_expiration > now) {
|
| + var input = new JsEvalContext(this.last_bypass_);
|
| + jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID));
|
| + } else {
|
| + var input = new JsEvalContext();
|
| + jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID));
|
| + }
|
| +
|
| + if (this.data_reduction_proxy_config_.ssl_origin) {
|
| + primaryProxy = 'HTTPS Tunnel: ' + this.buildProxyString_(
|
| + this.data_reduction_proxy_config_.ssl_origin, false);
|
| + }
|
| +
|
| + if (this.data_reduction_proxy_config_.primary_origin) {
|
| + var proxyString = this.buildProxyString_(
|
| + this.data_reduction_proxy_config_.primary_origin,
|
| + this.data_reduction_proxy_config_.primary_restricted);
|
| +
|
| + if (primaryProxy == '') {
|
| + primaryProxy = proxyString;
|
| + } else {
|
| + secondaryProxy = proxyString;
|
| + }
|
| + }
|
| +
|
| + if (this.data_reduction_proxy_config_.fallback_origin) {
|
| + var proxyString = this.buildProxyString_(
|
| + this.data_reduction_proxy_config_.fallback_origin,
|
| + this.data_reduction_proxy_config_.fallback_restricted);
|
| +
|
| + if (primaryProxy == '') {
|
| + primaryProxy = proxyString;
|
| + } else if (secondaryProxy == '') {
|
| + secondaryProxy = proxyString;
|
| + }
|
| + }
|
| +
|
| + $(BandwidthView.PRIMARY_PROXY_ID).innerText = primaryProxy;
|
| + $(BandwidthView.SECONDARY_PROXY_ID).innerText = secondaryProxy;
|
| + }
|
| + },
|
| +
|
| + buildProxyString_: function(proxy, restricted) {
|
| + var normalizedProxy = this.normalize_(proxy);
|
| + var configured = this.isConfigured_(normalizedProxy);
|
| + var bypassed = this.isBypassed_(normalizedProxy);
|
| + var proxyString = '';
|
| + if (restricted) {
|
| + proxyString += proxy + ' (RESTRICTED)';
|
| + }
|
| + else if (configured) {
|
| + proxyString += proxy;
|
| + if (bypassed) {
|
| + proxyString += ' (BYPASSED)';
|
| + setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), true);
|
| + } else {
|
| + proxyString += ' (ACTIVE)';
|
| + }
|
| + }
|
| +
|
| + return proxyString;
|
| + },
|
| +
|
| + normalize_: function(proxy) {
|
| + function startsWith(str, prefix) {
|
| + return str.lastIndexOf(prefix, 0) == 0;
|
| + }
|
| +
|
| + function strContains(str, substr, startIndex) {
|
| + return str.indexOf(substr, startIndex) != -1;
|
| + }
|
| +
|
| + function endsWith(str, suffix) {
|
| + return str.indexOf(suffix, str.length - suffix.length) !== -1;
|
| + }
|
| +
|
| + function stripSuffix(str, suffix) {
|
| + if (!endsWith(str, suffix))
|
| + return str;
|
| + return str.substring(str, str.length - suffix.length);
|
| + }
|
| +
|
| + var normalized = stripSuffix(proxy, '/');
|
| +
|
| + if (startsWith(normalized, 'http://')) {
|
| + normalized = normalized.substr(7);
|
| + }
|
| +
|
| + if (startsWith(normalized, 'https://')) {
|
| + if (!strContains(normalized, ':', 7)) {
|
| + normalized += ':443';
|
| + }
|
| + } else if (!strContains(normalized, ':', 0)) {
|
| + normalized += ':80';
|
| + }
|
| +
|
| + return normalized;
|
| + },
|
| +
|
| + isConfigured_: function(proxy) {
|
| + for (var index in this.proxy_config_) {
|
| + var entry = this.proxy_config_[index];
|
| + if (entry == proxy) {
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + return false;
|
| + },
|
| +
|
| + isBypassed_: function(proxy) {
|
| + var now = timeutil.getCurrentTimeTicks();
|
| + for (var entry in this.bad_proxy_config_) {
|
| + if (entry == proxy && this.bad_proxy_config_[entry] > now) {
|
| + return true;
|
| + }
|
| + }
|
| +
|
| + return false;
|
| }
|
| };
|
|
|
|
|