Skip to content

Commit 6275858

Browse files
fujunweirogerwang
authored andcommitted
Fix nwjs#916: support pac_url and auto proxy detection
Add test cases for pac url. (cherry picked from commit 206df0d)
1 parent 3c61ca9 commit 6275858

File tree

7 files changed

+126
-26
lines changed

7 files changed

+126
-26
lines changed

docs/References/App.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,12 @@ These 2 functions crashes the browser process and the renderer process respectiv
6262

6363
Query the proxy to be used for loading `url` in DOM. The return value is in the same format used in [PAC](http://en.wikipedia.org/wiki/Proxy_auto-config) (e.g. "DIRECT", "PROXY localhost:8080").
6464

65-
## App.setProxyConfig(config)
65+
## App.setProxyConfig(config, pac_url)
6666

6767
* `config` `{String}` Proxy rules
68+
* `pac_url` `{String}` PAC url
6869

69-
Set the proxy config which the web engine will be used to request network resources.
70+
Set the proxy config which the web engine will be used to request network resources or PAC url to detect proxy automatically.
7071

7172
Rule (copied from [`net/proxy/proxy_config.h`](https://github.com/nwjs/chromium.src/blob/nw13/net/proxy/proxy_config.h))
7273

src/api/nw_app.idl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace nw.App {
1919
static void closeAllWindows();
2020
static void clearCache();
2121
static void clearAppCache(DOMString manifest_url);
22-
static void setProxyConfig(DOMString config);
22+
static void setProxyConfig(DOMString config, optional DOMString pac_url);
2323
[nocompile] static DOMString getProxyForURL(DOMString url);
2424
[nocompile] static void addOriginAccessWhitelistEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);
2525
[nocompile] static void removeOriginAccessWhitelistEntry(DOMString sourceOrigin, DOMString destinationProtocol, DOMString destinationHost, boolean allowDestinationSubdomains);

src/api/nw_app_api.cc

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "chrome/browser/devtools/devtools_window.h"
99
#include "chrome/browser/extensions/devtools_util.h"
1010
#include "chrome/browser/extensions/extension_service.h"
11+
#include "content/nw/src/api/nw_app.h"
1112
#include "content/nw/src/nw_base.h"
1213
#include "content/public/browser/render_process_host.h"
1314
#include "content/public/browser/render_view_host.h"
@@ -24,6 +25,8 @@
2425
#include "net/url_request/url_request_context.h"
2526
#include "net/url_request/url_request_context_getter.h"
2627

28+
using namespace extensions::nwapi::nw__app;
29+
2730
namespace {
2831
void SetProxyConfigCallback(
2932
base::WaitableEvent* done,
@@ -150,13 +153,27 @@ NwAppSetProxyConfigFunction::~NwAppSetProxyConfigFunction() {
150153
}
151154

152155
bool NwAppSetProxyConfigFunction::RunNWSync(base::ListValue* response, std::string* error) {
153-
std::string proxy_config;
154-
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &proxy_config));
156+
net::ProxyConfig config;
157+
std::unique_ptr<nwapi::nw__app::SetProxyConfig::Params> params(
158+
nwapi::nw__app::SetProxyConfig::Params::Create(*args_));
159+
EXTENSION_FUNCTION_VALIDATE(params.get());
160+
161+
std::string pac_url = params->pac_url.get() ? *params->pac_url : "";
162+
if (!pac_url.empty()) {
163+
if (pac_url == "<direct>")
164+
config = net::ProxyConfig::CreateDirect();
165+
else if (pac_url == "<auto>")
166+
config = net::ProxyConfig::CreateAutoDetect();
167+
else
168+
config = net::ProxyConfig::CreateFromCustomPacURL(GURL(pac_url));
169+
} else {
170+
std::string proxy_config;
171+
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &proxy_config));
172+
config.proxy_rules().ParseFromString(proxy_config);
173+
}
155174

156175
base::ThreadRestrictions::ScopedAllowWait allow_wait;
157176

158-
net::ProxyConfig config;
159-
config.proxy_rules().ParseFromString(proxy_config);
160177
content::RenderProcessHost* render_process_host = GetSenderWebContents()->GetRenderProcessHost();
161178
net::URLRequestContextGetter* context_getter =
162179
render_process_host->GetStoragePartition()->GetURLRequestContext();

test/sanity/app-getproxyforurl/bg.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(function(){
2+
const http = require('http');
3+
let id = 1;
4+
5+
// Create an HTTP server
6+
var srv = http.createServer( (req, res) => {
7+
res.writeHead(200, {'Content-Type': 'text/plain'});
8+
res.write('function FindProxyForURL(url, host) {\n');
9+
res.write(' if (host == \'www.port3128.com\')\n');
10+
res.write(' return \'PROXY localhost:3128\';\n');
11+
res.write(' else if (host == \'www.port4040.com\')\n');
12+
res.write(' return \'PROXY localhost:4040\';\n');
13+
res.write(' return "DIRECT";\n');
14+
res.write('}');
15+
res.end();
16+
});
17+
18+
srv.listen(nw.App.manifest.port, '127.0.0.1');
19+
})()
Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,54 @@
11
<!DOCTYPE html>
22
<html>
33
<head>
4-
<meta charset="utf-8">
5-
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6-
<title>App.getProxyForURL</title>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<title>App.getProxyForURL</title>
77
</head>
88
<body>
9-
<script>
10-
nw.App.setProxyConfig('dummy:8080');
11-
var proxy = nw.App.getProxyForURL('http://www.example.com/');
12-
var expect = 'PROXY dummy:8080';
13-
if (proxy === expect) {
14-
document.write('<h1 id="result">success</h1>');
15-
} else {
16-
document.write('<h1 id="result">failure: expect "' + expect + '" but get ' + proxy +'</h1>');
17-
}
18-
</script>
9+
<button id="pac" onclick="requestPac()">Request pac</button>
10+
<button id="open-devtools" onclick="openDevTools()">Open DevTools</button>
11+
<script>
12+
nw.App.setProxyConfig('dummy:8080');
13+
var proxy = nw.App.getProxyForURL('http://www.example.com/');
14+
var expect = 'PROXY dummy:8080';
15+
if (proxy === expect) {
16+
document.write('<h1 id="result">success</h1>');
17+
} else {
18+
document.write('<h1 id="result">failure: expect "' + expect + '" but get ' + proxy +'</h1>');
19+
}
20+
21+
// Reset Proxy
22+
nw.App.setProxyConfig("", "<direct>");
23+
24+
function requestPac() {
25+
var xhr = new XMLHttpRequest();
26+
xhr.open('GET', `http://localhost:${nw.App.manifest.port}/`, true);
27+
xhr.send();
28+
xhr.onload = ()=>{
29+
var b = new Buffer(xhr.responseText);
30+
var encodedUrl = "data:application/x-ns-proxy-autoconfig;base64," + b.toString('base64');
31+
nw.App.setProxyConfig('dummy:8080', encodedUrl);
32+
var proxy = nw.App.getProxyForURL('http://www.port3128.com/');
33+
var expect = 'PROXY localhost:3128';
34+
if (proxy === expect) {
35+
document.write('<h1 id="result2">success</h1>');
36+
} else {
37+
document.write('<h1 id="result2">failure: expect "' + expect + '" but get ' + proxy +'</h1>');
38+
}
39+
var proxy = nw.App.getProxyForURL('http://www.port4040.com/');
40+
var expect = 'PROXY localhost:4040';
41+
if (proxy === expect) {
42+
document.write('<h1 id="result3">success</h1>');
43+
} else {
44+
document.write('<h1 id="result3">failure: expect "' + expect + '" but get ' + proxy +'</h1>');
45+
}
46+
};
47+
}
48+
49+
function openDevTools() {
50+
chrome.developerPrivate.openDevTools({renderProcessId: -1, renderViewId: -1, extensionId: chrome.runtime.id});
51+
}
52+
</script>
1953
</body>
20-
</html>
54+
</html>

test/sanity/app-getproxyforurl/package.json

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,50 @@
11
import time
22
import os
3+
import sys
4+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
5+
from nw_util import *
36

47
from selenium import webdriver
58
from selenium.webdriver.chrome.options import Options
9+
from selenium.webdriver.common import utils
10+
11+
test_dir = os.path.dirname(os.path.abspath(__file__))
612
chrome_options = Options()
7-
chrome_options.add_argument("nwapp=" + os.path.dirname(os.path.abspath(__file__)))
13+
chrome_options.add_argument("nwapp=" + test_dir)
14+
15+
port = str(utils.free_port())
16+
17+
pkgjson = '''
18+
{
19+
"name": "app-getproxyforurl",
20+
"main": "index.html",
21+
"bg-script": "bg.js",
22+
"port": "%s"
23+
}
24+
''' % port
25+
26+
with open(os.path.join(test_dir, 'package.json'), 'w') as bg:
27+
bg.write(pkgjson)
828

929
driver = webdriver.Chrome(executable_path=os.environ['CHROMEDRIVER'], chrome_options=chrome_options)
30+
driver.implicitly_wait(2)
31+
time.sleep(1)
1032
try:
1133
print driver.current_url
34+
1235
time.sleep(1)
1336
result = driver.find_element_by_id('result')
1437
print result.get_attribute('innerHTML')
1538
assert("success" in result.get_attribute('innerHTML'))
39+
40+
wait_window_handles(driver, 1)
41+
switch_to_app(driver)
42+
driver.find_element_by_id('pac').click()
43+
wait_window_handles(driver, 1)
44+
result2 = driver.find_element_by_id('result2')
45+
assert("success" in result2.get_attribute('innerHTML'))
46+
wait_window_handles(driver, 1)
47+
result3 = driver.find_element_by_id('result3')
48+
assert("success" in result3.get_attribute('innerHTML'))
1649
finally:
1750
driver.quit()

0 commit comments

Comments
 (0)