Skip to content

Commit b04ea5a

Browse files
aduh95danielleadams
authored andcommitted
url: allow extension of user provided URL objects
PR-URL: #46989Fixes: #46981 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
1 parent 5fc2bb7 commit b04ea5a

3 files changed

Lines changed: 51 additions & 14 deletions

File tree

‎doc/api/url.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,6 +1226,11 @@ pathToFileURL('/some/path%.c'); // Correct: file:///some/path%25.c (POSI
12261226
added:
12271227
- v15.7.0
12281228
- v14.18.0
1229+
changes:
1230+
- version: REPLACEME
1231+
pr-url: https://github.com/nodejs/node/pull/46989
1232+
description: The returned object will also contain all the own enumerable
1233+
properties of the `url` argument.
12291234
-->
12301235
12311236
* `url` {URL} The [WHATWG URL][] object to convert to an options object.

‎lib/internal/url.js‎

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,27 +1136,32 @@ function domainToUnicode(domain) {
11361136
return_domainToUnicode(`${domain}`);
11371137
}
11381138

1139-
// Utility function that converts a URL object into an ordinary
1140-
// options object as expected by the http.request and https.request
1141-
// APIs.
1139+
/**
1140+
* Utility function that converts a URL object into an ordinary options object
1141+
* as expected by the `http.request` and `https.request` APIs.
1142+
* @param {URL} url
1143+
* @returns {Record<string, unknown>}
1144+
*/
11421145
functionurlToHttpOptions(url){
1146+
const{ hostname, pathname, port, username, password, search }=url;
11431147
constoptions={
1148+
__proto__: null,
1149+
...url,// In case the url object was extended by the user.
11441150
protocol: url.protocol,
1145-
hostname: typeofurl.hostname==='string'&&
1146-
StringPrototypeStartsWith(url.hostname,'[') ?
1147-
StringPrototypeSlice(url.hostname,1,-1) :
1148-
url.hostname,
1151+
hostname: typeofurl.hostname==='string'&&StringPrototypeStartsWith(hostname,'[') ?
1152+
StringPrototypeSlice(hostname,1,-1) :
1153+
hostname,
11491154
hash: url.hash,
1150-
search: url.search,
1151-
pathname: url.pathname,
1152-
path: `${url.pathname||''}${url.search||''}`,
1155+
search: search,
1156+
pathname: pathname,
1157+
path: `${pathname||''}${search||''}`,
11531158
href: url.href,
11541159
};
1155-
if(url.port!==''){
1156-
options.port=Number(url.port);
1160+
if(port!==''){
1161+
options.port=Number(port);
11571162
}
1158-
if(url.username||url.password){
1159-
options.auth=`${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`;
1163+
if(username||password){
1164+
options.auth=`${decodeURIComponent(username)}:${decodeURIComponent(password)}`;
11601165
}
11611166
returnoptions;
11621167
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
constcommon=require('../common');
4+
constassert=require('node:assert');
5+
consthttp=require('node:http');
6+
7+
constheaders={foo: 'Bar'};
8+
constserver=http.createServer(common.mustCall((req,res)=>{
9+
assert.strictEqual(req.url,'/ping?q=term');
10+
assert.strictEqual(req.headers?.foo,headers.foo);
11+
req.resume();
12+
req.on('end',()=>{
13+
res.writeHead(200);
14+
res.end('pong');
15+
});
16+
}));
17+
18+
server.listen(0,common.localhostIPv4,()=>{
19+
const{ address, port }=server.address();
20+
consturl=newURL(`http://${address}:${port}/ping?q=term`);
21+
url.headers=headers;
22+
constclientReq=http.request(url);
23+
clientReq.on('close',common.mustCall(()=>{
24+
server.close();
25+
}));
26+
clientReq.end();
27+
});

0 commit comments

Comments
 (0)