diff --git a/src/services/npdi.ts b/src/services/npdi.ts index 596e9d1..5af9c89 100644 --- a/src/services/npdi.ts +++ b/src/services/npdi.ts @@ -3,6 +3,7 @@ import { restrictHostnames } from '@/middleware/host-limit'; import { config } from '@/config-manager'; import { getCDNFileAsStream, streamFileToResponse } from '@/cdn'; import { getTaskFileByDataID } from '@/database'; +import { handleEtag, sendEtagCacheResponse } from '@/util'; const npdi = express.Router(); @@ -18,6 +19,11 @@ npdi.get('/p01/data/1/:bossAppId/:dataId/:fileHash', async (request, response) = return response.sendStatus(404); } + const { clientHasCached } = handleEtag(request, response, file.hash); + if (clientHasCached) { + return sendEtagCacheResponse(response); + } + const fileStream = await getCDNFileAsStream('taskFile', file.file_key); if (!fileStream) { throw new Error('File not found in CDN'); diff --git a/src/services/npdl.ts b/src/services/npdl.ts index e934949..d41a998 100644 --- a/src/services/npdl.ts +++ b/src/services/npdl.ts @@ -3,6 +3,7 @@ import { getTaskFile } from '@/database'; import { config } from '@/config-manager'; import { restrictHostnames } from '@/middleware/host-limit'; import { getCDNFileAsStream, streamFileToResponse } from '@/cdn'; +import { handleEtag, sendEtagCacheResponse } from '@/util'; const npdl = express.Router(); @@ -29,6 +30,11 @@ npdl.get([ return; } + const { clientHasCached } = handleEtag(request, response, file.hash); + if (clientHasCached) { + return sendEtagCacheResponse(response); + } + const readStream = await getCDNFileAsStream('taskFile', file.file_key); if (!readStream) { response.sendStatus(404); diff --git a/src/util.ts b/src/util.ts index a4e12c0..ebc8bf4 100644 --- a/src/util.ts +++ b/src/util.ts @@ -10,7 +10,7 @@ import type { AccountClient } from '@pretendonetwork/grpc/account/account_servic import type { GetNEXDataResponse } from '@pretendonetwork/grpc/account/get_nex_data_rpc'; import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/get_user_data_rpc'; import type { GetUserFriendPIDsResponse } from '@pretendonetwork/grpc/friends/get_user_friend_pids_rpc'; -import type { Response } from 'express'; +import type { Request, Response } from 'express'; import type { Stats } from 'node:fs'; const gRPCAccountChannel = createChannel(`${config.grpc.account.address}:${config.grpc.account.port}`); @@ -148,3 +148,16 @@ export async function getFriends(pid: number): Promise