Skip to content

Commit f9b739e

Browse files
rubysmcollina
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 <[email protected]> Reviewed-By: Ron Korving <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Matteo Collina <[email protected]>
1 parent 19bc893 commit f9b739e

File tree

5 files changed

+79
-19
lines changed

5 files changed

+79
-19
lines changed

doc/api/http.md

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

17981798
## http.get(options[, callback])
1799+
## http.get(url[, options][, callback])
17991800
<!-- YAML
18001801
added: v0.3.6
18011802
changes:
1803+
- version: REPLACEME
1804+
pr-url: https://github.com/nodejs/node/pull/21616
1805+
description: allow both url and options to be passed to `http.get()`
18021806
- version: v7.5.0
18031807
pr-url: https://github.com/nodejs/node/pull/10638
18041808
description: The `options` parameter can be a WHATWG `URL` object.
18051809
-->
18061810

1807-
* `options` {Object | string | URL} Accepts the same `options` as
1811+
* `url` {string | URL}
1812+
* `options` {Object} Accepts the same `options` as
18081813
[`http.request()`][], with the `method` always set to `GET`.
18091814
Properties that are inherited from the prototype are ignored.
18101815
* `callback` {Function}
@@ -1868,15 +1873,20 @@ Global instance of `Agent` which is used as the default for all HTTP client
18681873
requests.
18691874

18701875
## http.request(options[, callback])
1876+
## http.request(url[, options][, callback])
18711877
<!-- YAML
18721878
added: v0.3.6
18731879
changes:
1880+
- version: REPLACEME
1881+
pr-url: https://github.com/nodejs/node/pull/21616
1882+
description: allow both url and options to be passed to `http.request()`
18741883
- version: v7.5.0
18751884
pr-url: https://github.com/nodejs/node/pull/10638
18761885
description: The `options` parameter can be a WHATWG `URL` object.
18771886
-->
18781887

1879-
* `options` {Object | string | URL}
1888+
* `url` {string | URL}
1889+
* `options` {Object}
18801890
* `protocol` {string} Protocol to use. **Default:** `'http:'`.
18811891
* `host` {string} A domain name or IP address of the server to issue the
18821892
request to. **Default:** `'localhost'`.
@@ -1918,10 +1928,13 @@ changes:
19181928
Node.js maintains several connections per server to make HTTP requests.
19191929
This function allows one to transparently issue requests.
19201930

1921-
`options` can be an object, a string, or a [`URL`][] object. If `options` is a
1931+
`url` can be a string or a [`URL`][] object. If `url` is a
19221932
string, it is automatically parsed with [`new URL()`][]. If it is a [`URL`][]
19231933
object, it will be automatically converted to an ordinary `options` object.
19241934

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

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

+19-10
Original file line numberDiff line numberDiff line change
@@ -60,16 +60,16 @@ function validateHost(host, name) {
6060
}
6161

6262
let urlWarningEmitted = false;
63-
function ClientRequest(options, cb) {
63+
function ClientRequest(input, options, cb) {
6464
OutgoingMessage.call(this);
6565

66-
if (typeof options === 'string') {
67-
const urlStr = options;
66+
if (typeof input === 'string') {
67+
const urlStr = input;
6868
try {
69-
options = urlToOptions(new URL(urlStr));
69+
input = urlToOptions(new URL(urlStr));
7070
} catch (err) {
71-
options = url.parse(urlStr);
72-
if (!options.hostname) {
71+
input = url.parse(urlStr);
72+
if (!input.hostname) {
7373
throw err;
7474
}
7575
if (!urlWarningEmitted && !process.noDeprecation) {
@@ -80,14 +80,23 @@ function ClientRequest(options, cb) {
8080
'DeprecationWarning', 'DEP0109');
8181
}
8282
}
83-
} else if (options && options[searchParamsSymbol] &&
84-
options[searchParamsSymbol][searchParamsSymbol]) {
83+
} else if (input && input[searchParamsSymbol] &&
84+
input[searchParamsSymbol][searchParamsSymbol]) {
8585
// url.URL instance
86-
options = urlToOptions(options);
86+
input = urlToOptions(input);
8787
} else {
88-
options = util._extend({}, options);
88+
cb = options;
89+
options = input;
90+
input = null;
8991
}
9092

93+
if (typeof options === 'function') {
94+
cb = options;
95+
options = null;
96+
}
97+
98+
options = util._extend(input || {}, options || {});
99+
91100
var agent = options.agent;
92101
var defaultAgent = options._defaultAgent || Agent.globalAgent;
93102
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)