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..77ab41df28add21b4312fac78a795e718c1128ea 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) { |
mmenke
2014/12/05 16:18:25
I'm not going to review all this, but it seems lik
jeremyim
2014/12/05 21:31:12
For mobile readability, we split the events across
|
+ $(BandwidthView.EVENTS_TBODY_ID).innerHTML = ''; |
+ |
+ if (!info) { |
+ return false; |
+ } |
mmenke
2014/12/05 16:18:25
nit: Preferred style is not to use braces for two
jeremyim
2014/12/05 21:31:12
Done.
|
+ |
+ if (info.enabled) { |
+ $(BandwidthView.ENABLED_ID).innerText = 'Enabled'; |
+ if (info.canary != null) { |
+ $(BandwidthView.CANARY_STATUS_ID).innerText = info.canary; |
+ } |
mmenke
2014/12/05 16:18:25
nit: Remove braces.
jeremyim
2014/12/05 21:31:11
Done.
|
+ if (info.last_bypass != null) { |
+ this.last_bypass_ = this.parseBypassEvent_(info.last_bypass); |
+ } |
mmenke
2014/12/05 16:18:25
nit: Remove braces.
jeremyim
2014/12/05 21:31:12
Done.
|
+ 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); |
+ } |
mmenke
2014/12/05 16:18:25
nit: Remove braces. (There are a number of other
jeremyim
2014/12/05 21:31:11
Done.
|
+ } |
+ } |
+ } |
+ } |
+ 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) { |
mmenke
2014/12/05 16:18:25
Suggest a dictionary here instead. More compact a
jeremyim
2014/12/05 21:31:12
Done.
|
+ 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) { |
mmenke
2014/12/05 16:18:25
+?
jeremyim
2014/12/05 21:31:12
Forces the expiration ticks (a string) into a numb
|
+ 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) { |
mmenke
2014/12/05 16:18:25
merge these two lines.
jeremyim
2014/12/05 21:31:12
Done.
|
+ proxyString += proxy; |
+ if (bypassed) { |
+ proxyString += ' (BYPASSED)'; |
+ setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), true); |
mmenke
2014/12/05 16:18:25
This is a really weird side effect to have in "bui
jeremyim
2014/12/05 21:31:12
Done.
|
+ } else { |
+ proxyString += ' (ACTIVE)'; |
+ } |
+ } |
+ |
+ return proxyString; |
+ }, |
+ |
+ normalize_: function(proxy) { |
mmenke
2014/12/05 16:18:25
This file is badly in need of comments.
jeremyim
2014/12/05 21:31:11
Done.
|
+ 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, '/'); |
mmenke
2014/12/05 16:18:25
Can we provide a proxy string from C++ that's clos
jeremyim
2014/12/05 21:31:12
Done.
|
+ |
+ 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) { |
mmenke
2014/12/05 16:18:25
Using different terminology van be confusing (bypa
jeremyim
2014/12/05 21:31:12
Done.
|
+ 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; |
} |
}; |