Replace URL generation code in the drive file uploader with something more robust.

Closes #10404, hopefully.
This commit is contained in:
yumeko 2023-07-22 13:57:44 +03:00
parent 2f49c8734d
commit 4e23b77aff

View file

@ -37,6 +37,32 @@ import { deleteFile } from "./delete-file.js";
const logger = driveLogger.createSubLogger("register", "yellow"); const logger = driveLogger.createSubLogger("register", "yellow");
type PathPartLike = string | null
// Joins an array of elements into a URL pathname, possibly with a base URL object to append to.
// Null or 0-length parts will be left out.
function urlPathJoin(
baseOrParts: URL | PathPartLike[],
pathParts?: PathPartLike[],
): string {
if (baseOrParts instanceof URL) {
const url = new URL(baseOrParts as URL);
if (pathParts) {
pathParts.unshift(
url.pathname.endsWith("/") ? url.pathname.slice(0, -1) : url.pathname,
);
url.pathname = pathParts
.filter((x) => x !== null && x.toString().length > 0)
.join("/");
}
return url.toString();
}
const baseParts = baseOrParts.concat(pathParts ?? []);
return baseParts
.filter((x) => x !== null && x.toString().length > 0)
.join("/");
}
/*** /***
* Save file * Save file
* @param path Path for original * @param path Path for original
@ -77,17 +103,16 @@ async function save(
ext = ""; ext = "";
} }
const baseUrl = const baseUrl = new URL(
meta.objectStorageBaseUrl || meta.objectStorageBaseUrl ?? `/${meta.objectStorageBucket}`,
`${meta.objectStorageUseSSL ? "https" : "http"}://${ `${meta.objectStorageUseSSL ? "https" : "http"}://${
meta.objectStorageEndpoint meta.objectStorageEndpoint
}${meta.objectStoragePort ? `:${meta.objectStoragePort}` : ""}/${ }${meta.objectStoragePort ? `:${meta.objectStoragePort}` : ""}`,
meta.objectStorageBucket );
}`;
// for original // for original
const key = `${meta.objectStoragePrefix}/${uuid()}${ext}`; const key = urlPathJoin([meta.objectStoragePrefix, `${uuid()}${ext}`]);
const url = `${baseUrl}/${key}`; const url = urlPathJoin(baseUrl, [key]);
// for alts // for alts
let webpublicKey: string | null = null; let webpublicKey: string | null = null;
@ -101,10 +126,8 @@ async function save(
const uploads = [upload(key, fs.createReadStream(path), type, name)]; const uploads = [upload(key, fs.createReadStream(path), type, name)];
if (alts.webpublic) { if (alts.webpublic) {
webpublicKey = `${meta.objectStoragePrefix}/webpublic-${uuid()}.${ webpublicKey = urlPathJoin([meta.objectStoragePrefix, `webpublic-${uuid()}.${alts.webpublic.ext}`]);
alts.webpublic.ext webpublicUrl = urlPathJoin(baseUrl, [webpublicKey]);
}`;
webpublicUrl = `${baseUrl}/${webpublicKey}`;
logger.info(`uploading webpublic: ${webpublicKey}`); logger.info(`uploading webpublic: ${webpublicKey}`);
uploads.push( uploads.push(
@ -113,10 +136,8 @@ async function save(
} }
if (alts.thumbnail) { if (alts.thumbnail) {
thumbnailKey = `${meta.objectStoragePrefix}/thumbnail-${uuid()}.${ thumbnailKey = urlPathJoin([meta.objectStoragePrefix, `thumbnail-${uuid()}.${alts.thumbnail.ext}`]);
alts.thumbnail.ext thumbnailUrl = urlPathJoin(baseUrl, [thumbnailKey]);
}`;
thumbnailUrl = `${baseUrl}/${thumbnailKey}`;
logger.info(`uploading thumbnail: ${thumbnailKey}`); logger.info(`uploading thumbnail: ${thumbnailKey}`);
uploads.push( uploads.push(