Skip to content

Commit 2f9fdc4

Browse files
jasnellitaloacasas
authored andcommitted
url: allow use of URL with http.request and https.request
PR-URL: #10638 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Evan Lucas <[email protected]> Reviewed-By: Michal Zasso <[email protected]> Reviewed-By: Joyee Cheung <[email protected]>
1 parent 3adda4b commit 2f9fdc4

File tree

6 files changed

+61
-5
lines changed

6 files changed

+61
-5
lines changed

lib/_http_client.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const debug = common.debug;
1313
const OutgoingMessage = require('_http_outgoing').OutgoingMessage;
1414
const Agent = require('_http_agent');
1515
const Buffer = require('buffer').Buffer;
16-
16+
const urlToOptions = require('internal/url').urlToOptions;
1717

1818
// The actual list of disallowed characters in regexp form is more like:
1919
// /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
@@ -52,6 +52,8 @@ function ClientRequest(options, cb) {
5252
if (!options.hostname) {
5353
throw new Error('Unable to determine the domain name');
5454
}
55+
} else if (options instanceof url.URL) {
56+
options = urlToOptions(options);
5557
} else {
5658
options = util._extend({}, options);
5759
}

lib/https.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const http = require('http');
88
const util = require('util');
99
const inherits = util.inherits;
1010
const debug = util.debuglog('https');
11+
const urlToOptions = require('internal/url').urlToOptions;
1112

1213
function Server(opts, requestListener) {
1314
if (!(this instanceof Server)) return new Server(opts, requestListener);
@@ -196,6 +197,8 @@ exports.request = function request(options, cb) {
196197
if (!options.hostname) {
197198
throw new Error('Unable to determine the domain name');
198199
}
200+
} else if (options instanceof url.URL) {
201+
options = urlToOptions(options);
199202
} else {
200203
options = util._extend({}, options);
201204
}

lib/internal/url.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,9 +1019,33 @@ function domainToUnicode(domain) {
10191019
return binding.domainToUnicode(String(domain));
10201020
}
10211021

1022+
// Utility function that converts a URL object into an ordinary
1023+
// options object as expected by the http.request and https.request
1024+
// APIs.
1025+
function urlToOptions(url) {
1026+
var options = {
1027+
protocol: url.protocol,
1028+
host: url.host,
1029+
hostname: url.hostname,
1030+
hash: url.hash,
1031+
search: url.search,
1032+
pathname: url.pathname,
1033+
path: `${url.pathname}${url.search}`,
1034+
href: url.href
1035+
};
1036+
if (url.port !== '') {
1037+
options.port = Number(url.port);
1038+
}
1039+
if (url.username || url.password) {
1040+
options.auth = `${url.username}:${url.password}`;
1041+
}
1042+
return options;
1043+
}
1044+
10221045
exports.URL = URL;
10231046
exports.URLSearchParams = URLSearchParams;
10241047
exports.originFor = originFor;
10251048
exports.domainToASCII = domainToASCII;
10261049
exports.domainToUnicode = domainToUnicode;
10271050
exports.encodeAuth = encodeAuth;
1051+
exports.urlToOptions = urlToOptions;

test/parallel/test-http-client-get-url.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
const common = require('../common');
33
const assert = require('assert');
44
const http = require('http');
5+
const url = require('url');
6+
const URL = url.URL;
57

68
var server = http.createServer(common.mustCall(function(req, res) {
79
assert.equal('GET', req.method);
@@ -10,8 +12,11 @@ var server = http.createServer(common.mustCall(function(req, res) {
1012
res.write('hello\n');
1113
res.end();
1214
server.close();
13-
}));
15+
}, 3));
1416

1517
server.listen(0, function() {
16-
http.get(`http://127.0.0.1:${this.address().port}/foo?bar`);
18+
const u = `http://127.0.0.1:${this.address().port}/foo?bar`;
19+
http.get(u);
20+
http.get(url.parse(u));
21+
http.get(new URL(u));
1722
});

test/parallel/test-https-client-get-url.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ if (!common.hasCrypto) {
1212
const https = require('https');
1313

1414
const fs = require('fs');
15+
const url = require('url');
16+
const URL = url.URL;
1517

1618
var options = {
1719
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
@@ -25,8 +27,11 @@ var server = https.createServer(options, common.mustCall(function(req, res) {
2527
res.write('hello\n');
2628
res.end();
2729
server.close();
28-
}));
30+
}, 3));
2931

3032
server.listen(0, function() {
31-
https.get(`https://127.0.0.1:${this.address().port}/foo?bar`);
33+
const u = `https://127.0.0.1:${this.address().port}/foo?bar`;
34+
https.get(u);
35+
https.get(url.parse(u));
36+
https.get(new URL(u));
3237
});

test/parallel/test-whatwg-url-properties.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
// Flags: --expose-internals
12
'use strict';
23

34
require('../common');
45

56
const URL = require('url').URL;
67
const assert = require('assert');
8+
const urlToOptions = require('internal/url').urlToOptions;
79

810
const url = new URL('http://user:[email protected]:21/aaa/zzz?l=24#test');
911
const oldParams = url.searchParams; // for test of [SameObject]
@@ -125,3 +127,18 @@ assert.strictEqual(url.toString(),
125127
'https://user2:[email protected]:23/aaa/bbb?k=99#abcd');
126128
assert.strictEqual((delete url.searchParams), true);
127129
assert.strictEqual(url.searchParams, oldParams);
130+
131+
// Test urlToOptions
132+
{
133+
const opts =
134+
urlToOptions(new URL('http://user:[email protected]:21/aaa/zzz?l=24#test'));
135+
assert.strictEqual(opts instanceof URL, false);
136+
assert.strictEqual(opts.protocol, 'http:');
137+
assert.strictEqual(opts.auth, 'user:pass');
138+
assert.strictEqual(opts.hostname, 'foo.bar.com');
139+
assert.strictEqual(opts.port, 21);
140+
assert.strictEqual(opts.path, '/aaa/zzz?l=24');
141+
assert.strictEqual(opts.pathname, '/aaa/zzz');
142+
assert.strictEqual(opts.search, '?l=24');
143+
assert.strictEqual(opts.hash, '#test');
144+
}

0 commit comments

Comments
 (0)