| Index: netlog_viewer/proxy_view.js
|
| diff --git a/netlog_viewer/proxy_view.js b/netlog_viewer/proxy_view.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..10534137408b393a27e1040eb996a1ebd98c41cd
|
| --- /dev/null
|
| +++ b/netlog_viewer/proxy_view.js
|
| @@ -0,0 +1,187 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +/**
|
| + * This view displays information on the proxy setup:
|
| + *
|
| + * - Shows the current proxy settings.
|
| + * - Has a button to reload these settings.
|
| + * - Shows the list of proxy hostnames that are cached as "bad".
|
| + * - Has a button to clear the cached bad proxies.
|
| + */
|
| +var ProxyView = (function() {
|
| + 'use strict';
|
| +
|
| + // We inherit from DivView.
|
| + var superClass = DivView;
|
| +
|
| + /**
|
| + * @constructor
|
| + */
|
| + function ProxyView() {
|
| + assertFirstConstructorCall(ProxyView);
|
| +
|
| + // Call superclass's constructor.
|
| + superClass.call(this, ProxyView.MAIN_BOX_ID);
|
| +
|
| + // Hook up the UI components.
|
| + $(ProxyView.RELOAD_SETTINGS_BUTTON_ID).onclick =
|
| + g_browser.sendReloadProxySettings.bind(g_browser);
|
| + $(ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID).onclick =
|
| + g_browser.sendClearBadProxies.bind(g_browser);
|
| +
|
| + // Register to receive proxy information as it changes.
|
| + g_browser.addProxySettingsObserver(this, true);
|
| + g_browser.addBadProxiesObserver(this, true);
|
| + }
|
| +
|
| + ProxyView.TAB_ID = 'tab-handle-proxy';
|
| + ProxyView.TAB_NAME = 'Proxy';
|
| + ProxyView.TAB_HASH = '#proxy';
|
| +
|
| + // IDs for special HTML elements in proxy_view.html
|
| + ProxyView.MAIN_BOX_ID = 'proxy-view-tab-content';
|
| + ProxyView.ORIGINAL_SETTINGS_DIV_ID = 'proxy-view-original-settings';
|
| + ProxyView.EFFECTIVE_SETTINGS_DIV_ID = 'proxy-view-effective-settings';
|
| + ProxyView.ORIGINAL_CONTENT_DIV_ID = 'proxy-view-original-content';
|
| + ProxyView.EFFECTIVE_CONTENT_DIV_ID = 'proxy-view-effective-content';
|
| + ProxyView.RELOAD_SETTINGS_BUTTON_ID = 'proxy-view-reload-settings';
|
| + ProxyView.BAD_PROXIES_DIV_ID = 'proxy-view-bad-proxies-div';
|
| + ProxyView.BAD_PROXIES_TBODY_ID = 'proxy-view-bad-proxies-tbody';
|
| + ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID = 'proxy-view-clear-bad-proxies';
|
| + ProxyView.SOCKS_HINTS_DIV_ID = 'proxy-view-socks-hints';
|
| + ProxyView.SOCKS_HINTS_FLAG_DIV_ID = 'proxy-view-socks-hints-flag';
|
| +
|
| + cr.addSingletonGetter(ProxyView);
|
| +
|
| + ProxyView.prototype = {
|
| + // Inherit the superclass's methods.
|
| + __proto__: superClass.prototype,
|
| +
|
| + onLoadLogFinish: function(data) {
|
| + return this.onProxySettingsChanged(data.proxySettings) &&
|
| + this.onBadProxiesChanged(data.badProxies);
|
| + },
|
| +
|
| + onProxySettingsChanged: function(proxySettings) {
|
| + $(ProxyView.ORIGINAL_SETTINGS_DIV_ID).innerHTML = '';
|
| + $(ProxyView.EFFECTIVE_SETTINGS_DIV_ID).innerHTML = '';
|
| + this.updateSocksHints_(null);
|
| +
|
| + if (!proxySettings)
|
| + return false;
|
| +
|
| + // Both |original| and |effective| are dictionaries describing the
|
| + // settings.
|
| + var original = proxySettings.original;
|
| + var effective = proxySettings.effective;
|
| +
|
| + var originalStr = proxySettingsToString(original);
|
| + var effectiveStr = proxySettingsToString(effective);
|
| +
|
| + setNodeDisplay($(ProxyView.ORIGINAL_CONTENT_DIV_ID),
|
| + originalStr != effectiveStr);
|
| +
|
| + $(ProxyView.ORIGINAL_SETTINGS_DIV_ID).innerText = originalStr;
|
| + $(ProxyView.EFFECTIVE_SETTINGS_DIV_ID).innerText = effectiveStr;
|
| +
|
| + this.updateSocksHints_(effective);
|
| +
|
| + return true;
|
| + },
|
| +
|
| + onBadProxiesChanged: function(badProxies) {
|
| + $(ProxyView.BAD_PROXIES_TBODY_ID).innerHTML = '';
|
| + setNodeDisplay($(ProxyView.BAD_PROXIES_DIV_ID),
|
| + badProxies && badProxies.length > 0);
|
| +
|
| + if (!badProxies)
|
| + return false;
|
| +
|
| + // Add a table row for each bad proxy entry.
|
| + for (var i = 0; i < badProxies.length; ++i) {
|
| + var entry = badProxies[i];
|
| + var badUntilDate = timeutil.convertTimeTicksToDate(entry.bad_until);
|
| +
|
| + var tr = addNode($(ProxyView.BAD_PROXIES_TBODY_ID), 'tr');
|
| +
|
| + var nameCell = addNode(tr, 'td');
|
| + var badUntilCell = addNode(tr, 'td');
|
| +
|
| + addTextNode(nameCell, entry.proxy_uri);
|
| + timeutil.addNodeWithDate(badUntilCell, badUntilDate);
|
| + }
|
| + return true;
|
| + },
|
| +
|
| + updateSocksHints_: function(proxySettings) {
|
| + setNodeDisplay($(ProxyView.SOCKS_HINTS_DIV_ID), false);
|
| +
|
| + if (!proxySettings)
|
| + return;
|
| +
|
| + var socksProxy = getSingleSocks5Proxy_(proxySettings.single_proxy);
|
| + if (!socksProxy)
|
| + return;
|
| +
|
| + // Suggest a recommended --host-resolver-rules.
|
| + // NOTE: This does not compensate for any proxy bypass rules. If the
|
| + // proxy settings include proxy bypasses the user may need to expand the
|
| + // exclusions for host resolving.
|
| + var hostResolverRules = 'MAP * ~NOTFOUND , EXCLUDE ' + socksProxy.host;
|
| + var hostResolverRulesFlag = '--host-resolver-rules="' +
|
| + hostResolverRules + '"';
|
| +
|
| + // TODO(eroman): On Linux the ClientInfo.command_line is wrong in that it
|
| + // doesn't include any quotes around the parameters. This means the
|
| + // string search above is going to fail :(
|
| + if (ClientInfo.command_line &&
|
| + ClientInfo.command_line.indexOf(hostResolverRulesFlag) != -1) {
|
| + // Chrome is already using the suggested resolver rules.
|
| + return;
|
| + }
|
| +
|
| + $(ProxyView.SOCKS_HINTS_FLAG_DIV_ID).innerText = hostResolverRulesFlag;
|
| + setNodeDisplay($(ProxyView.SOCKS_HINTS_DIV_ID), true);
|
| + }
|
| + };
|
| +
|
| + function getSingleSocks5Proxy_(proxyList) {
|
| + var proxyString;
|
| + if (typeof proxyList == 'string') {
|
| + // Older versions of Chrome passed single_proxy as a string.
|
| + // TODO(eroman): This behavior changed in M27. Support for older logs can
|
| + // safely be removed circa M29.
|
| + proxyString = proxyList;
|
| + } else if (Array.isArray(proxyList) && proxyList.length == 1) {
|
| + proxyString = proxyList[0];
|
| + } else {
|
| + return null;
|
| + }
|
| +
|
| + var pattern = /^socks5:\/\/(.*)$/;
|
| + var matches = pattern.exec(proxyString);
|
| +
|
| + if (!matches)
|
| + return null;
|
| +
|
| + var hostPortString = matches[1];
|
| +
|
| + matches = /^(.*):(\d+)$/.exec(hostPortString);
|
| + if (!matches)
|
| + return null;
|
| +
|
| + var result = {host: matches[1], port: matches[2]};
|
| +
|
| + // Strip brackets off of IPv6 literals.
|
| + matches = /^\[(.*)\]$/.exec(result.host);
|
| + if (matches)
|
| + result.host = matches[1];
|
| +
|
| + return result;
|
| + }
|
| +
|
| + return ProxyView;
|
| +})();
|
| +
|
|
|