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
Lines 1332 to 1336 in 36c72c8
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.
};