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

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 // This map should match the DataReductionProxyBypassType enum.
mmenke 2014/12/09 21:58:52 Sorry for not saying this in the first place, but
jeremyim 2014/12/09 23:14:28 Done.
22 this.bypassTypeLookup_ = {};
23 this.bypassTypeLookup_[0] = 'Bypass current request';
24 this.bypassTypeLookup_[1] = 'Bypass for short period';
25 this.bypassTypeLookup_[2] = 'Bypass for medium period';
26 this.bypassTypeLookup_[3] = 'Bypass for long period';
27 this.bypassTypeLookup_[4] = 'Missing Via Header 4xx';
28 this.bypassTypeLookup_[5] = 'Missing Via Header non-4xx';
29 this.bypassTypeLookup_[6] = '407';
30 this.bypassTypeLookup_[7] = '500';
31 this.bypassTypeLookup_[8] = '502';
32 this.bypassTypeLookup_[9] = '503';
33 this.bypassTypeLookup_[10] = 'Network error';
34
21 g_browser.addSessionNetworkStatsObserver(this, true); 35 g_browser.addSessionNetworkStatsObserver(this, true);
22 g_browser.addHistoricNetworkStatsObserver(this, true); 36 g_browser.addHistoricNetworkStatsObserver(this, true);
23 37
38 // Register to receive data reduction proxy info.
39 g_browser.addDataReductionProxyInfoObserver(this, true);
40
41 // Register to receive proxy settings.
42 g_browser.addProxySettingsObserver(this, true);
43
44 // Register to receive bad proxy info.
45 g_browser.addBadProxiesObserver(this, true);
46
24 this.sessionNetworkStats_ = null; 47 this.sessionNetworkStats_ = null;
25 this.historicNetworkStats_ = null; 48 this.historicNetworkStats_ = null;
26 } 49 }
27 50
28 BandwidthView.TAB_ID = 'tab-handle-bandwidth'; 51 BandwidthView.TAB_ID = 'tab-handle-bandwidth';
29 BandwidthView.TAB_NAME = 'Bandwidth'; 52 BandwidthView.TAB_NAME = 'Bandwidth';
30 BandwidthView.TAB_HASH = '#bandwidth'; 53 BandwidthView.TAB_HASH = '#bandwidth';
31 54
32 // IDs for special HTML elements in bandwidth_view.html 55 // IDs for special HTML elements in bandwidth_view.html
33 BandwidthView.MAIN_BOX_ID = 'bandwidth-view-tab-content'; 56 BandwidthView.MAIN_BOX_ID = 'bandwidth-view-tab-content';
57 BandwidthView.ENABLED_ID = 'data-reduction-proxy-enabled';
58 BandwidthView.PRIMARY_PROXY_ID = 'data-reduction-proxy-primary';
59 BandwidthView.SECONDARY_PROXY_ID = 'data-reduction-proxy-secondary';
60 BandwidthView.CANARY_STATUS_ID = 'data-reduction-proxy-canary-status';
61 BandwidthView.BYPASS_STATE_ID = 'data-reduction-proxy-bypass-state';
62 BandwidthView.BYPASS_STATE_CONTAINER_ID =
63 'data-reduction-proxy-bypass-state-container';
64 BandwidthView.EVENTS_TBODY_ID = 'data-reduction-proxy-view-events-tbody';
65 BandwidthView.EVENTS_UL = 'data-reduction-proxy-view-events-list';
66 BandwidthView.STATS_BOX_ID = 'bandwidth-stats-table';
34 67
35 cr.addSingletonGetter(BandwidthView); 68 cr.addSingletonGetter(BandwidthView);
36 69
37 BandwidthView.prototype = { 70 BandwidthView.prototype = {
38 // Inherit the superclass's methods. 71 // Inherit the superclass's methods.
39 __proto__: superClass.prototype, 72 __proto__: superClass.prototype,
40 73
74 data_reduction_proxy_config_: null,
75 last_bypass_event_: null,
76 proxy_config_: null,
77 bad_proxy_config_: null,
78
41 onLoadLogFinish: function(data) { 79 onLoadLogFinish: function(data) {
42 // Even though this information is included in log dumps, there's no real 80 // Even though this information is included in log dumps, there's no real
43 // reason to display it when debugging a loaded log file. 81 // reason to display it when debugging a loaded log file.
44 return false; 82 return false;
mmenke 2014/12/09 21:58:52 Note that this will hide the tab when loading log
jeremyim 2014/12/09 23:14:28 Done. I had this in a separate CL, but pulled that
45 }, 83 },
46 84
47 /** 85 /**
48 * Retains information on bandwidth usage this session. 86 * Retains information on bandwidth usage this session.
49 */ 87 */
50 onSessionNetworkStatsChanged: function(sessionNetworkStats) { 88 onSessionNetworkStatsChanged: function(sessionNetworkStats) {
51 this.sessionNetworkStats_ = sessionNetworkStats; 89 this.sessionNetworkStats_ = sessionNetworkStats;
52 return this.updateBandwidthUsageTable_(); 90 return this.updateBandwidthUsageTable_();
53 }, 91 },
54 92
55 /** 93 /**
56 * Displays information on bandwidth usage this session and over the 94 * Displays information on bandwidth usage this session and over the
57 * browser's lifetime. 95 * browser's lifetime.
58 */ 96 */
59 onHistoricNetworkStatsChanged: function(historicNetworkStats) { 97 onHistoricNetworkStatsChanged: function(historicNetworkStats) {
60 this.historicNetworkStats_ = historicNetworkStats; 98 this.historicNetworkStats_ = historicNetworkStats;
61 return this.updateBandwidthUsageTable_(); 99 return this.updateBandwidthUsageTable_();
62 }, 100 },
63 101
64 /** 102 /**
103 * Updates the UI based on receiving changes in information about the
104 * data reduction proxy summary.
105 */
106 onDataReductionProxyInfoChanged: function(info) {
107 $(BandwidthView.EVENTS_TBODY_ID).innerHTML = '';
108
109 if (!info)
110 return false;
111
112 if (info.enabled) {
113 $(BandwidthView.ENABLED_ID).innerText = 'Enabled';
114 if (info.canary != null)
115 $(BandwidthView.CANARY_STATUS_ID).innerText = info.canary;
mmenke 2014/12/09 21:58:52 If canary info is null, we just keep whatever we w
jeremyim 2014/12/09 23:14:28 Done.
116 if (info.last_bypass != null)
117 this.last_bypass_ = this.parseBypassEvent_(info.last_bypass);
mmenke 2014/12/09 21:58:52 As above, should to something with last_bypass_ if
jeremyim 2014/12/09 23:14:28 Done.
118 this.data_reduction_proxy_config_ = info.proxy_config.params;
119 } else {
120 $(BandwidthView.ENABLED_ID).innerText = 'Disabled';
121 $(BandwidthView.CANARY_STATUS_ID).innerText = 'N/A';
122 this.data_reduction_proxy_config_ = null;
123 }
124
125 this.updateDataReductionProxyConfig_();
126
127 for (var eventIndex = info.events.length; eventIndex > 0; --eventIndex) {
128 var event = info.events[eventIndex - 1];
mmenke 2014/12/09 21:58:52 This is kinda weird...better to make the eventInde
jeremyim 2014/12/09 23:14:28 Done.
129 var headerRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
130 var detailsRow = addNode($(BandwidthView.EVENTS_TBODY_ID), 'tr');
131
132 var timeCell = addNode(headerRow, 'td');
133 var actionCell = addNode(headerRow, 'td');
134 var detailsCell = addNode(detailsRow, 'td');
135 detailsCell.colSpan = 2;
136 detailsCell.className = 'data-reduction-proxy-view-events-details';
137 var eventTime = timeutil.convertTimeTicksToDate(event.time);
138 timeutil.addNodeWithDate(timeCell, eventTime);
139
140 switch (event.type) {
141 case EventType.DATA_REDUCTION_PROXY_ENABLED:
142 this.buildEnabledRow_(event, actionCell, detailsCell);
143 break;
144 case EventType.DATA_REDUCTION_PROXY_CANARY_REQUEST:
145 this.buildCanaryRow_(event, actionCell, detailsCell);
146 break;
147 case EventType.DATA_REDUCTION_PROXY_CANARY_RESPONSE_RECEIVED:
148 this.buildCanaryResponseRow_(event, actionCell, detailsCell);
149 break;
150 case EventType.DATA_REDUCTION_PROXY_BYPASS_REQUESTED:
151 this.buildBypassRow_(event, actionCell, detailsCell);
152 break;
153 case EventType.DATA_REDUCTION_PROXY_FALLBACK:
154 this.buildFallbackRow_(event, actionCell, detailsCell);
155 break;
156 }
157 }
158 },
159
160 /**
161 * Updates the UI based on receiving changes in information about the
162 * proxy settings.
163 */
164 onProxySettingsChanged: function(proxySettings) {
165 var newProxySettings = [];
166 var effectiveSettings = proxySettings.effective;
167 if (effectiveSettings && effectiveSettings.proxy_per_scheme) {
168 for (var scheme in effectiveSettings.proxy_per_scheme) {
169 var schemeSettings = effectiveSettings.proxy_per_scheme[scheme];
170 if (scheme != 'fallback') {
171 for (var i = 0; i < schemeSettings.length; ++i) {
172 var proxyUri = schemeSettings[i];
173 if (proxyUri != 'direct://')
174 newProxySettings.push(proxyUri);
175 }
176 }
177 }
178 }
179 this.proxy_config_ = newProxySettings;
180 this.updateDataReductionProxyConfig_();
181 },
182
183 /**
184 * Updates the UI based on receiving changes in information about bad
185 * proxy servers.
186 */
187 onBadProxiesChanged: function(badProxies) {
188 var newBadProxies = [];
189 if (badProxies.length == 0) {
190 this.last_bypass_ = null;
191 } else {
192 for (var i = 0; i < badProxies.length; ++i) {
193 var entry = badProxies[i];
194 newBadProxies[entry.proxy_uri] = entry.bad_until;
195 }
196 }
197 this.bad_proxy_config_ = newBadProxies;
198 this.updateDataReductionProxyConfig_();
199 },
200
201 /**
65 * Update the bandwidth usage table. Returns false on failure. 202 * Update the bandwidth usage table. Returns false on failure.
66 */ 203 */
67 updateBandwidthUsageTable_: function() { 204 updateBandwidthUsageTable_: function() {
68 var sessionNetworkStats = this.sessionNetworkStats_; 205 var sessionNetworkStats = this.sessionNetworkStats_;
69 var historicNetworkStats = this.historicNetworkStats_; 206 var historicNetworkStats = this.historicNetworkStats_;
70 if (!sessionNetworkStats || !historicNetworkStats) 207 if (!sessionNetworkStats || !historicNetworkStats)
71 return false; 208 return false;
72 209
73 var sessionOriginal = sessionNetworkStats.session_original_content_length; 210 var sessionOriginal = sessionNetworkStats.session_original_content_length;
74 var sessionReceived = sessionNetworkStats.session_received_content_length; 211 var sessionReceived = sessionNetworkStats.session_received_content_length;
(...skipping 21 matching lines...) Expand all
96 bytesToRoundedKilobytes_(historicOriginal - historicReceived) 233 bytesToRoundedKilobytes_(historicOriginal - historicReceived)
97 }); 234 });
98 rows.push({ 235 rows.push({
99 title: 'Savings (%)', 236 title: 'Savings (%)',
100 sessionValue: getPercentSavings_(sessionOriginal, sessionReceived), 237 sessionValue: getPercentSavings_(sessionOriginal, sessionReceived),
101 historicValue: getPercentSavings_(historicOriginal, 238 historicValue: getPercentSavings_(historicOriginal,
102 historicReceived) 239 historicReceived)
103 }); 240 });
104 241
105 var input = new JsEvalContext({rows: rows}); 242 var input = new JsEvalContext({rows: rows});
106 jstProcess(input, $(BandwidthView.MAIN_BOX_ID)); 243 jstProcess(input, $(BandwidthView.STATS_BOX_ID));
107 return true; 244 return true;
245 },
246
247 /**
248 * Renders a data reduction proxy enabled/disabled event into the event
249 * tbody.
250 */
251 buildEnabledRow_: function(event, actionCell, detailsCell) {
252 if (event.params.enabled == 1) {
253 addTextNode(actionCell, 'Proxy: Enabled');
254 var proxyWrapper = addNode(detailsCell, 'div');
255 addNodeWithText(proxyWrapper, 'div', 'Proxy configuration:');
256
257 if (event.params.primary_origin != null &&
258 event.params.primary_origin.trim() != '') {
259 var proxyText = 'Primary: ' + event.params.primary_origin;
260 if (event.params.primary_restricted != null &&
261 event.params.primary_restricted)
262 proxyText += ' (restricted)';
mmenke 2014/12/09 21:58:52 use braces when condition of the if takes more tha
jeremyim 2014/12/09 23:14:28 Done.
263 addNodeWithText(proxyWrapper, 'div', proxyText);
264 }
265
266 if (event.params.fallback_origin != null &&
267 event.params.fallback_origin.trim() != '') {
268 var proxyText = 'Fallback: ' + event.params.fallback_origin;
269 if (event.params.fallback_restricted != null &&
270 event.params.fallback_restricted)
271 proxyText += ' (restricted)';
mmenke 2014/12/09 21:58:52 use braces when condition of the if takes more tha
jeremyim 2014/12/09 23:14:28 Done.
272 addNodeWithText(proxyWrapper, 'div', proxyText);
273 }
274
275 if (event.params.ssl_origin != null &&
276 event.params.ssl_origin.trim() != '')
277 addNodeWithText(proxyWrapper, 'div',
278 'SSL: ' + event.params.ssl_origin);
mmenke 2014/12/09 21:58:52 use braces when body of the if takes more than one
jeremyim 2014/12/09 23:14:28 Done.
279 } else {
280 addTextNode(actionCell, 'Proxy: Disabled');
281 }
282 },
283
284 /**
285 * Renders a data reduction proxy canary request event into the event
286 * tbody.
287 */
288 buildCanaryRow_: function(event, actionCell, detailsCell) {
289 if (event.phase == EventPhase.PHASE_BEGIN) {
290 addTextNode(actionCell, 'Canary request sent');
291 addTextNode(detailsCell, 'URL: ' + event.params.url);
292 } else if (event.phase == EventPhase.PHASE_END) {
293 addTextNode(actionCell, 'Canary request completed');
294 if (event.params.net_error == 0) {
295 addTextNode(detailsCell, 'Result: OK');
296 } else {
297 addTextNode(detailsCell,
298 'Result: ' + netErrorToString(event.params.net_error));
299 }
300 }
301 },
302
303 /**
304 * Renders a data reduction proxy canary response event into the event
305 * tbody.
306 */
307 buildCanaryResponseRow_: function(event, actionCell, detailsCell) {
308 addTextNode(actionCell, 'Canary response received');
309 },
310
311 /**
312 * Renders a data reduction proxy bypass event into the event tbody.
313 */
314 buildBypassRow_: function(event, actionCell, detailsCell) {
315 var parsedBypass = this.parseBypassEvent_(event);
316
317 addTextNode(actionCell,
318 'Bypass received (' + parsedBypass.bypass_reason + ')');
319 var bypassWrapper = addNode(detailsCell, 'div');
320 addNodeWithText(bypassWrapper, 'div', 'URL: ' + parsedBypass.origin_url);
321 addNodeWithText(
322 bypassWrapper, 'div',
323 'Bypassed for ' + parsedBypass.bypass_duration_seconds + ' seconds.');
324 },
325
326 /**
327 * Renders a data reduction proxy fallback event into the event tbody.
328 */
329 buildFallbackRow_: function(event, actionCell, detailsCell) {
330 addTextNode(actionCell, 'Proxy fallback');
331 },
332
333 /**
334 * Parses a data reduction proxy bypass event for use in the summary and
335 * in the event tbody.
336 */
337 parseBypassEvent_: function(event) {
338 var reason;
339 if (event.params.action != null) {
340 reason = event.params.action;
341 } else {
342 reason = this.bypassTypeLookup_[event.params.bypass_type];
343 if (reason == null)
344 reason = 'Unknown error';
345 }
346
347 var parsedBypass = {
348 bypass_reason: reason,
349 origin_url: event.params.url,
350 bypass_duration_seconds: event.params.bypass_duration_seconds,
351 bypass_expiration: event.params.expiration,
352 };
353
354 return parsedBypass;
355 },
356
357 /**
358 * Updates the data reduction proxy summary block.
359 */
360 updateDataReductionProxyConfig_: function() {
361 $(BandwidthView.PRIMARY_PROXY_ID).innerHTML = '';
362 $(BandwidthView.SECONDARY_PROXY_ID).innerHTML = '';
363 setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), false);
364
365 if (this.data_reduction_proxy_config_) {
366 var primaryProxy = '';
367 var secondaryProxy = '';
368 var hasBypassedProxy = false;
369 var now = timeutil.getCurrentTimeTicks();
370
371 if (this.last_bypass_ && +this.last_bypass_.bypass_expiration > now) {
372 var input = new JsEvalContext(this.last_bypass_);
373 jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID));
374 } else {
375 var input = new JsEvalContext();
376 jstProcess(input, $(BandwidthView.BYPASS_STATE_CONTAINER_ID));
377 }
378
379 if (this.data_reduction_proxy_config_.ssl_origin) {
380 if (this.isMarkedAsBad_(this.data_reduction_proxy_config_.ssl_origin))
381 hasBypassedProxy = true;
382
383 primaryProxy = 'HTTPS Tunnel: ' + this.buildProxyString_(
384 this.data_reduction_proxy_config_.ssl_origin, false);
385 }
386
387 if (this.data_reduction_proxy_config_.primary_origin) {
388 if (this.isMarkedAsBad_(
389 this.data_reduction_proxy_config_.primary_origin))
390 hasBypassedProxy = true;
391
392 var proxyString = this.buildProxyString_(
393 this.data_reduction_proxy_config_.primary_origin,
394 this.data_reduction_proxy_config_.primary_restricted);
395
396 if (primaryProxy == '')
397 primaryProxy = proxyString;
398 else
399 secondaryProxy = proxyString;
400 }
401
402 if (this.data_reduction_proxy_config_.fallback_origin) {
403 if (this.isMarkedAsBad_(
404 this.data_reduction_proxy_config_.fallback_origin))
405 hasBypassedProxy = true;
406
407 var proxyString = this.buildProxyString_(
408 this.data_reduction_proxy_config_.fallback_origin,
409 this.data_reduction_proxy_config_.fallback_restricted);
410
411 if (primaryProxy == '')
412 primaryProxy = proxyString;
413 else if (secondaryProxy == '')
414 secondaryProxy = proxyString;
415 }
416
417 $(BandwidthView.PRIMARY_PROXY_ID).innerText = primaryProxy;
418 $(BandwidthView.SECONDARY_PROXY_ID).innerText = secondaryProxy;
419 if (hasBypassedProxy)
420 setNodeDisplay($(BandwidthView.BYPASS_STATE_CONTAINER_ID), true);
421 }
422 },
423
424 /**
425 * Takes a data reduction proxy configuration and renders to a friendly
426 * string.
427 */
428 buildProxyString_: function(proxy, restricted) {
429 var configured = this.isConfigured_(proxy);
430 var markedAsBad = this.isMarkedAsBad_(proxy);
431 var proxyString = '';
432 if (restricted) {
433 proxyString += proxy + ' (RESTRICTED)';
434 } else if (configured) {
435 proxyString += proxy;
436 if (markedAsBad) {
437 proxyString += ' (BYPASSED)';
438 } else {
439 proxyString += ' (ACTIVE)';
440 }
441 }
442
443 return proxyString;
444 },
445
446 /**
447 * Checks to see if a proxy server is in the current configuration.
448 */
449 isConfigured_: function(proxy) {
450 for (var index in this.proxy_config_) {
451 var entry = this.proxy_config_[index];
452 if (entry == proxy)
453 return true;
454 }
455
456 return false;
457 },
458
459 /**
460 * Checks to see if a proxy server is in marked as bad.
461 */
462 isMarkedAsBad_: function(proxy) {
463 var now = timeutil.getCurrentTimeTicks();
464 for (var entry in this.bad_proxy_config_) {
465 if (entry == proxy && this.bad_proxy_config_[entry] > now)
466 return true;
467 }
468
469 return false;
108 } 470 }
109 }; 471 };
110 472
111 /** 473 /**
112 * Converts bytes to kilobytes rounded to one decimal place. 474 * Converts bytes to kilobytes rounded to one decimal place.
113 */ 475 */
114 function bytesToRoundedKilobytes_(val) { 476 function bytesToRoundedKilobytes_(val) {
115 return (val / 1024).toFixed(1); 477 return (val / 1024).toFixed(1);
116 } 478 }
117 479
118 /** 480 /**
119 * Returns bandwidth savings as a percent rounded to one decimal place. 481 * Returns bandwidth savings as a percent rounded to one decimal place.
120 */ 482 */
121 function getPercentSavings_(original, received) { 483 function getPercentSavings_(original, received) {
122 if (original > 0) { 484 if (original > 0) {
123 return ((original - received) * 100 / original).toFixed(1); 485 return ((original - received) * 100 / original).toFixed(1);
124 } 486 }
125 return '0.0'; 487 return '0.0';
126 } 488 }
127 489
128 return BandwidthView; 490 return BandwidthView;
129 })(); 491 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698