Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(684)

Side by Side Diff: chrome/browser/resources/net_internals/bandwidth_view.js

Issue 775773002: Add data reduction proxy debug info to net-internals#bandwidth (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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) {
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
89 $(BandwidthView.EVENTS_TBODY_ID).innerHTML = '';
90
91 if (!info) {
92 return false;
93 }
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.
94
95 if (info.enabled) {
96 $(BandwidthView.ENABLED_ID).innerText = 'Enabled';
97 if (info.canary != null) {
98 $(BandwidthView.CANARY_STATUS_ID).innerText = info.canary;
99 }
mmenke 2014/12/05 16:18:25 nit: Remove braces.
jeremyim 2014/12/05 21:31:11 Done.
100 if (info.last_bypass != null) {
101 this.last_bypass_ = this.parseBypassEvent_(info.last_bypass);
102 }
mmenke 2014/12/05 16:18:25 nit: Remove braces.
jeremyim 2014/12/05 21:31:12 Done.
103 this.data_reduction_proxy_config_ = info.proxy_config.params;
104 } else {
105 $(BandwidthView.ENABLED_ID).innerText = 'Disabled';
106 $(BandwidthView.CANARY_STATUS_ID).innerText = 'N/A';
107 this.data_reduction_proxy_config_ = null;
108 }
109
110 this.updateDataReductionProxyConfig_();
111
112 for (var eventIndex in info.events) {
113 var event = info.events[eventIndex];
114 var headerRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
115 var detailsRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
116
117 var timeCell = addNode(headerRow, 'td');
118 var actionCell = addNode(headerRow, 'td');
119 var detailsCell = addNode(detailsRow, 'td');
120 detailsCell.colSpan = 2;
121 detailsCell.className = 'data-reduction-proxy-view-events-details';
122 var eventTime = timeutil.convertTimeTicksToDate(event.time);
123 timeutil.addNodeWithDate(timeCell, eventTime);
124
125 switch (event.type) {
126 case EventType.DATA_REDUCTION_PROXY_ENABLED:
127 this.buildEnabledRow_(event, actionCell, detailsCell);
128 break;
129 case EventType.DATA_REDUCTION_PROXY_CANARY_REQUEST:
130 this.buildCanaryRow_(event, actionCell, detailsCell);
131 break;
132 case EventType.DATA_REDUCTION_PROXY_CANARY_RESPONSE_RECEIVED:
133 this.buildCanaryResponseRow_(event, actionCell, detailsCell);
134 break;
135 case EventType.DATA_REDUCTION_PROXY_BYPASS_REQUESTED:
136 this.buildBypassRow_(event, actionCell, detailsCell);
137 break;
138 case EventType.DATA_REDUCTION_PROXY_FALLBACK:
139 this.buildFallbackRow_(event, actionCell, detailsCell);
140 break;
141 }
142 }
143 },
144
145 onProxySettingsChanged: function(proxySettings) {
146 var newProxySettings = [];
147 var effectiveSettings = proxySettings.effective;
148 if (effectiveSettings && effectiveSettings.proxy_per_scheme) {
149 for (var scheme in effectiveSettings.proxy_per_scheme) {
150 var schemeSettings = effectiveSettings.proxy_per_scheme[scheme];
151 if (scheme != 'fallback') {
152 for (var i = 0; i < schemeSettings.length; ++i) {
153 var proxyUri = schemeSettings[i];
154 if (proxyUri != 'direct://') {
155 newProxySettings.push(proxyUri);
156 }
mmenke 2014/12/05 16:18:25 nit: Remove braces. (There are a number of other
jeremyim 2014/12/05 21:31:11 Done.
157 }
158 }
159 }
160 }
161 this.proxy_config_ = newProxySettings;
162 this.updateDataReductionProxyConfig_();
163 },
164
165 onBadProxiesChanged: function(badProxies) {
166 var newBadProxies = [];
167 if (badProxies.length == 0) {
168 this.last_bypass_ = null;
169 } else {
170 for (var i = 0; i < badProxies.length; ++i) {
171 var entry = badProxies[i];
172 newBadProxies[entry.proxy_uri] = entry.bad_until;
173 }
174 }
175 this.bad_proxy_config_ = newBadProxies;
176 this.updateDataReductionProxyConfig_();
177 },
178
64 /** 179 /**
65 * Update the bandwidth usage table. Returns false on failure. 180 * Update the bandwidth usage table. Returns false on failure.
66 */ 181 */
67 updateBandwidthUsageTable_: function() { 182 updateBandwidthUsageTable_: function() {
68 var sessionNetworkStats = this.sessionNetworkStats_; 183 var sessionNetworkStats = this.sessionNetworkStats_;
69 var historicNetworkStats = this.historicNetworkStats_; 184 var historicNetworkStats = this.historicNetworkStats_;
70 if (!sessionNetworkStats || !historicNetworkStats) 185 if (!sessionNetworkStats || !historicNetworkStats)
71 return false; 186 return false;
72 187
73 var sessionOriginal = sessionNetworkStats.session_original_content_length; 188 var sessionOriginal = sessionNetworkStats.session_original_content_length;
(...skipping 22 matching lines...) Expand all
96 bytesToRoundedKilobytes_(historicOriginal - historicReceived) 211 bytesToRoundedKilobytes_(historicOriginal - historicReceived)
97 }); 212 });
98 rows.push({ 213 rows.push({
99 title: 'Savings (%)', 214 title: 'Savings (%)',
100 sessionValue: getPercentSavings_(sessionOriginal, sessionReceived), 215 sessionValue: getPercentSavings_(sessionOriginal, sessionReceived),
101 historicValue: getPercentSavings_(historicOriginal, 216 historicValue: getPercentSavings_(historicOriginal,
102 historicReceived) 217 historicReceived)
103 }); 218 });
104 219
105 var input = new JsEvalContext({rows: rows}); 220 var input = new JsEvalContext({rows: rows});
106 jstProcess(input, $(BandwidthView.MAIN_BOX_ID)); 221 jstProcess(input, $(BandwidthView.STATS_BOX_ID));
107 return true; 222 return true;
223 },
224
225 buildEnabledRow_: function(event, actionCell, detailsCell) {
226 if (event.params.enabled == 1) {
227 addTextNode(actionCell, 'Proxy: Enabled');
228 var proxyWrapper = addNode(detailsCell, 'div');
229 addNodeWithText(proxyWrapper, 'div', 'Proxy configuration:');
230
231 if (event.params.primary_origin != null &&
232 event.params.primary_origin.trim() != '') {
233 var proxyText = 'Primary: ' + event.params.primary_origin;
234 if (event.params.primary_restricted != null &&
235 event.params.primary_restricted) {
236 proxyText += ' (restricted)';
237 }
238 addNodeWithText(proxyWrapper, 'div', proxyText);
239 }
240
241 if (event.params.fallback_origin != null &&
242 event.params.fallback_origin.trim() != '') {
243 var proxyText = 'Fallback: ' + event.params.fallback_origin;
244 if (event.params.fallback_restricted != null &&
245 event.params.fallback_restricted) {
246 proxyText += ' (restricted)';
247 }
248 addNodeWithText(proxyWrapper, 'div', proxyText);
249 }
250
251 if (event.params.ssl_origin != null &&
252 event.params.ssl_origin.trim() != '') {
253 addNodeWithText(proxyWrapper, 'div',
254 'SSL: ' + event.params.ssl_origin);
255 }
256 } else {
257 addTextNode(actionCell, 'Proxy: Disabled');
258 }
259 },
260
261 buildCanaryRow_: function(event, actionCell, detailsCell) {
262 if (event.phase == EventPhase.PHASE_BEGIN) {
263 addTextNode(actionCell, 'Canary request sent');
264 addTextNode(detailsCell, 'URL: ' + event.params.url);
265 } else if (event.phase == EventPhase.PHASE_END) {
266 addTextNode(actionCell, 'Canary request completed');
267 if (event.params.net_error == 0) {
268 addTextNode(detailsCell, 'Result: OK');
269 } else {
270 addTextNode(detailsCell,
271 'Result: ' + netErrorToString(event.params.net_error));
272 }
273 }
274 },
275
276 buildCanaryResponseRow_: function(event, actionCell, detailsCell) {
277 addTextNode(actionCell, 'Canary response received');
278 },
279
280 buildBypassRow_: function(event, actionCell, detailsCell) {
281 var parsedBypass = this.parseBypassEvent_(event);
282
283 addTextNode(actionCell,
284 'Bypass received (' + parsedBypass.bypass_reason + ')');
285 var bypassWrapper = addNode(detailsCell, 'div');
286 addNodeWithText(bypassWrapper, 'div', 'URL: ' + parsedBypass.origin_url);
287 addNodeWithText(
288 bypassWrapper, 'div',
289 'Bypassed for ' + parsedBypass.bypass_duration_seconds + ' seconds.');
290 },
291
292 buildFallbackRow_: function(event, actionCell, detailsCell) {
293 addTextNode(actionCell, 'Proxy fallback');
294 },
295
296 parseBypassEvent_: function(event) {
297 var reason;
298 if (event.params.action != null) {
299 reason = event.params.action;
300 } else {
301 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.
302 case 0:
303 reason = 'Bypass current request';
304 break;
305 case 1:
306 reason = 'Bypass for short period';
307 break;
308 case 2:
309 reason = 'Bypass for medium period';
310 break;
311 case 3:
312 reason = 'Bypass for long period';
313 break;
314 case 4:
315 reason = 'Missing Via Header 4xx';
316 break;
317 case 5:
318 reason = 'Missing Via Header non-4xx';
319 break;
320 case 6:
321 reason = '407';
322 break;
323 case 7:
324 reason = '500';
325 break;
326 case 8:
327 reason = '502';
328 break;
329 case 9:
330 reason = '503';
331 break;
332 case 10:
333 reason = 'Network error';
334 break;
335 default:
336 reason = 'Unknown error';
337 break;
338 }
339 }
340
341 var parsedBypass = {
342 bypass_reason: reason,
343 origin_url: event.params.url,
344 bypass_duration_seconds: event.params.bypass_duration_seconds,
345 bypass_expiration: event.params.expiration,
346 };
347
348 return parsedBypass;
349 },
350
351 updateDataReductionProxyConfig_: function() {
352 $(BandwidthView.PRIMARY_PROXY_ID).innerHTML = '';
353 $(BandwidthView.SECONDARY_PROXY_ID).innerHTML = '';
354 setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), false);
355
356 if (this.data_reduction_proxy_config_) {
357 var primaryProxy = '';
358 var secondaryProxy = '';
359 var now = timeutil.getCurrentTimeTicks();
360
361 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
362 var input = new JsEvalContext(this.last_bypass_);
363 jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID));
364 } else {
365 var input = new JsEvalContext();
366 jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID));
367 }
368
369 if (this.data_reduction_proxy_config_.ssl_origin) {
370 primaryProxy = 'HTTPS Tunnel: ' + this.buildProxyString_(
371 this.data_reduction_proxy_config_.ssl_origin, false);
372 }
373
374 if (this.data_reduction_proxy_config_.primary_origin) {
375 var proxyString = this.buildProxyString_(
376 this.data_reduction_proxy_config_.primary_origin,
377 this.data_reduction_proxy_config_.primary_restricted);
378
379 if (primaryProxy == '') {
380 primaryProxy = proxyString;
381 } else {
382 secondaryProxy = proxyString;
383 }
384 }
385
386 if (this.data_reduction_proxy_config_.fallback_origin) {
387 var proxyString = this.buildProxyString_(
388 this.data_reduction_proxy_config_.fallback_origin,
389 this.data_reduction_proxy_config_.fallback_restricted);
390
391 if (primaryProxy == '') {
392 primaryProxy = proxyString;
393 } else if (secondaryProxy == '') {
394 secondaryProxy = proxyString;
395 }
396 }
397
398 $(BandwidthView.PRIMARY_PROXY_ID).innerText = primaryProxy;
399 $(BandwidthView.SECONDARY_PROXY_ID).innerText = secondaryProxy;
400 }
401 },
402
403 buildProxyString_: function(proxy, restricted) {
404 var normalizedProxy = this.normalize_(proxy);
405 var configured = this.isConfigured_(normalizedProxy);
406 var bypassed = this.isBypassed_(normalizedProxy);
407 var proxyString = '';
408 if (restricted) {
409 proxyString += proxy + ' (RESTRICTED)';
410 }
411 else if (configured) {
mmenke 2014/12/05 16:18:25 merge these two lines.
jeremyim 2014/12/05 21:31:12 Done.
412 proxyString += proxy;
413 if (bypassed) {
414 proxyString += ' (BYPASSED)';
415 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.
416 } else {
417 proxyString += ' (ACTIVE)';
418 }
419 }
420
421 return proxyString;
422 },
423
424 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.
425 function startsWith(str, prefix) {
426 return str.lastIndexOf(prefix, 0) == 0;
427 }
428
429 function strContains(str, substr, startIndex) {
430 return str.indexOf(substr, startIndex) != -1;
431 }
432
433 function endsWith(str, suffix) {
434 return str.indexOf(suffix, str.length - suffix.length) !== -1;
435 }
436
437 function stripSuffix(str, suffix) {
438 if (!endsWith(str, suffix))
439 return str;
440 return str.substring(str, str.length - suffix.length);
441 }
442
443 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.
444
445 if (startsWith(normalized, 'http://')) {
446 normalized = normalized.substr(7);
447 }
448
449 if (startsWith(normalized, 'https://')) {
450 if (!strContains(normalized, ':', 7)) {
451 normalized += ':443';
452 }
453 } else if (!strContains(normalized, ':', 0)) {
454 normalized += ':80';
455 }
456
457 return normalized;
458 },
459
460 isConfigured_: function(proxy) {
461 for (var index in this.proxy_config_) {
462 var entry = this.proxy_config_[index];
463 if (entry == proxy) {
464 return true;
465 }
466 }
467
468 return false;
469 },
470
471 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.
472 var now = timeutil.getCurrentTimeTicks();
473 for (var entry in this.bad_proxy_config_) {
474 if (entry == proxy && this.bad_proxy_config_[entry] > now) {
475 return true;
476 }
477 }
478
479 return false;
108 } 480 }
109 }; 481 };
110 482
111 /** 483 /**
112 * Converts bytes to kilobytes rounded to one decimal place. 484 * Converts bytes to kilobytes rounded to one decimal place.
113 */ 485 */
114 function bytesToRoundedKilobytes_(val) { 486 function bytesToRoundedKilobytes_(val) {
115 return (val / 1024).toFixed(1); 487 return (val / 1024).toFixed(1);
116 } 488 }
117 489
118 /** 490 /**
119 * Returns bandwidth savings as a percent rounded to one decimal place. 491 * Returns bandwidth savings as a percent rounded to one decimal place.
120 */ 492 */
121 function getPercentSavings_(original, received) { 493 function getPercentSavings_(original, received) {
122 if (original > 0) { 494 if (original > 0) {
123 return ((original - received) * 100 / original).toFixed(1); 495 return ((original - received) * 100 / original).toFixed(1);
124 } 496 }
125 return '0.0'; 497 return '0.0';
126 } 498 }
127 499
128 return BandwidthView; 500 return BandwidthView;
129 })(); 501 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698