Skip to content

Commit 0f62ee6

Browse files
committed
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 fd11586 commit 0f62ee6

File tree

6 files changed

+61
-5
lines changed

6 files changed

+61
-5
lines changed

lib/_http_client.js

+3-1
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
function ClientRequest(options, cb) {
1919
var self = this;
@@ -24,6 +24,8 @@ function ClientRequest(options, cb) {
2424
if (!options.hostname) {
2525
throw new Error('Unable to determine the domain name');
2626
}
27+
} else if (options instanceof url.URL) {
28+
options = urlToOptions(options);
2729
} else {
2830
options = util._extend({}, options);
2931
}

lib/https.js

+3
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);
@@ -192,6 +193,8 @@ exports.request = function request(options, cb) {
192193
if (!options.hostname) {
193194
throw new Error('Unable to determine the domain name');
194195
}
196+
} else if (options instanceof url.URL) {
197+
options = urlToOptions(options);
195198
} else {
196199
options = util._extend({}, options);
197200
}

lib/internal/url.js

+24
Original file line numberDiff line numberDiff line change
@@ -909,8 +909,32 @@ function domainToUnicode(domain) {
909909
return binding.domainToUnicode(String(domain));
910910
}
911911

912+
// Utility function that converts a URL object into an ordinary
913+
// options object as expected by the http.request and https.request
914+
// APIs.
915+
function urlToOptions(url) {
916+
var options = {
917+
protocol: url.protocol,
918+
host: url.host,
919+
hostname: url.hostname,
920+
hash: url.hash,
921+
search: url.search,
922+
pathname: url.pathname,
923+
path: `${url.pathname}${url.search}`,
924+
href: url.href
925+
};
926+
if (url.port !== '') {
927+
options.port = Number(url.port);
928+
}
929+
if (url.username || url.password) {
930+
options.auth = `${url.username}:${url.password}`;
931+
}
932+
return options;
933+
}
934+
912935
exports.URL = URL;
913936
exports.originFor = originFor;
914937
exports.domainToASCII = domainToASCII;
915938
exports.domainToUnicode = domainToUnicode;
916939
exports.encodeAuth = encodeAuth;
940+
exports.urlToOptions = urlToOptions;

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

+7-2
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

+7-2
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

+17
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)