Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** This view displays summary statistics on bandwidth usage. */ | 5 /** This view displays summary statistics on bandwidth usage. */ |
| 6 var BandwidthView = (function() { | 6 var BandwidthView = (function() { |
| 7 'use strict'; | 7 'use strict'; |
| 8 | 8 |
| 9 // We inherit from DivView. | 9 // We inherit from DivView. |
| 10 var superClass = DivView; | 10 var superClass = DivView; |
| 11 | 11 |
| 12 /** | 12 /** |
| 13 * @constructor | 13 * @constructor |
| 14 */ | 14 */ |
| 15 function BandwidthView() { | 15 function BandwidthView() { |
| 16 assertFirstConstructorCall(BandwidthView); | 16 assertFirstConstructorCall(BandwidthView); |
| 17 | 17 |
| 18 // Call superclass's constructor. | 18 // Call superclass's constructor. |
| 19 superClass.call(this, BandwidthView.MAIN_BOX_ID); | 19 superClass.call(this, BandwidthView.MAIN_BOX_ID); |
| 20 | 20 |
| 21 g_browser.addSessionNetworkStatsObserver(this, true); | 21 g_browser.addSessionNetworkStatsObserver(this, true); |
| 22 g_browser.addHistoricNetworkStatsObserver(this, true); | 22 g_browser.addHistoricNetworkStatsObserver(this, true); |
| 23 | 23 |
| 24 // Register to receive data reduction proxy info. | |
| 25 g_browser.addDataReductionProxyInfoObserver(this, true); | |
| 26 | |
| 27 // Register to receive proxy settings. | |
| 28 g_browser.addProxySettingsObserver(this, true); | |
| 29 | |
| 30 // Register to receive bad proxy info. | |
| 31 g_browser.addBadProxiesObserver(this, true); | |
| 32 | |
| 24 this.sessionNetworkStats_ = null; | 33 this.sessionNetworkStats_ = null; |
| 25 this.historicNetworkStats_ = null; | 34 this.historicNetworkStats_ = null; |
| 26 } | 35 } |
| 27 | 36 |
| 28 BandwidthView.TAB_ID = 'tab-handle-bandwidth'; | 37 BandwidthView.TAB_ID = 'tab-handle-bandwidth'; |
| 29 BandwidthView.TAB_NAME = 'Bandwidth'; | 38 BandwidthView.TAB_NAME = 'Bandwidth'; |
| 30 BandwidthView.TAB_HASH = '#bandwidth'; | 39 BandwidthView.TAB_HASH = '#bandwidth'; |
| 31 | 40 |
| 32 // IDs for special HTML elements in bandwidth_view.html | 41 // IDs for special HTML elements in bandwidth_view.html |
| 33 BandwidthView.MAIN_BOX_ID = 'bandwidth-view-tab-content'; | 42 BandwidthView.MAIN_BOX_ID = 'bandwidth-view-tab-content'; |
| 43 BandwidthView.ENABLED_ID = 'data-reduction-proxy-enabled'; | |
| 44 BandwidthView.PRIMARY_PROXY_ID = 'data-reduction-proxy-primary'; | |
| 45 BandwidthView.SECONDARY_PROXY_ID = 'data-reduction-proxy-secondary'; | |
| 46 BandwidthView.CANARY_STATUS_ID = 'data-reduction-proxy-canary-status'; | |
| 47 BandwidthView.BYPASS_STATE_ID = 'data-reduction-proxy-bypass-state'; | |
| 48 BandwidthView.BYPASS_STATE_CONTAINER_ID = | |
| 49 'data-reduction-proxy-bypass-state-container'; | |
| 50 BandwidthView.EVENTS_TBODY_ID = 'data-reduction-proxy-view-events-tbody'; | |
| 51 BandwidthView.EVENTS_UL = 'data-reduction-proxy-view-events-list'; | |
| 52 BandwidthView.STATS_BOX_ID = 'bandwidth-stats-table'; | |
| 34 | 53 |
| 35 cr.addSingletonGetter(BandwidthView); | 54 cr.addSingletonGetter(BandwidthView); |
| 36 | 55 |
| 37 BandwidthView.prototype = { | 56 BandwidthView.prototype = { |
| 38 // Inherit the superclass's methods. | 57 // Inherit the superclass's methods. |
| 39 __proto__: superClass.prototype, | 58 __proto__: superClass.prototype, |
| 40 | 59 |
| 60 data_reduction_proxy_config_: null, | |
| 61 last_bypass_event_: null, | |
| 62 proxy_config_: null, | |
| 63 bad_proxy_config_: null, | |
| 64 | |
| 41 onLoadLogFinish: function(data) { | 65 onLoadLogFinish: function(data) { |
| 42 // Even though this information is included in log dumps, there's no real | 66 // Even though this information is included in log dumps, there's no real |
| 43 // reason to display it when debugging a loaded log file. | 67 // reason to display it when debugging a loaded log file. |
| 44 return false; | 68 return false; |
| 45 }, | 69 }, |
| 46 | 70 |
| 47 /** | 71 /** |
| 48 * Retains information on bandwidth usage this session. | 72 * Retains information on bandwidth usage this session. |
| 49 */ | 73 */ |
| 50 onSessionNetworkStatsChanged: function(sessionNetworkStats) { | 74 onSessionNetworkStatsChanged: function(sessionNetworkStats) { |
| 51 this.sessionNetworkStats_ = sessionNetworkStats; | 75 this.sessionNetworkStats_ = sessionNetworkStats; |
| 52 return this.updateBandwidthUsageTable_(); | 76 return this.updateBandwidthUsageTable_(); |
| 53 }, | 77 }, |
| 54 | 78 |
| 55 /** | 79 /** |
| 56 * Displays information on bandwidth usage this session and over the | 80 * Displays information on bandwidth usage this session and over the |
| 57 * browser's lifetime. | 81 * browser's lifetime. |
| 58 */ | 82 */ |
| 59 onHistoricNetworkStatsChanged: function(historicNetworkStats) { | 83 onHistoricNetworkStatsChanged: function(historicNetworkStats) { |
| 60 this.historicNetworkStats_ = historicNetworkStats; | 84 this.historicNetworkStats_ = historicNetworkStats; |
| 61 return this.updateBandwidthUsageTable_(); | 85 return this.updateBandwidthUsageTable_(); |
| 62 }, | 86 }, |
| 63 | 87 |
| 88 onDataReductionProxyInfoChanged: function(info) { | |
| 89 $(BandwidthView.EVENTS_TBODY_ID).innerHTML = ''; | |
| 90 | |
| 91 if (!info) | |
| 92 { | |
|
bengr
2014/12/02 23:55:32
Move up a line.
jeremyim
2014/12/03 08:10:36
Done.
| |
| 93 return false; | |
| 94 } | |
| 95 | |
| 96 if (info.enabled == 'true') { | |
| 97 $(BandwidthView.ENABLED_ID).innerText = 'Enabled'; | |
| 98 if (info.canary != null) { | |
| 99 $(BandwidthView.CANARY_STATUS_ID).innerText = info.canary; | |
| 100 } | |
| 101 if (info.last_bypass != null) { | |
| 102 this.last_bypass_ = this.parseBypassEvent_(info.last_bypass); | |
| 103 } | |
| 104 this.data_reduction_proxy_config_ = info.proxy_config.params; | |
| 105 } else { | |
| 106 $(BandwidthView.ENABLED_ID).innerText = 'Disabled'; | |
| 107 $(BandwidthView.CANARY_STATUS_ID).innerText = 'N/A'; | |
| 108 this.data_reduction_proxy_config_ = null; | |
| 109 } | |
| 110 | |
| 111 this.updateDataReductionProxyConfig_(); | |
| 112 | |
| 113 for (var eventIndex in info.events) { | |
| 114 var event = info.events[eventIndex]; | |
| 115 var headerRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr'); | |
| 116 var detailsRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr'); | |
| 117 | |
| 118 var timeCell = addNode(headerRow, 'td'); | |
| 119 var actionCell = addNode(headerRow, 'td'); | |
| 120 var detailsCell = addNode(detailsRow, 'td'); | |
| 121 detailsCell.colSpan = 2; | |
| 122 detailsCell.className = 'data-reduction-proxy-view-events-details'; | |
| 123 var eventTime = timeutil.convertTimeTicksToDate(event.time); | |
| 124 timeutil.addNodeWithDate(timeCell, eventTime); | |
| 125 | |
| 126 switch (event.type) { | |
| 127 case EventType.DATA_REDUCTION_PROXY_ENABLED: | |
| 128 this.buildEnabledRow_(event, actionCell, detailsCell); | |
| 129 break; | |
| 130 case EventType.DATA_REDUCTION_PROXY_CANARY_REQUEST: | |
| 131 this.buildCanaryRow_(event, actionCell, detailsCell); | |
| 132 break; | |
| 133 case EventType.DATA_REDUCTION_PROXY_CANARY_RESPONSE_RECEIVED: | |
| 134 this.buildCanaryResponseRow_(event, actionCell, detailsCell); | |
| 135 break; | |
| 136 case EventType.DATA_REDUCTION_PROXY_BYPASS_REQUESTED: | |
| 137 this.buildBypassRow_(event, actionCell, detailsCell); | |
| 138 break; | |
| 139 case EventType.DATA_REDUCTION_PROXY_FALLBACK: | |
| 140 this.buildFallbackRow_(event, actionCell, detailsCell); | |
| 141 break; | |
| 142 } | |
| 143 } | |
| 144 }, | |
| 145 | |
| 146 onProxySettingsChanged: function(proxySettings) { | |
| 147 var newProxySettings = []; | |
| 148 var effectiveSettings = proxySettings.effective; | |
| 149 if (effectiveSettings && effectiveSettings.proxy_per_scheme) { | |
| 150 for (var scheme in effectiveSettings.proxy_per_scheme) { | |
| 151 var schemeSettings = effectiveSettings.proxy_per_scheme[scheme]; | |
| 152 if (scheme != 'fallback') { | |
| 153 for (var i = 0; i < schemeSettings.length; ++i) { | |
| 154 var proxyUri = schemeSettings[i]; | |
| 155 if (proxyUri != 'direct://') { | |
| 156 newProxySettings.push(proxyUri); | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 } | |
| 161 } | |
| 162 this.proxy_config_ = newProxySettings; | |
| 163 this.updateDataReductionProxyConfig_(); | |
| 164 }, | |
| 165 | |
| 166 onBadProxiesChanged: function(badProxies) { | |
| 167 var newBadProxies = []; | |
| 168 if (badProxies.length == 0) { | |
| 169 this.last_bypass_ = null; | |
| 170 } else { | |
| 171 for (var i = 0; i < badProxies.length; ++i) { | |
| 172 var entry = badProxies[i]; | |
| 173 newBadProxies[entry.proxy_uri] = entry.bad_until; | |
| 174 } | |
| 175 } | |
| 176 this.bad_proxy_config_ = newBadProxies; | |
| 177 this.updateDataReductionProxyConfig_(); | |
| 178 }, | |
| 179 | |
| 64 /** | 180 /** |
| 65 * Update the bandwidth usage table. Returns false on failure. | 181 * Update the bandwidth usage table. Returns false on failure. |
| 66 */ | 182 */ |
| 67 updateBandwidthUsageTable_: function() { | 183 updateBandwidthUsageTable_: function() { |
| 68 var sessionNetworkStats = this.sessionNetworkStats_; | 184 var sessionNetworkStats = this.sessionNetworkStats_; |
| 69 var historicNetworkStats = this.historicNetworkStats_; | 185 var historicNetworkStats = this.historicNetworkStats_; |
| 70 if (!sessionNetworkStats || !historicNetworkStats) | 186 if (!sessionNetworkStats || !historicNetworkStats) |
| 71 return false; | 187 return false; |
| 72 | 188 |
| 73 var sessionOriginal = sessionNetworkStats.session_original_content_length; | 189 var sessionOriginal = sessionNetworkStats.session_original_content_length; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 96 bytesToRoundedKilobytes_(historicOriginal - historicReceived) | 212 bytesToRoundedKilobytes_(historicOriginal - historicReceived) |
| 97 }); | 213 }); |
| 98 rows.push({ | 214 rows.push({ |
| 99 title: 'Savings (%)', | 215 title: 'Savings (%)', |
| 100 sessionValue: getPercentSavings_(sessionOriginal, sessionReceived), | 216 sessionValue: getPercentSavings_(sessionOriginal, sessionReceived), |
| 101 historicValue: getPercentSavings_(historicOriginal, | 217 historicValue: getPercentSavings_(historicOriginal, |
| 102 historicReceived) | 218 historicReceived) |
| 103 }); | 219 }); |
| 104 | 220 |
| 105 var input = new JsEvalContext({rows: rows}); | 221 var input = new JsEvalContext({rows: rows}); |
| 106 jstProcess(input, $(BandwidthView.MAIN_BOX_ID)); | 222 jstProcess(input, $(BandwidthView.STATS_BOX_ID)); |
| 107 return true; | 223 return true; |
| 224 }, | |
| 225 | |
| 226 buildEnabledRow_: function(event, actionCell, detailsCell) { | |
| 227 if (event.params.enabled == 1) { | |
| 228 addTextNode(actionCell, 'Proxy: Enabled'); | |
| 229 var proxyWrapper = addNode(detailsCell, 'div'); | |
| 230 addNodeWithText(proxyWrapper, 'div', 'Proxy configuration:'); | |
| 231 | |
| 232 if (event.params.primary_origin != null && | |
| 233 event.params.primary_origin.trim() != '') { | |
| 234 var proxyText = 'Primary: ' + event.params.primary_origin; | |
| 235 if (event.params.primary_restricted != null && | |
| 236 event.params.primary_restricted) { | |
| 237 proxyText += ' (restricted)'; | |
| 238 } | |
| 239 addNodeWithText(proxyWrapper, 'div', proxyText); | |
| 240 } | |
| 241 | |
| 242 if (event.params.fallback_origin != null && | |
| 243 event.params.fallback_origin.trim() != '') { | |
| 244 var proxyText = 'Fallback: ' + event.params.fallback_origin; | |
| 245 if (event.params.fallback_restricted != null && | |
| 246 event.params.fallback_restricted) { | |
| 247 proxyText += ' (restricted)'; | |
| 248 } | |
| 249 addNodeWithText(proxyWrapper, 'div', proxyText); | |
| 250 } | |
| 251 | |
| 252 if (event.params.ssl_origin != null && | |
| 253 event.params.ssl_origin.trim() != '') { | |
| 254 addNodeWithText(proxyWrapper, 'div', | |
| 255 'SSL: ' + event.params.ssl_origin); | |
| 256 } | |
| 257 } else { | |
| 258 addTextNode(actionCell, 'Proxy: Disabled'); | |
| 259 } | |
| 260 }, | |
| 261 | |
| 262 buildCanaryRow_: function(event, actionCell, detailsCell) { | |
| 263 if (event.phase == EventPhase.PHASE_BEGIN) { | |
| 264 addTextNode(actionCell, 'Canary request sent'); | |
| 265 addTextNode(detailsCell, 'URL: ' + event.params.url); | |
| 266 } else if (event.phase == EventPhase.PHASE_END) { | |
| 267 addTextNode(actionCell, 'Canary request completed'); | |
| 268 if (event.params.net_error == 0) { | |
| 269 addTextNode(detailsCell, 'Result: OK'); | |
| 270 } else { | |
| 271 addTextNode(detailsCell, | |
| 272 'Result: ' + netErrorToString(event.params.net_error)); | |
| 273 } | |
| 274 } | |
| 275 }, | |
| 276 | |
| 277 buildCanaryResponseRow_: function(event, actionCell, detailsCell) { | |
| 278 addTextNode(actionCell, 'Canary response received'); | |
| 279 }, | |
| 280 | |
| 281 buildBypassRow_: function(event, actionCell, detailsCell) { | |
| 282 var parsedBypass = this.parseBypassEvent_(event); | |
| 283 | |
| 284 addTextNode(actionCell, | |
| 285 'Bypass received (' + parsedBypass.bypass_reason + ')'); | |
| 286 var bypassWrapper = addNode(detailsCell, 'div'); | |
| 287 addNodeWithText(bypassWrapper, 'div', 'URL: ' + parsedBypass.origin_url); | |
| 288 addNodeWithText( | |
| 289 bypassWrapper, 'div', | |
| 290 'Bypassed for ' + parsedBypass.bypass_duration_seconds + ' seconds.'); | |
| 291 }, | |
| 292 | |
| 293 buildFallbackRow_: function(event, actionCell, detailsCell) { | |
| 294 addTextNode(actionCell, 'Proxy fallback'); | |
| 295 }, | |
| 296 | |
| 297 parseBypassEvent_: function(event) { | |
|
bengr
2014/12/02 23:55:32
Is this how the net events are visualized? It woul
jeremyim
2014/12/03 08:10:37
Net events uses the constants dictionary to perfor
| |
| 298 var reason; | |
| 299 if (event.params.action != null) { | |
| 300 reason = event.params.action; | |
| 301 } else { | |
| 302 switch (event.params.bypass_type) { | |
| 303 case 0: | |
| 304 reason = 'Bypass current request'; | |
| 305 break; | |
| 306 case 1: | |
| 307 reason = 'Bypass for short period'; | |
| 308 break; | |
| 309 case 2: | |
| 310 reason = 'Bypass for medium period'; | |
| 311 break; | |
| 312 case 3: | |
| 313 reason = 'Bypass for long period'; | |
| 314 break; | |
| 315 case 4: | |
| 316 reason = 'Missing Via Header 4xx'; | |
| 317 break; | |
| 318 case 5: | |
| 319 reason = 'Missing Via Header non-4xx'; | |
| 320 break; | |
| 321 case 6: | |
| 322 reason = '407'; | |
| 323 break; | |
| 324 case 7: | |
| 325 reason = '500'; | |
| 326 break; | |
| 327 case 8: | |
| 328 reason = '502'; | |
| 329 break; | |
| 330 case 9: | |
| 331 reason = '503'; | |
| 332 break; | |
| 333 case 10: | |
| 334 reason = 'Network error'; | |
| 335 break; | |
| 336 default: | |
| 337 reason = 'Unknown error'; | |
| 338 break; | |
| 339 } | |
| 340 } | |
| 341 | |
| 342 var parsedBypass = | |
| 343 { | |
|
bengr
2014/12/02 23:55:32
Move up a line.
jeremyim
2014/12/03 08:10:37
Done.
| |
| 344 bypass_reason: reason, | |
| 345 origin_url: event.params.url, | |
| 346 bypass_duration_seconds: event.params.bypass_duration_seconds, | |
| 347 bypass_expiration: event.params.expiration, | |
| 348 }; | |
| 349 | |
| 350 return parsedBypass; | |
| 351 }, | |
| 352 | |
| 353 updateDataReductionProxyConfig_: function() { | |
| 354 $(BandwidthView.PRIMARY_PROXY_ID).innerHTML = ''; | |
| 355 $(BandwidthView.SECONDARY_PROXY_ID).innerHTML = ''; | |
| 356 setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), false); | |
| 357 | |
| 358 if (this.data_reduction_proxy_config_) { | |
| 359 var primaryProxy = ''; | |
| 360 var secondaryProxy = ''; | |
| 361 var now = timeutil.getCurrentTimeTicks(); | |
| 362 | |
| 363 if (this.last_bypass_ && +this.last_bypass_.bypass_expiration > now) { | |
| 364 var input = new JsEvalContext(this.last_bypass_); | |
| 365 jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID)); | |
| 366 } else { | |
| 367 var input = new JsEvalContext(); | |
| 368 jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID)); | |
| 369 } | |
| 370 | |
| 371 if (this.data_reduction_proxy_config_.ssl_origin) { | |
| 372 primaryProxy = 'HTTPS Tunnel: ' + this.buildProxyString_( | |
| 373 this.data_reduction_proxy_config_.ssl_origin, false); | |
| 374 } | |
| 375 | |
| 376 if (this.data_reduction_proxy_config_.primary_origin) { | |
| 377 var proxyString = this.buildProxyString_( | |
| 378 this.data_reduction_proxy_config_.primary_origin, | |
| 379 this.data_reduction_proxy_config_.primary_restricted); | |
| 380 | |
| 381 if (primaryProxy == '') { | |
| 382 primaryProxy = proxyString; | |
| 383 } else { | |
| 384 secondaryProxy = proxyString; | |
| 385 } | |
| 386 } | |
| 387 | |
| 388 if (this.data_reduction_proxy_config_.fallback_origin) { | |
| 389 var proxyString = this.buildProxyString_( | |
| 390 this.data_reduction_proxy_config_.fallback_origin, | |
| 391 this.data_reduction_proxy_config_.fallback_restricted); | |
| 392 | |
| 393 if (primaryProxy == '') { | |
| 394 primaryProxy = proxyString; | |
| 395 } else if (secondaryProxy == '') { | |
| 396 secondaryProxy = proxyString; | |
| 397 } | |
| 398 } | |
| 399 | |
| 400 $(BandwidthView.PRIMARY_PROXY_ID).innerText = primaryProxy; | |
| 401 $(BandwidthView.SECONDARY_PROXY_ID).innerText = secondaryProxy; | |
| 402 } | |
| 403 }, | |
| 404 | |
| 405 buildProxyString_: function(proxy, restricted) { | |
| 406 var normalizedProxy = this.normalize_(proxy); | |
| 407 var configured = this.isConfigured_(normalizedProxy); | |
| 408 var bypassed = this.isBypassed_(normalizedProxy); | |
| 409 var proxyString = ''; | |
| 410 if (restricted) { | |
| 411 proxyString += proxy + ' (RESTRICTED)'; | |
| 412 } | |
| 413 else if (configured) { | |
| 414 proxyString += proxy; | |
| 415 if (bypassed) { | |
| 416 proxyString += ' (BYPASSED)'; | |
| 417 setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), true); | |
| 418 } else { | |
| 419 proxyString += ' (ACTIVE)'; | |
| 420 } | |
| 421 } | |
| 422 | |
| 423 return proxyString; | |
| 424 }, | |
| 425 | |
| 426 normalize_: function(proxy) { | |
| 427 function startsWith(str, prefix) { | |
| 428 return str.lastIndexOf(prefix, 0) == 0; | |
| 429 } | |
| 430 | |
| 431 function strContains(str, substr, startIndex) { | |
| 432 return str.indexOf(substr, startIndex) != -1; | |
| 433 } | |
| 434 | |
| 435 function endsWith(str, suffix) { | |
| 436 return str.indexOf(suffix, str.length - suffix.length) !== -1; | |
| 437 } | |
| 438 | |
| 439 function stripSuffix(str, suffix) { | |
| 440 if (!endsWith(str, suffix)) | |
| 441 return str; | |
| 442 return str.substring(str, str.length - suffix.length); | |
| 443 } | |
| 444 | |
| 445 var normalized = stripSuffix(proxy, '/'); | |
| 446 | |
| 447 if (startsWith(normalized, 'http://')) { | |
| 448 normalized = normalized.substr(7); | |
| 449 } | |
| 450 | |
| 451 if (startsWith(normalized, 'https://')) { | |
| 452 if (!strContains(normalized, ':', 7)) { | |
| 453 normalized += ':443'; | |
| 454 } | |
| 455 } else if (!strContains(normalized, ':', 0)) { | |
| 456 normalized += ':80'; | |
| 457 } | |
| 458 | |
| 459 return normalized; | |
| 460 }, | |
| 461 | |
| 462 isConfigured_: function(proxy) { | |
| 463 for (var index in this.proxy_config_) { | |
| 464 var entry = this.proxy_config_[index]; | |
| 465 if (entry == proxy) { | |
| 466 return true; | |
| 467 } | |
| 468 } | |
| 469 | |
| 470 return false; | |
| 471 }, | |
| 472 | |
| 473 isBypassed_: function(proxy) { | |
| 474 var now = timeutil.getCurrentTimeTicks(); | |
| 475 for (var entry in this.bad_proxy_config_) { | |
| 476 if (entry == proxy && this.bad_proxy_config_[entry] > now) { | |
| 477 return true; | |
| 478 } | |
| 479 } | |
| 480 | |
| 481 return false; | |
| 108 } | 482 } |
| 109 }; | 483 }; |
| 110 | 484 |
| 111 /** | 485 /** |
| 112 * Converts bytes to kilobytes rounded to one decimal place. | 486 * Converts bytes to kilobytes rounded to one decimal place. |
| 113 */ | 487 */ |
| 114 function bytesToRoundedKilobytes_(val) { | 488 function bytesToRoundedKilobytes_(val) { |
| 115 return (val / 1024).toFixed(1); | 489 return (val / 1024).toFixed(1); |
| 116 } | 490 } |
| 117 | 491 |
| 118 /** | 492 /** |
| 119 * Returns bandwidth savings as a percent rounded to one decimal place. | 493 * Returns bandwidth savings as a percent rounded to one decimal place. |
| 120 */ | 494 */ |
| 121 function getPercentSavings_(original, received) { | 495 function getPercentSavings_(original, received) { |
| 122 if (original > 0) { | 496 if (original > 0) { |
| 123 return ((original - received) * 100 / original).toFixed(1); | 497 return ((original - received) * 100 / original).toFixed(1); |
| 124 } | 498 } |
| 125 return '0.0'; | 499 return '0.0'; |
| 126 } | 500 } |
| 127 | 501 |
| 128 return BandwidthView; | 502 return BandwidthView; |
| 129 })(); | 503 })(); |
| OLD | NEW |