const ORIGIN_GROUPS = ["originGroup1", "originGroup2"];
const VIRTUAL_NODES_PER_GROUP = 15;
const ORIGIN_HEADER_NAME = 'X-Forwarded-For-Origin';
let virtualNodesHashesCache = null;
addEventListener("fetch", (event) => {
handleRequest(event.request);
});
async function handleRequest(request) {
const ip = request.headers.get("EO-Client-IP") || "";
if (!virtualNodesHashesCache) {
virtualNodesHashesCache = await generateVirtualNodesHashes();
}
const group = await findSourceGroupForIp(
ip,
virtualNodesHashesCache.hashes,
virtualNodesHashesCache.mapping
);
console.log(`Group: ${group}`);
request.headers.set(ORIGIN_HEADER_NAME, group)
return;
}
async function generateVirtualNodesHashes() {
const virtualNodesHashes = {};
for (let group in ORIGIN_GROUPS) {
for (let i = 0; i < VIRTUAL_NODES_PER_GROUP; i++) {
const virtualNodeIdentifier = `${group}-VN${i}`;
const hash = await md5(virtualNodeIdentifier);
if (!virtualNodesHashes[hash]) {
virtualNodesHashes[hash] = group;
}
}
}
const hashes = Object.keys(virtualNodesHashes).sort();
return { hashes, mapping: virtualNodesHashes };
}
async function findSourceGroupForIp(ip, hashes, mapping) {
const ipHash = await md5(ip);
let closestHash = hashes.find((hash) => hash > ipHash) || hashes[0];
const selectedGroupName = mapping[closestHash];
const selectedGroupIPs = ORIGIN_GROUPS[selectedGroupName];
console.log(
`IP: ${ip}, Hash: ${ipHash}, Closest Hash: ${closestHash}, Selected Group: ${selectedGroupName}`
);
return selectedGroupIPs;
}
function bufferToHex(arr) {
return Array.prototype.map
.call(arr, (x) => (x >= 16 ? x.toString(16) : "0" + x.toString(16)))
.join("");
}
async function md5(text) {
const buffer = await crypto.subtle.digest("MD5", TextEncoder().encode(text));
return bufferToHex(new Uint8Array(buffer));
}
本页内容是否解决了您的问题?