efficiencize redis and parsing cidr
This commit is contained in:
parent
23d3cb7036
commit
3b54b2e13c
|
|
@ -1,4 +1,4 @@
|
|||
import { readdir } from 'node:fs/promises'
|
||||
import { readdir, stat } from 'node:fs/promises'
|
||||
import * as path from 'node:path'
|
||||
|
||||
export interface BlockedIpResult {
|
||||
|
|
@ -62,6 +62,35 @@ let networkRefreshPromise: Promise<void> | null = null
|
|||
let networksCheckedAt = 0
|
||||
let networksEtag: string | null = null
|
||||
|
||||
interface BlockedListCache {
|
||||
mtimeMs: number;
|
||||
parsedCidrs: { cidr: string, parsed: ParsedCidr }[];
|
||||
}
|
||||
const blockedCache = new Map<string, BlockedListCache>();
|
||||
|
||||
async function getBlockedCidrs(fileName: string, filePath: string) {
|
||||
const fileStat = await stat(filePath).catch(() => null);
|
||||
if (!fileStat) return [];
|
||||
|
||||
const cached = blockedCache.get(fileName);
|
||||
if (cached && cached.mtimeMs === fileStat.mtimeMs) {
|
||||
return cached.parsedCidrs;
|
||||
}
|
||||
|
||||
const content = await Bun.file(filePath).text();
|
||||
const cidrs = extractCidrs(content);
|
||||
const parsedCidrs = [];
|
||||
for (const cidr of cidrs) {
|
||||
const parsed = parseCidr(cidr);
|
||||
if (parsed) {
|
||||
parsedCidrs.push({ cidr, parsed });
|
||||
}
|
||||
}
|
||||
|
||||
blockedCache.set(fileName, { mtimeMs: fileStat.mtimeMs, parsedCidrs });
|
||||
return parsedCidrs;
|
||||
}
|
||||
|
||||
function ipv4ToInt(ip: string): number | null {
|
||||
const parts = ip.trim().split('.')
|
||||
if (parts.length !== 4) return null
|
||||
|
|
@ -326,11 +355,19 @@ export async function checkIpRanges(ip: string): Promise<BlockedIpResult> {
|
|||
|
||||
for (const fileName of files) {
|
||||
const filePath = path.join(BLOCKED_DIR, fileName)
|
||||
const content = await Bun.file(filePath).text()
|
||||
const cidrs = extractCidrs(content)
|
||||
const cachedCidrs = await getBlockedCidrs(fileName, filePath)
|
||||
|
||||
for (const cidr of cidrs) {
|
||||
if (isIpInCidr(parsedIp, cidr)) {
|
||||
for (const item of cachedCidrs) {
|
||||
const { cidr, parsed } = item;
|
||||
let matched = false;
|
||||
|
||||
if (parsedIp.version === 4 && parsed.version === 4) {
|
||||
matched = (parsedIp.value & parsed.mask) === parsed.network
|
||||
} else if (parsedIp.version === 6 && parsed.version === 6) {
|
||||
matched = (parsedIp.value & parsed.mask) === parsed.network
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
return {
|
||||
blocked: path.basename(fileName, '.txt') != 'cloudflare',
|
||||
list: path.basename(fileName, '.txt'),
|
||||
|
|
|
|||
|
|
@ -8,8 +8,10 @@ const redis = new Redis({
|
|||
|
||||
redis.on('ready', async function () {
|
||||
console.log('connected to redis')
|
||||
})
|
||||
|
||||
setInterval(async () => {
|
||||
if (redis.status !== 'ready') return;
|
||||
const files = fs.readdirSync('videos')
|
||||
const targetFiles = files.filter((file) => file.endsWith('.webm') || file.endsWith('.mp4') || file.endsWith('.m4a'))
|
||||
targetFiles.forEach(async (f) => {
|
||||
|
|
@ -21,6 +23,5 @@ redis.on('ready', async function () {
|
|||
}
|
||||
})
|
||||
}, 5 * 60000)
|
||||
})
|
||||
|
||||
export default redis
|
||||
Loading…
Reference in New Issue