-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Description
Version
20.5.0
Platform
Darwin 22.2.0
Subsystem
No response
What steps will reproduce the bug?
When using request library and @sentry/nodejs, the https/http will send the request with empty path - https://api.io/testing will become https://api.io.
The reason is request library added an href field to request args, and Sentry added a protocol field:
https://github.com/getsentry/sentry-javascript/blob/beec5be5cf90fc13d5c0000419422f51d2d75d1c/packages/node/src/integrations/utils/http.ts#L188-L192
https://github.com/request/request/blob/3c0cddc7c8eb60b470e9519da85896ed7ee0081e/request.js#L729
And when href and protocol both exist, isURL will think it's an URL object and reset path to pathname+search, and the above is clearly not a URL object and does not have pathname
Lines 761 to 763 in 36c72c8
| function isURL(self) { | |
| return Boolean(self?.href && self.protocol && self.auth === undefined); | |
| } |
Lines 1332 to 1336 in 36c72c8
| search: search, | |
| pathname: pathname, | |
| path: `${pathname || ''}${search || ''}`, | |
| href: url.href, | |
| }; |
Having the following code, if the protocol and href in options, the https will set path to empty to request https://64bfcd8c0d8e251fd1117729.mockapi.io, and without protocol or href, it will request https://64bfcd8c0d8e251fd1117729.mockapi.io/test as expected.
const https = require('https');
const href = 'https://64bfcd8c0d8e251fd1117729.mockapi.io/test';
const options = {
method: 'GET',
host: '64bfcd8c0d8e251fd1117729.mockapi.io',
href,
protocol: 'https:',
path: '/test',
};
const req = https.request(options);
let rawData = '';
req.on('response', (res) => {
res.on('data', (chunk) => {
rawData += chunk;
});
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error('error', e.message);
}
});
});
req.on('error', (e) => {
console.log(e);
});
req.end();And when run node test.js with protocol and href, it will output
error Unexpected token '<', "<html>
<h"... is not valid JSON
And if delete protocol or href, it will get the correct response []
How often does it reproduce? Is there a required condition?
Everytime.
What is the expected behavior? Why is that the expected behavior?
No response
What do you see instead?
isURL cannot accurately determine if it is a URL object
Additional information
Of course, the request library might should not add the href field since it is not the correct args for http(s).request, but it's not maintained and there are still a lot of users, it should be fixed.
IMO, the root cause is isURL cannot accurately determine if it is a URL object, I think it can be fixed by
Change isURL to
function isURL(self) {
return Boolean(self?.href && self.protocol && self.auth === undefined && self.path === undefined);
} Or respect user's path by changing urlToHttpOptions - move ...url to the bottom of options instead of top.
const options = {
__proto__: null,
protocol: url.protocol,
hostname: hostname && StringPrototypeStartsWith(hostname, '[') ?
StringPrototypeSlice(hostname, 1, -1) :
hostname,
hash: url.hash,
search: search,
pathname: pathname,
path: `${pathname || ''}${search || ''}`,
href: url.href,
...url, // In case the url object was extended by the user.
};