Skip to content

Commit 24def19

Browse files
jasnellMylesBorins
authored andcommitted
url: adding WHATWG URL support
Implements WHATWG URL support. Example: ``` var u = new url.URL('http://example.org'); ``` Many, many other commits improving the implementation have been squashed into this backport PR. They are not listed separately here for brevity. Backport-PR-URL: #17365 PR-URL: #7448 Reviewed-By: Ilkka Myller <[email protected]>
1 parent 60b10f0 commit 24def19

File tree

57 files changed

+16345
-75
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+16345
-75
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const url = require('url');
4+
const URL = url.URL;
5+
const assert = require('assert');
6+
const inputs = require('../fixtures/url-inputs.js').urls;
7+
8+
const bench = common.createBenchmark(main, {
9+
type: Object.keys(inputs),
10+
method: ['legacy', 'whatwg'],
11+
n: [1e5]
12+
});
13+
14+
// At the time of writing, when using a passed property name to index
15+
// the object, Crankshaft would generate a LoadKeyedGeneric even when it
16+
// remains a constant in the function, so here we must use the literal
17+
// instead to get a LoadNamedField.
18+
function useLegacy(n, input) {
19+
const obj = url.parse(input);
20+
const noDead = {
21+
protocol: obj.protocol,
22+
auth: obj.auth,
23+
host: obj.host,
24+
hostname: obj.hostname,
25+
port: obj.port,
26+
pathname: obj.pathname,
27+
search: obj.search,
28+
hash: obj.hash
29+
};
30+
// It's necessary to assign the values to an object
31+
// to avoid loop invariant code motion.
32+
bench.start();
33+
for (var i = 0; i < n; i += 1) {
34+
noDead.protocol = obj.protocol;
35+
noDead.auth = obj.auth;
36+
noDead.host = obj.host;
37+
noDead.hostname = obj.hostname;
38+
noDead.port = obj.port;
39+
noDead.pathname = obj.pathname;
40+
noDead.search = obj.search;
41+
noDead.hash = obj.hash;
42+
}
43+
bench.end(n);
44+
return noDead;
45+
}
46+
47+
function useWHATWG(n, input) {
48+
const obj = new URL(input);
49+
const noDead = {
50+
protocol: obj.protocol,
51+
auth: `${obj.username}:${obj.password}`,
52+
host: obj.host,
53+
hostname: obj.hostname,
54+
port: obj.port,
55+
pathname: obj.pathname,
56+
search: obj.search,
57+
hash: obj.hash
58+
};
59+
bench.start();
60+
for (var i = 0; i < n; i += 1) {
61+
noDead.protocol = obj.protocol;
62+
noDead.auth = `${obj.username}:${obj.password}`;
63+
noDead.host = obj.host;
64+
noDead.hostname = obj.hostname;
65+
noDead.port = obj.port;
66+
noDead.pathname = obj.pathname;
67+
noDead.search = obj.search;
68+
noDead.hash = obj.hash;
69+
}
70+
bench.end(n);
71+
return noDead;
72+
}
73+
74+
function main(conf) {
75+
const type = conf.type;
76+
const n = conf.n | 0;
77+
const method = conf.method;
78+
79+
const input = inputs[type];
80+
if (!input) {
81+
throw new Error('Unknown input type');
82+
}
83+
84+
var noDead; // Avoid dead code elimination.
85+
switch (method) {
86+
case 'legacy':
87+
noDead = useLegacy(n, input);
88+
break;
89+
case 'whatwg':
90+
noDead = useWHATWG(n, input);
91+
break;
92+
default:
93+
throw new Error('Unknown method');
94+
}
95+
96+
assert.ok(noDead);
97+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const url = require('url');
4+
const URL = url.URL;
5+
const assert = require('assert');
6+
const inputs = require('../fixtures/url-inputs.js').urls;
7+
8+
const bench = common.createBenchmark(main, {
9+
type: Object.keys(inputs),
10+
method: ['legacy', 'whatwg'],
11+
n: [1e5]
12+
});
13+
14+
function useLegacy(n, input) {
15+
var noDead = url.parse(input);
16+
bench.start();
17+
for (var i = 0; i < n; i += 1) {
18+
noDead = url.parse(input);
19+
}
20+
bench.end(n);
21+
return noDead;
22+
}
23+
24+
function useWHATWG(n, input) {
25+
var noDead = new URL(input);
26+
bench.start();
27+
for (var i = 0; i < n; i += 1) {
28+
noDead = new URL(input);
29+
}
30+
bench.end(n);
31+
return noDead;
32+
}
33+
34+
function main(conf) {
35+
const type = conf.type;
36+
const n = conf.n | 0;
37+
const method = conf.method;
38+
39+
const input = inputs[type];
40+
if (!input) {
41+
throw new Error('Unknown input type');
42+
}
43+
44+
var noDead; // Avoid dead code elimination.
45+
switch (method) {
46+
case 'legacy':
47+
noDead = useLegacy(n, input);
48+
break;
49+
case 'whatwg':
50+
noDead = useWHATWG(n, input);
51+
break;
52+
default:
53+
throw new Error('Unknown method');
54+
}
55+
56+
assert.ok(noDead);
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const { URLSearchParams } = require('url');
4+
const querystring = require('querystring');
5+
const inputs = require('../fixtures/url-inputs.js').searchParams;
6+
7+
const bench = common.createBenchmark(main, {
8+
type: Object.keys(inputs),
9+
method: ['legacy', 'whatwg'],
10+
n: [1e6]
11+
});
12+
13+
function useLegacy(n, input) {
14+
querystring.parse(input);
15+
bench.start();
16+
for (var i = 0; i < n; i += 1) {
17+
querystring.parse(input);
18+
}
19+
bench.end(n);
20+
}
21+
22+
function useWHATWG(n, input) {
23+
new URLSearchParams(input);
24+
bench.start();
25+
for (var i = 0; i < n; i += 1) {
26+
new URLSearchParams(input);
27+
}
28+
bench.end(n);
29+
}
30+
31+
function main(conf) {
32+
const type = conf.type;
33+
const n = conf.n | 0;
34+
const method = conf.method;
35+
36+
const input = inputs[type];
37+
if (!input) {
38+
throw new Error('Unknown input type');
39+
}
40+
41+
switch (method) {
42+
case 'legacy':
43+
useLegacy(n, input);
44+
break;
45+
case 'whatwg':
46+
useWHATWG(n, input);
47+
break;
48+
default:
49+
throw new Error('Unknown method');
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const { URLSearchParams } = require('url');
4+
const querystring = require('querystring');
5+
const inputs = require('../fixtures/url-inputs.js').searchParams;
6+
7+
const bench = common.createBenchmark(main, {
8+
type: Object.keys(inputs),
9+
method: ['legacy', 'whatwg'],
10+
n: [1e6]
11+
});
12+
13+
function useLegacy(n, input, prop) {
14+
const obj = querystring.parse(input);
15+
querystring.stringify(obj);
16+
bench.start();
17+
for (var i = 0; i < n; i += 1) {
18+
querystring.stringify(obj);
19+
}
20+
bench.end(n);
21+
}
22+
23+
function useWHATWG(n, input, prop) {
24+
const obj = new URLSearchParams(input);
25+
obj.toString();
26+
bench.start();
27+
for (var i = 0; i < n; i += 1) {
28+
obj.toString();
29+
}
30+
bench.end(n);
31+
}
32+
33+
function main(conf) {
34+
const type = conf.type;
35+
const n = conf.n | 0;
36+
const method = conf.method;
37+
38+
const input = inputs[type];
39+
if (!input) {
40+
throw new Error('Unknown input type');
41+
}
42+
43+
switch (method) {
44+
case 'legacy':
45+
useLegacy(n, input);
46+
break;
47+
case 'whatwg':
48+
useWHATWG(n, input);
49+
break;
50+
default:
51+
throw new Error('Unknown method');
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const url = require('url');
4+
const URL = url.URL;
5+
const assert = require('assert');
6+
const inputs = require('../fixtures/url-inputs.js').urls;
7+
8+
const bench = common.createBenchmark(main, {
9+
type: Object.keys(inputs),
10+
method: ['legacy', 'whatwg'],
11+
n: [1e5]
12+
});
13+
14+
function useLegacy(n, input, prop) {
15+
const obj = url.parse(input);
16+
var noDead = url.format(obj);
17+
bench.start();
18+
for (var i = 0; i < n; i += 1) {
19+
noDead = url.format(obj);
20+
}
21+
bench.end(n);
22+
return noDead;
23+
}
24+
25+
function useWHATWG(n, input, prop) {
26+
const obj = new URL(input);
27+
var noDead = obj.toString();
28+
bench.start();
29+
for (var i = 0; i < n; i += 1) {
30+
noDead = obj.toString();
31+
}
32+
bench.end(n);
33+
return noDead;
34+
}
35+
36+
function main(conf) {
37+
const type = conf.type;
38+
const n = conf.n | 0;
39+
const method = conf.method;
40+
41+
const input = inputs[type];
42+
if (!input) {
43+
throw new Error('Unknown input type');
44+
}
45+
46+
var noDead; // Avoid dead code elimination.
47+
switch (method) {
48+
case 'legacy':
49+
noDead = useLegacy(n, input);
50+
break;
51+
case 'whatwg':
52+
noDead = useWHATWG(n, input);
53+
break;
54+
default:
55+
throw new Error('Unknown method');
56+
}
57+
58+
assert.ok(noDead);
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
'use strict';
2+
const common = require('../common.js');
3+
const assert = require('assert');
4+
const { URLSearchParams } = require('url');
5+
6+
const bench = common.createBenchmark(main, {
7+
method: ['forEach', 'iterator'],
8+
n: [1e6]
9+
});
10+
11+
const str = 'one=single&two=first&three=first&two=2nd&three=2nd&three=3rd';
12+
13+
function forEach(n) {
14+
const params = new URLSearchParams(str);
15+
const noDead = [];
16+
const cb = (val, key) => {
17+
noDead[0] = key;
18+
noDead[1] = val;
19+
};
20+
21+
bench.start();
22+
for (var i = 0; i < n; i += 1)
23+
params.forEach(cb);
24+
bench.end(n);
25+
26+
assert.strictEqual(noDead[0], 'three');
27+
assert.strictEqual(noDead[1], '3rd');
28+
}
29+
30+
function iterator(n) {
31+
const params = new URLSearchParams(str);
32+
const noDead = [];
33+
34+
bench.start();
35+
for (var i = 0; i < n; i += 1) {
36+
for (const pair of params) {
37+
noDead[0] = pair[0];
38+
noDead[1] = pair[1];
39+
}
40+
}
41+
bench.end(n);
42+
43+
assert.strictEqual(noDead[0], 'three');
44+
assert.strictEqual(noDead[1], '3rd');
45+
}
46+
47+
function main(conf) {
48+
const method = conf.method;
49+
const n = conf.n | 0;
50+
51+
switch (method) {
52+
case 'forEach':
53+
forEach(n);
54+
break;
55+
case 'iterator':
56+
iterator(n);
57+
break;
58+
default:
59+
throw new Error('Unknown method');
60+
}
61+
}

0 commit comments

Comments
 (0)