mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-06 13:58:05 +03:00
change CDNRetrieve to CDNRedirect
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { KTCDN_ROOT } from "../setup/config";
|
||||
import { CDN_ROOT, CDN_URL } from "../setup/config";
|
||||
import CreateLogCtx from "../logger/logger";
|
||||
import { promisify } from "util";
|
||||
import mkdirp from "mkdirp";
|
||||
import { Response } from "express";
|
||||
|
||||
const readFilePromise = promisify(fs.readFile);
|
||||
const writeFilePromise = promisify(fs.writeFile);
|
||||
@@ -18,18 +19,38 @@ const logger = CreateLogCtx(__filename);
|
||||
* Path directory traversal *is* possible, and *will* ruin your day.
|
||||
*/
|
||||
function CDNRoot(fileLoc: string) {
|
||||
return path.join(KTCDN_ROOT, fileLoc);
|
||||
return path.join(CDN_ROOT, fileLoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the data of the file at the given CDN location.
|
||||
*
|
||||
* This is used for quick development setups, where a cdn server isn't available.
|
||||
* As in, this ruins the purpose of a CDN! make sure you have one running.
|
||||
*/
|
||||
export function CDNRetrieve(fileLoc: string) {
|
||||
logger.debug(`Retrieving path ${fileLoc}.`);
|
||||
function CDNRetrieve(fileLoc: string) {
|
||||
logger.debug(`Retrieving path ${fileLoc} locally.`);
|
||||
|
||||
return readFilePromise(CDNRoot(fileLoc));
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects the response to the CDN server at the given path.
|
||||
*
|
||||
* If no CDN_URL is set, then this falls back to fetching from the CDN ROOT via. FS.
|
||||
*/
|
||||
export function CDNRedirect(res: Response, fileLoc: string) {
|
||||
if (fileLoc[0] !== "/") {
|
||||
throw new Error(`Invalid fileLoc - did not start with /.`);
|
||||
}
|
||||
|
||||
if (CDN_URL) {
|
||||
return res.redirect(`${CDN_URL}${fileLoc}`);
|
||||
} else {
|
||||
return CDNRetrieve(fileLoc);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag for fs.open to write a file but NOT overwrite it if it already exists.
|
||||
*/
|
||||
|
||||
@@ -4,7 +4,7 @@ import JSON5 from "json5";
|
||||
import fs from "fs";
|
||||
import p from "prudence";
|
||||
import { FormatPrError } from "../../utils/prudence";
|
||||
import { integer, Game, StaticConfig } from "tachi-common";
|
||||
import { integer, StaticConfig } from "tachi-common";
|
||||
dotenv.config(); // imports things like NODE_ENV from a local .env file if one is present.
|
||||
|
||||
// reads from $pwd/conf.json5
|
||||
@@ -36,6 +36,7 @@ export interface TachiConfig {
|
||||
ARC_API_URL: string;
|
||||
ARC_AUTH_TOKEN: string;
|
||||
CDN_ROOT: string;
|
||||
CDN_URL: string | null;
|
||||
TYPE: "ktchi" | "btchi" | "omni";
|
||||
PORT: integer;
|
||||
TYPE_INFO: StaticConfig.ServerConfig;
|
||||
@@ -52,6 +53,7 @@ const err = p(config, {
|
||||
ARC_API_URL: isValidURL,
|
||||
ARC_AUTH_TOKEN: "string",
|
||||
CDN_ROOT: "string",
|
||||
CDN_URL: "?string",
|
||||
PORT: p.isPositiveInteger,
|
||||
TYPE: p.isIn("ktchi", "btchi", "omni"),
|
||||
});
|
||||
@@ -79,7 +81,8 @@ export const FLO_API_URL = tachiConfig.FLO_API_URL;
|
||||
export const EAG_API_URL = tachiConfig.EAG_API_URL;
|
||||
export const ARC_API_URL = tachiConfig.ARC_API_URL;
|
||||
export const ARC_AUTH_TOKEN = tachiConfig.ARC_AUTH_TOKEN;
|
||||
export const KTCDN_ROOT = tachiConfig.CDN_ROOT;
|
||||
export const CDN_ROOT = tachiConfig.CDN_ROOT;
|
||||
export const CDN_URL = tachiConfig.CDN_URL;
|
||||
export const CONF_INFO = tachiConfig.TYPE_INFO;
|
||||
export const PORT = tachiConfig.PORT;
|
||||
export const CONFIG = tachiConfig;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Router } from "express";
|
||||
import db from "../../../../../../../external/mongo/db";
|
||||
import { CDNStoreOrOverwrite, CDNRetrieve, CDNDelete } from "../../../../../../../lib/cdn/cdn";
|
||||
import { CDNStoreOrOverwrite, CDNRedirect, CDNDelete } from "../../../../../../../lib/cdn/cdn";
|
||||
import { GetProfileBannerURL } from "../../../../../../../lib/cdn/url-format";
|
||||
import { ONE_MEGABYTE } from "../../../../../../../lib/constants/filesize";
|
||||
import { SYMBOL_TachiData } from "../../../../../../../lib/constants/tachi";
|
||||
@@ -86,14 +86,14 @@ router.get("/", async (req, res) => {
|
||||
|
||||
if (!user.customBanner) {
|
||||
res.setHeader("Content-Type", "image/png");
|
||||
const buf = await CDNRetrieve("/users/default/banner.png");
|
||||
const buf = await CDNRedirect("/users/default/banner.png");
|
||||
return res.send(buf);
|
||||
}
|
||||
|
||||
// this might be a png or a jpg. Could we sniff this out somehow?
|
||||
// alternatively - could we convert jpgs to pngs on upload?
|
||||
// this isn't my area of expertise - zkldi
|
||||
const buf = await CDNRetrieve(GetProfileBannerURL(user.id));
|
||||
const buf = await CDNRedirect(GetProfileBannerURL(user.id));
|
||||
|
||||
return res.send(buf);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Router } from "express";
|
||||
import db from "../../../../../../../external/mongo/db";
|
||||
import { CDNStoreOrOverwrite, CDNRetrieve, CDNDelete } from "../../../../../../../lib/cdn/cdn";
|
||||
import { CDNStoreOrOverwrite, CDNRedirect, CDNDelete } from "../../../../../../../lib/cdn/cdn";
|
||||
import { GetProfilePictureURL } from "../../../../../../../lib/cdn/url-format";
|
||||
import { ONE_MEGABYTE } from "../../../../../../../lib/constants/filesize";
|
||||
import { SYMBOL_TachiData } from "../../../../../../../lib/constants/tachi";
|
||||
@@ -84,14 +84,14 @@ router.get("/", async (req, res) => {
|
||||
|
||||
if (!user.customPfp) {
|
||||
res.setHeader("Content-Type", "image/png");
|
||||
const buf = await CDNRetrieve("/users/default/pfp.png");
|
||||
const buf = await CDNRedirect("/users/default/pfp.png");
|
||||
return res.send(buf);
|
||||
}
|
||||
|
||||
// this might be a png or a jpg. Could we sniff this out somehow?
|
||||
// alternatively - could we convert jpgs to pngs on upload?
|
||||
// this isn't my area of expertise - zkldi
|
||||
const buf = await CDNRetrieve(GetProfilePictureURL(user.id));
|
||||
const buf = await CDNRedirect(GetProfilePictureURL(user.id));
|
||||
|
||||
return res.send(buf);
|
||||
});
|
||||
|
||||
@@ -6,7 +6,7 @@ import ResetDBState, { ResetCDN } from "../../../../test-utils/resets";
|
||||
import deepmerge from "deepmerge";
|
||||
import { PBScoreDocument, ScoreDocument } from "tachi-common";
|
||||
import { GetKTDataBuffer } from "../../../../test-utils/test-data";
|
||||
import { CDNRetrieve } from "../../../../lib/cdn/cdn";
|
||||
import { CDNRedirect } from "../../../../lib/cdn/cdn";
|
||||
|
||||
async function InsertFakeUSCAuth() {
|
||||
await db["api-tokens"].insert({
|
||||
@@ -374,7 +374,7 @@ t.test("POST /replays", (t) => {
|
||||
body: null,
|
||||
});
|
||||
|
||||
const stored = await CDNRetrieve("/uscir/replays/MOCK_IDENTIFIER");
|
||||
const stored = await CDNRedirect("/uscir/replays/MOCK_IDENTIFIER");
|
||||
|
||||
t.strictSame(stored, replayFile, "Should store the same file exactly.");
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import path from "path";
|
||||
import CreateLogCtx from "../lib/logger/logger";
|
||||
// im installing an entire library for rm rf...
|
||||
import rimraf from "rimraf";
|
||||
import { KTCDN_ROOT, MONGO_CONNECTION_URL } from "../lib/setup/config";
|
||||
import { CDN_ROOT, MONGO_CONNECTION_URL } from "../lib/setup/config";
|
||||
import { SetIndexes } from "../external/mongo/indexes";
|
||||
|
||||
const logger = CreateLogCtx(__filename);
|
||||
@@ -77,7 +77,7 @@ export default async function ResetDBState() {
|
||||
|
||||
export function ResetCDN() {
|
||||
return new Promise<void>((resolve, reject) =>
|
||||
rimraf(KTCDN_ROOT, (err) => {
|
||||
rimraf(CDN_ROOT, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user