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

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) {
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
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 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698