@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
55 lines (53 loc) • 2.65 kB
JavaScript
const ipHeaderNames = [
"X-Client-IP",
"X-Forwarded-For",
"Fly-Client-IP",
"CF-Connecting-IP",
"Fastly-Client-Ip",
"True-Client-Ip",
"X-Real-IP",
"X-Cluster-Client-IP",
"X-Forwarded",
"Forwarded-For",
"Forwarded",
"X-Vercel-Forwarded-For"
];
function getClientIPAddress(headers) {
const lowerCaseHeaders = {};
for (const key of Object.keys(headers)) {
lowerCaseHeaders[key.toLowerCase()] = headers[key];
}
const headerValues = ipHeaderNames.map((headerName) => {
const rawValue = lowerCaseHeaders[headerName.toLowerCase()];
const value = Array.isArray(rawValue) ? rawValue.join(";") : rawValue;
if (headerName === "Forwarded") {
return parseForwardedHeader(value);
}
return value?.split(",").map((v) => v.trim());
});
const flattenedHeaderValues = headerValues.reduce((acc, val) => {
if (!val) {
return acc;
}
return acc.concat(val);
}, []);
const ipAddress = flattenedHeaderValues.find((ip) => ip !== null && isIP(ip));
return ipAddress || null;
}
function parseForwardedHeader(value) {
if (!value) {
return null;
}
for (const part of value.split(";")) {
if (part.startsWith("for=")) {
return part.slice(4);
}
}
return null;
}
function isIP(str) {
const regex = /(?:^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$)|(?:^(?:(?:[a-fA-F\d]{1,4}:){7}(?:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){6}(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|:[a-fA-F\d]{1,4}|:)|(?:[a-fA-F\d]{1,4}:){5}(?::(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,2}|:)|(?:[a-fA-F\d]{1,4}:){4}(?:(?::[a-fA-F\d]{1,4}){0,1}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,3}|:)|(?:[a-fA-F\d]{1,4}:){3}(?:(?::[a-fA-F\d]{1,4}){0,2}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,4}|:)|(?:[a-fA-F\d]{1,4}:){2}(?:(?::[a-fA-F\d]{1,4}){0,3}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,5}|:)|(?:[a-fA-F\d]{1,4}:){1}(?:(?::[a-fA-F\d]{1,4}){0,4}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,6}|:)|(?::(?:(?::[a-fA-F\d]{1,4}){0,5}:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:\\.(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}|(?::[a-fA-F\d]{1,4}){1,7}|:)))(?:%[0-9a-zA-Z]{1,})?$)/;
return regex.test(str);
}
export { getClientIPAddress, ipHeaderNames };
//# sourceMappingURL=getIpAddress.js.map