Chromium Code Reviews| 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..e4269bf82d1cd921626ca689229f504ae117a54c 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,10 +57,17 @@ var BandwidthView = (function() { |
| // Inherit the superclass's methods. |
| __proto__: superClass.prototype, |
| + data_reduction_proxy_config_: null, |
| + last_bypass_: 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. |
| - return false; |
| + return this.onBadProxiesChanged(data.badProxies) && |
| + this.onProxySettingsChanged(data.proxySettings) && |
| + this.onDataReductionProxyInfoChanged(data.dataReductionProxyInfo) && |
| + (this.onSessionNetworkStatsChanged(data.sessionNetworkStats) || |
| + this.onHistoricNetworkStatsChanged(data.historicNetworkStats)); |
| }, |
| /** |
| @@ -62,6 +88,112 @@ var BandwidthView = (function() { |
| }, |
| /** |
| + * Updates the UI based on receiving changes in information about the |
| + * data reduction proxy summary. |
| + */ |
| + onDataReductionProxyInfoChanged: function(info) { |
| + $(BandwidthView.EVENTS_TBODY_ID).innerHTML = ''; |
| + |
| + if (!info) |
| + return false; |
| + |
| + if (info.enabled) { |
| + $(BandwidthView.ENABLED_ID).innerText = 'Enabled'; |
| + $(BandwidthView.CANARY_STATUS_ID).innerText = |
| + info.canary != null ? info.canary : 'N/A'; |
| + this.last_bypass_ = info.last_bypass != null ? |
| + this.parseBypassEvent_(info.last_bypass) : null; |
| + 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 = info.events.length - 1; eventIndex >= 0; |
| + --eventIndex) { |
| + 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; |
| + } |
| + } |
| + |
| + return true; |
| + }, |
| + |
| + /** |
| + * Updates the UI based on receiving changes in information about the |
| + * proxy settings. |
| + */ |
| + 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_(); |
| + |
| + return true; |
| + }, |
| + |
| + /** |
| + * Updates the UI based on receiving changes in information about bad |
| + * proxy servers. |
| + */ |
| + 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_(); |
| + |
| + return true; |
| + }, |
| + |
| + /** |
| * Update the bandwidth usage table. Returns false on failure. |
| */ |
| updateBandwidthUsageTable_: function() { |
| @@ -103,8 +235,251 @@ var BandwidthView = (function() { |
| }); |
| var input = new JsEvalContext({rows: rows}); |
| - jstProcess(input, $(BandwidthView.MAIN_BOX_ID)); |
| + jstProcess(input, $(BandwidthView.STATS_BOX_ID)); |
| return true; |
| + }, |
| + |
| + /** |
| + * Renders a data reduction proxy enabled/disabled event into the event |
| + * tbody. |
| + */ |
| + 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'); |
| + } |
| + }, |
| + |
| + /** |
| + * Renders a data reduction proxy canary request event into the event |
| + * tbody. |
| + */ |
| + 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)); |
| + } |
| + } |
| + }, |
| + |
| + /** |
| + * Renders a data reduction proxy canary response event into the event |
| + * tbody. |
| + */ |
| + buildCanaryResponseRow_: function(event, actionCell, detailsCell) { |
| + addTextNode(actionCell, 'Canary response received'); |
| + }, |
| + |
| + /** |
| + * Renders a data reduction proxy bypass event into the event tbody. |
| + */ |
| + 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.'); |
| + }, |
| + |
| + /** |
| + * Renders a data reduction proxy fallback event into the event tbody. |
| + */ |
| + buildFallbackRow_: function(event, actionCell, detailsCell) { |
| + addTextNode(actionCell, 'Proxy fallback'); |
| + }, |
| + |
| + /** |
| + * Parses a data reduction proxy bypass event for use in the summary and |
| + * in the event tbody. |
| + */ |
| + parseBypassEvent_: function(event) { |
| + var reason; |
| + if (event.params.action != null) { |
| + reason = event.params.action; |
| + } else { |
| + reason = getKeyWithValue( |
| + DataReductionProxyBypassEventType, event.params.bypass_type); |
| + } |
| + |
| + 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; |
| + }, |
| + |
| + /** |
| + * Updates the data reduction proxy summary block. |
| + */ |
| + 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 hasBypassedProxy = false; |
| + 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) { |
| + if (this.isMarkedAsBad_(this.data_reduction_proxy_config_.ssl_origin)) |
| + hasBypassedProxy = true; |
| + |
| + primaryProxy = 'HTTPS Tunnel: ' + this.buildProxyString_( |
| + this.data_reduction_proxy_config_.ssl_origin, false); |
| + } |
| + |
| + if (this.data_reduction_proxy_config_.primary_origin) { |
| + if (this.isMarkedAsBad_( |
| + this.data_reduction_proxy_config_.primary_origin)) |
| + hasBypassedProxy = true; |
| + |
| + 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) { |
| + if (this.isMarkedAsBad_( |
| + this.data_reduction_proxy_config_.fallback_origin)) |
| + hasBypassedProxy = true; |
| + |
| + 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; |
| + if (hasBypassedProxy) |
| + setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), true); |
| + } |
| + }, |
| + |
| + /** |
| + * Takes a data reduction proxy configuration and renders to a friendly |
| + * string. |
| + */ |
| + buildProxyString_: function(proxy, restricted) { |
| + var configured = this.isConfigured_(proxy); |
| + var markedAsBad = this.isMarkedAsBad_(proxy); |
| + var proxyString = ''; |
| + if (restricted) { |
| + proxyString += proxy + ' (RESTRICTED)'; |
| + } else if (configured) { |
| + proxyString += proxy; |
| + if (markedAsBad) { |
| + proxyString += ' (BYPASSED)'; |
| + } else { |
| + proxyString += ' (ACTIVE)'; |
| + } |
| + } |
| + |
| + return proxyString; |
| + }, |
| + |
| + /** |
| + * Checks to see if a proxy server is in the current configuration. |
| + */ |
| + isConfigured_: function(proxy) { |
| + for (var index in this.proxy_config_) { |
| + var entry = this.proxy_config_[index]; |
| + if (entry == proxy) |
| + return true; |
| + } |
| + |
| + return false; |
| + }, |
| + |
| + /** |
| + * Checks to see if a proxy server is in marked as bad. |
| + */ |
| + isMarkedAsBad_: function(proxy) { |
| + for (var entry in this.bad_proxy_config_) { |
| + if (entry == proxy && |
| + this.hasTimePassedLogTime_(this.bad_proxy_config_[entry])) |
| + return true; |
|
mmenke
2014/12/10 21:09:43
nit: +braces
jeremyim
2014/12/11 05:24:21
Done.
|
| + } |
| + |
| + return false; |
| + }, |
| + |
| + /** |
| + * Checks to see if a given time in ticks has passed the time of the |
| + * the log. For real time viewing, this is "now", but for loaded logs, it |
| + * is the time at which the logs were taken. |
| + */ |
| + hasTimePassedLogTime_: function(timeTicks) { |
| + var logTime; |
| + if (MainView.isViewingLoadedLog() && ClientInfo.numericDate) { |
| + logTime = ClientInfo.numericDate; |
| + } else { |
| + logTime = timeutil.getCurrentTime(); |
| + } |
| + |
| + return timeutil.convertTimeTicksToTime(timeTicks) > logTime; |
| } |
| }; |