Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / resources / net_internals / proxy_view.js
blobef9709dde4fc9d0c086107fd6272c6e954c3588d
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
3 // found in the LICENSE file.
5 /**
6  * This view displays information on the proxy setup:
7  *
8  *   - Shows the current proxy settings.
9  *   - Has a button to reload these settings.
10  *   - Shows the list of proxy hostnames that are cached as "bad".
11  *   - Has a button to clear the cached bad proxies.
12  */
13 var ProxyView = (function() {
14   'use strict';
16   // We inherit from DivView.
17   var superClass = DivView;
19   /**
20    * @constructor
21    */
22   function ProxyView() {
23     assertFirstConstructorCall(ProxyView);
25     // Call superclass's constructor.
26     superClass.call(this, ProxyView.MAIN_BOX_ID);
28     // Hook up the UI components.
29     $(ProxyView.RELOAD_SETTINGS_BUTTON_ID).onclick =
30         g_browser.sendReloadProxySettings.bind(g_browser);
31     $(ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID).onclick =
32         g_browser.sendClearBadProxies.bind(g_browser);
34     // Register to receive proxy information as it changes.
35     g_browser.addProxySettingsObserver(this, true);
36     g_browser.addBadProxiesObserver(this, true);
37   }
39   ProxyView.TAB_ID = 'tab-handle-proxy';
40   ProxyView.TAB_NAME = 'Proxy';
41   ProxyView.TAB_HASH = '#proxy';
43   // IDs for special HTML elements in proxy_view.html
44   ProxyView.MAIN_BOX_ID = 'proxy-view-tab-content';
45   ProxyView.ORIGINAL_SETTINGS_DIV_ID = 'proxy-view-original-settings';
46   ProxyView.EFFECTIVE_SETTINGS_DIV_ID = 'proxy-view-effective-settings';
47   ProxyView.ORIGINAL_CONTENT_DIV_ID = 'proxy-view-original-content';
48   ProxyView.EFFECTIVE_CONTENT_DIV_ID = 'proxy-view-effective-content';
49   ProxyView.RELOAD_SETTINGS_BUTTON_ID = 'proxy-view-reload-settings';
50   ProxyView.BAD_PROXIES_DIV_ID = 'proxy-view-bad-proxies-div';
51   ProxyView.BAD_PROXIES_TBODY_ID = 'proxy-view-bad-proxies-tbody';
52   ProxyView.CLEAR_BAD_PROXIES_BUTTON_ID = 'proxy-view-clear-bad-proxies';
53   ProxyView.SOCKS_HINTS_DIV_ID = 'proxy-view-socks-hints';
54   ProxyView.SOCKS_HINTS_FLAG_DIV_ID = 'proxy-view-socks-hints-flag';
56   cr.addSingletonGetter(ProxyView);
58   ProxyView.prototype = {
59     // Inherit the superclass's methods.
60     __proto__: superClass.prototype,
62     onLoadLogFinish: function(data) {
63       return this.onProxySettingsChanged(data.proxySettings) &&
64              this.onBadProxiesChanged(data.badProxies);
65     },
67     onProxySettingsChanged: function(proxySettings) {
68       $(ProxyView.ORIGINAL_SETTINGS_DIV_ID).innerHTML = '';
69       $(ProxyView.EFFECTIVE_SETTINGS_DIV_ID).innerHTML = '';
70       this.updateSocksHints_(null);
72       if (!proxySettings)
73         return false;
75       // Both |original| and |effective| are dictionaries describing the
76       // settings.
77       var original = proxySettings.original;
78       var effective = proxySettings.effective;
80       var originalStr = proxySettingsToString(original);
81       var effectiveStr = proxySettingsToString(effective);
83       setNodeDisplay($(ProxyView.ORIGINAL_CONTENT_DIV_ID),
84                      originalStr != effectiveStr);
86       $(ProxyView.ORIGINAL_SETTINGS_DIV_ID).innerText = originalStr;
87       $(ProxyView.EFFECTIVE_SETTINGS_DIV_ID).innerText = effectiveStr;
89       this.updateSocksHints_(effective);
91       return true;
92     },
94     onBadProxiesChanged: function(badProxies) {
95       $(ProxyView.BAD_PROXIES_TBODY_ID).innerHTML = '';
96       setNodeDisplay($(ProxyView.BAD_PROXIES_DIV_ID),
97                      badProxies && badProxies.length > 0);
99       if (!badProxies)
100         return false;
102       // Add a table row for each bad proxy entry.
103       for (var i = 0; i < badProxies.length; ++i) {
104         var entry = badProxies[i];
105         var badUntilDate = timeutil.convertTimeTicksToDate(entry.bad_until);
107         var tr = addNode($(ProxyView.BAD_PROXIES_TBODY_ID), 'tr');
109         var nameCell = addNode(tr, 'td');
110         var badUntilCell = addNode(tr, 'td');
112         addTextNode(nameCell, entry.proxy_uri);
113         timeutil.addNodeWithDate(badUntilCell, badUntilDate);
114       }
115       return true;
116     },
118     updateSocksHints_: function(proxySettings) {
119       setNodeDisplay($(ProxyView.SOCKS_HINTS_DIV_ID), false);
121       if (!proxySettings)
122         return;
124       var socksProxy = getSingleSocks5Proxy_(proxySettings.single_proxy);
125       if (!socksProxy)
126         return;
128       // Suggest a recommended --host-resolver-rules.
129       // NOTE: This does not compensate for any proxy bypass rules. If the
130       // proxy settings include proxy bypasses the user may need to expand the
131       // exclusions for host resolving.
132       var hostResolverRules = 'MAP * ~NOTFOUND , EXCLUDE ' + socksProxy.host;
133       var hostResolverRulesFlag = '--host-resolver-rules="' +
134                                   hostResolverRules + '"';
136       // TODO(eroman): On Linux the ClientInfo.command_line is wrong in that it
137       // doesn't include any quotes around the parameters. This means the
138       // string search above is going to fail :(
139       if (ClientInfo.command_line &&
140           ClientInfo.command_line.indexOf(hostResolverRulesFlag) != -1) {
141         // Chrome is already using the suggested resolver rules.
142         return;
143       }
145       $(ProxyView.SOCKS_HINTS_FLAG_DIV_ID).innerText = hostResolverRulesFlag;
146       setNodeDisplay($(ProxyView.SOCKS_HINTS_DIV_ID), true);
147     }
148   };
150   function getSingleSocks5Proxy_(proxyList) {
151     var proxyString;
152     if (typeof proxyList == 'string') {
153       // Older versions of Chrome passed single_proxy as a string.
154       // TODO(eroman): This behavior changed in M27. Support for older logs can
155       //               safely be removed circa M29.
156       proxyString = proxyList;
157     } else if (Array.isArray(proxyList) && proxyList.length == 1) {
158       proxyString = proxyList[0];
159     } else {
160       return null;
161     }
163     var pattern = /^socks5:\/\/(.*)$/;
164     var matches = pattern.exec(proxyString);
166     if (!matches)
167       return null;
169     var hostPortString = matches[1];
171     matches = /^(.*):(\d+)$/.exec(hostPortString);
172     if (!matches)
173       return null;
175     var result = {host: matches[1], port: matches[2]};
177     // Strip brackets off of IPv6 literals.
178     matches = /^\[(.*)\]$/.exec(result.host);
179     if (matches)
180       result.host = matches[1];
182     return result;
183   }
185   return ProxyView;
186 })();