Skip to content

Commit 37369eb

Browse files
rubystargos
authored andcommitted
http: allow url and options to be passed to http*.request and http*.get
Fixes: #20795 PR-URL: #21616 Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com> Reviewed-By: Ron Korving <ron@ronkorving.nl> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Backport-PR-URL: #21880 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 38dd407 commit 37369eb

File tree

5 files changed

+77
-17
lines changed

5 files changed

+77
-17
lines changed

doc/api/http.md

+16-3
Original file line numberDiff line numberDiff line change
@@ -1794,15 +1794,20 @@ The `requestListener` is a function which is automatically
17941794
added to the [`'request'`][] event.
17951795

17961796
## http.get(options[, callback])
1797+
## http.get(url[, options][, callback])
17971798
<!-- YAML
17981799
added: v0.3.6
17991800
changes:
1801+
- version: REPLACEME
1802+
pr-url: https://github.com/nodejs/node/pull/21616
1803+
description: allow both url and options to be passed to `http.get()`
18001804
- version: v7.5.0
18011805
pr-url: https://github.com/nodejs/node/pull/10638
18021806
description: The `options` parameter can be a WHATWG `URL` object.
18031807
-->
18041808

1805-
* `options` {Object | string | URL} Accepts the same `options` as
1809+
* `url` {string | URL}
1810+
* `options` {Object} Accepts the same `options` as
18061811
[`http.request()`][], with the `method` always set to `GET`.
18071812
Properties that are inherited from the prototype are ignored.
18081813
* `callback` {Function}
@@ -1866,15 +1871,20 @@ Global instance of `Agent` which is used as the default for all HTTP client
18661871
requests.
18671872

18681873
## http.request(options[, callback])
1874+
## http.request(url[, options][, callback])
18691875
<!-- YAML
18701876
added: v0.3.6
18711877
changes:
1878+
- version: REPLACEME
1879+
pr-url: https://github.com/nodejs/node/pull/21616
1880+
description: allow both url and options to be passed to `http.request()`
18721881
- version: v7.5.0
18731882
pr-url: https://github.com/nodejs/node/pull/10638
18741883
description: The `options` parameter can be a WHATWG `URL` object.
18751884
-->
18761885

1877-
* `options` {Object | string | URL}
1886+
* `url` {string | URL}
1887+
* `options` {Object}
18781888
* `protocol` {string} Protocol to use. **Default:** `'http:'`.
18791889
* `host` {string} A domain name or IP address of the server to issue the
18801890
request to. **Default:** `'localhost'`.
@@ -1916,10 +1926,13 @@ changes:
19161926
Node.js maintains several connections per server to make HTTP requests.
19171927
This function allows one to transparently issue requests.
19181928

1919-
`options` can be an object, a string, or a [`URL`][] object. If `options` is a
1929+
`url` can be a string or a [`URL`][] object. If `url` is a
19201930
string, it is automatically parsed with [`url.parse()`][]. If it is a [`URL`][]
19211931
object, it will be automatically converted to an ordinary `options` object.
19221932

1933+
If both `url` and `options` are specified, the objects are merged, with the
1934+
`options` properties taking precedence.
1935+
19231936
The optional `callback` parameter will be added as a one-time listener for
19241937
the [`'response'`][] event.
19251938

doc/api/https.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,19 @@ https.createServer(options, (req, res) => {
112112
```
113113

114114
## https.get(options[, callback])
115+
## https.get(url[, options][, callback])
115116
<!-- YAML
116117
added: v0.3.6
117118
changes:
119+
- version: REPLACEME
120+
pr-url: https://github.com/nodejs/node/pull/21616
121+
description: allow both url and options to be passed to `https.get()`
118122
- version: v7.5.0
119123
pr-url: https://github.com/nodejs/node/pull/10638
120124
description: The `options` parameter can be a WHATWG `URL` object.
121125
-->
122-
- `options` {Object | string | URL} Accepts the same `options` as
126+
- `url` {string | URL}
127+
- `options` {Object} Accepts the same `options` as
123128
[`https.request()`][], with the `method` always set to `GET`.
124129
- `callback` {Function}
125130

@@ -155,17 +160,22 @@ added: v0.5.9
155160
Global instance of [`https.Agent`][] for all HTTPS client requests.
156161

157162
## https.request(options[, callback])
163+
## https.request(url[, options][, callback])
158164
<!-- YAML
159165
added: v0.3.6
160166
changes:
167+
- version: REPLACEME
168+
pr-url: https://github.com/nodejs/node/pull/21616
169+
description: allow both url and options to be passed to `https.request()`
161170
- version: v9.3.0
162171
pr-url: https://github.com/nodejs/node/pull/14903
163172
description: The `options` parameter can now include `clientCertEngine`.
164173
- version: v7.5.0
165174
pr-url: https://github.com/nodejs/node/pull/10638
166175
description: The `options` parameter can be a WHATWG `URL` object.
167176
-->
168-
- `options` {Object | string | URL} Accepts all `options` from
177+
- `url` {string | URL}
178+
- `options` {Object} Accepts all `options` from
169179
[`http.request()`][], with some differences in default values:
170180
- `protocol` **Default:** `'https:'`
171181
- `port` **Default:** `443`

lib/_http_client.js

+17-8
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,31 @@ function validateHost(host, name) {
6060
return host;
6161
}
6262

63-
function ClientRequest(options, cb) {
63+
function ClientRequest(input, options, cb) {
6464
OutgoingMessage.call(this);
6565

66-
if (typeof options === 'string') {
67-
options = url.parse(options);
68-
if (!options.hostname) {
66+
if (typeof input === 'string') {
67+
input = url.parse(input);
68+
if (!input.hostname) {
6969
throw new ERR_INVALID_DOMAIN_NAME();
7070
}
71-
} else if (options && options[searchParamsSymbol] &&
72-
options[searchParamsSymbol][searchParamsSymbol]) {
71+
} else if (input && input[searchParamsSymbol] &&
72+
input[searchParamsSymbol][searchParamsSymbol]) {
7373
// url.URL instance
74-
options = urlToOptions(options);
74+
input = urlToOptions(input);
7575
} else {
76-
options = util._extend({}, options);
76+
cb = options;
77+
options = input;
78+
input = null;
7779
}
7880

81+
if (typeof options === 'function') {
82+
cb = options;
83+
options = null;
84+
}
85+
86+
options = util._extend(input || {}, options || {});
87+
7988
var agent = options.agent;
8089
var defaultAgent = options._defaultAgent || Agent.globalAgent;
8190
if (agent === false) {

lib/http.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,12 @@ function createServer(opts, requestListener) {
3737
return new Server(opts, requestListener);
3838
}
3939

40-
function request(options, cb) {
41-
return new ClientRequest(options, cb);
40+
function request(url, options, cb) {
41+
return new ClientRequest(url, options, cb);
4242
}
4343

44-
function get(options, cb) {
45-
var req = request(options, cb);
44+
function get(url, options, cb) {
45+
var req = request(url, options, cb);
4646
req.end();
4747
return req;
4848
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const http = require('http');
5+
6+
// Test providing both a url and options, with the options partially
7+
// replacing address and port portions of the URL provided.
8+
{
9+
const server = http.createServer(
10+
common.mustCall((req, res) => {
11+
assert.strictEqual(req.url, '/testpath');
12+
res.end();
13+
server.close();
14+
})
15+
);
16+
server.listen(
17+
0,
18+
common.mustCall(() => {
19+
http.get(
20+
'http://example.com/testpath',
21+
{ hostname: 'localhost', port: server.address().port },
22+
common.mustCall((res) => {
23+
res.resume();
24+
})
25+
);
26+
})
27+
);
28+
}

0 commit comments

Comments
 (0)