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
|
function isURL(self) { |
|
return Boolean(self?.href && self.protocol && self.auth === undefined); |
|
} |
|
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.
};
Version
20.5.0
Platform
Darwin 22.2.0
Subsystem
No response
What steps will reproduce the bug?
When using
requestlibrary and@sentry/nodejs, thehttps/httpwill send the request with emptypath-https://api.io/testingwill becomehttps://api.io.The reason is
requestlibrary added anhreffield to request args, and Sentry added aprotocolfield: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
hrefandprotocolboth exist,isURLwill think it's anURLobject and resetpathtopathname+search, and the above is clearly not a URL object and does not havepathnamenode/lib/internal/url.js
Lines 761 to 763 in 36c72c8
node/lib/internal/url.js
Lines 1332 to 1336 in 36c72c8
Having the following code, if the
protocolandhrefinoptions, thehttpswill setpathto empty to requesthttps://64bfcd8c0d8e251fd1117729.mockapi.io, and withoutprotocolorhref, it will requesthttps://64bfcd8c0d8e251fd1117729.mockapi.io/testas expected.And when run
node test.jswithprotocolandhref, it will outputAnd if delete
protocolorhref, 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?
isURLcannot accurately determine if it is a URL objectAdditional information
Of course, the
requestlibrary might should not add thehreffield since it is not the correct args forhttp(s).request, but it's not maintained and there are still a lot of users, it should be fixed.IMO, the root cause is
isURLcannot accurately determine if it is a URL object, I think it can be fixed byChange
isURLtoOr respect user's
pathby changingurlToHttpOptions- move...urlto the bottom of options instead of top.