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.
6 * This view displays information on the proxy setup:
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.
13 var ProxyView
= (function() {
16 // We inherit from DivView.
17 var superClass
= DivView
;
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);
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
);
67 onProxySettingsChanged: function(proxySettings
) {
68 $(ProxyView
.ORIGINAL_SETTINGS_DIV_ID
).innerHTML
= '';
69 $(ProxyView
.EFFECTIVE_SETTINGS_DIV_ID
).innerHTML
= '';
70 this.updateSocksHints_(null);
75 // Both |original| and |effective| are dictionaries describing the
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
);
94 onBadProxiesChanged: function(badProxies
) {
95 $(ProxyView
.BAD_PROXIES_TBODY_ID
).innerHTML
= '';
96 setNodeDisplay($(ProxyView
.BAD_PROXIES_DIV_ID
),
97 badProxies
&& badProxies
.length
> 0);
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
);
118 updateSocksHints_: function(proxySettings
) {
119 setNodeDisplay($(ProxyView
.SOCKS_HINTS_DIV_ID
), false);
124 var socksProxy
= getSingleSocks5Proxy_(proxySettings
.single_proxy
);
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.
145 $(ProxyView
.SOCKS_HINTS_FLAG_DIV_ID
).innerText
= hostResolverRulesFlag
;
146 setNodeDisplay($(ProxyView
.SOCKS_HINTS_DIV_ID
), true);
150 function getSingleSocks5Proxy_(proxyList
) {
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];
163 var pattern
= /^socks5:\/\/(.*)$/;
164 var matches
= pattern
.exec(proxyString
);
169 var hostPortString
= matches
[1];
171 matches
= /^(.*):(\d+)$/.exec(hostPortString
);
175 var result
= {host
: matches
[1], port
: matches
[2]};
177 // Strip brackets off of IPv6 literals.
178 matches
= /^\[(.*)\]$/.exec(result
.host
);
180 result
.host
= matches
[1];