GeezerVison is showing github.com — url: allow extension of user provided URL objects · nodejs/node@0b565e8
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: doc/api/url.md +5Lines changed: 5 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -1226,6 +1226,11 @@ pathToFileURL('/some/path%.c'); // Correct: file:///some/path%25.c (POSI | 1226 | 1226 | added: | 1227 | 1227 | - v15.7.0 | 1228 | 1228 | - 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. | 1229 | 1234 | --> | 1230 | 1235 |
| 1231 | 1236 | * `url` {URL} The [WHATWG URL][] object to convert to an options object. | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/url.js +19-13Lines changed: 19 additions & 13 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -1126,26 +1126,32 @@ function domainToUnicode(domain) { | 1126 | 1126 | return _domainToUnicode(`${domain}`); | 1127 | 1127 | } | 1128 | 1128 |
| 1129 | | -// Utility function that converts a URL object into an ordinary | 1130 | | -// options object as expected by the http.request and https.request | 1131 | | -// APIs. | | 1129 | +/** | | 1130 | + * Utility function that converts a URL object into an ordinary options object | | 1131 | + * as expected by the `http.request` and `https.request` APIs. | | 1132 | + * @param {URL} url | | 1133 | + * @returns {Record<string, unknown>} | | 1134 | + */ | 1132 | 1135 | function urlToHttpOptions(url) { | | 1136 | + const { hostname, pathname, port, username, password, search } = url; | 1133 | 1137 | const options = { | | 1138 | + __proto__: null, | | 1139 | + ...url, // In case the url object was extended by the user. | 1134 | 1140 | protocol: url.protocol, | 1135 | | - hostname: url.hostname && StringPrototypeStartsWith(url.hostname, '[') ? | 1136 | | - StringPrototypeSlice(url.hostname, 1, -1) : | 1137 | | - url.hostname, | | 1141 | + hostname: hostname && StringPrototypeStartsWith(hostname, '[') ? | | 1142 | + StringPrototypeSlice(hostname, 1, -1) : | | 1143 | + hostname, | 1138 | 1144 | hash: url.hash, | 1139 | | - search: url.search, | 1140 | | - pathname: url.pathname, | 1141 | | - path: `${url.pathname || ''}${url.search || ''}`, | | 1145 | + search: search, | | 1146 | + pathname: pathname, | | 1147 | + path: `${pathname || ''}${search || ''}`, | 1142 | 1148 | href: url.href, | 1143 | 1149 | }; | 1144 | | - if (url.port !== '') { | 1145 | | - options.port = Number(url.port); | | 1150 | + if (port !== '') { | | 1151 | + options.port = Number(port); | 1146 | 1152 | } | 1147 | | - if (url.username || url.password) { | 1148 | | - options.auth = `${decodeURIComponent(url.username)}:${decodeURIComponent(url.password)}`; | | 1153 | + if (username || password) { | | 1154 | + options.auth = `${decodeURIComponent(username)}:${decodeURIComponent(password)}`; | 1149 | 1155 | } | 1150 | 1156 | return options; | 1151 | 1157 | } | |
Collapse file Copy file name to clipboard +27Lines changed: 27 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +'use strict'; | | 2 | + | | 3 | +const common = require('../common'); | | 4 | +const assert = require('node:assert'); | | 5 | +const http = require('node:http'); | | 6 | + | | 7 | +const headers = { foo: 'Bar' }; | | 8 | +const server = 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 | + const url = new URL(`http://${address}:${port}/ping?q=term`); | | 21 | + url.headers = headers; | | 22 | + const clientReq = http.request(url); | | 23 | + clientReq.on('close', common.mustCall(() => { | | 24 | + server.close(); | | 25 | + })); | | 26 | + clientReq.end(); | | 27 | +}); |
|