mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-25 07:06:25 -08:00
ok i'll need to figure more out later
This commit is contained in:
parent
3de215ee35
commit
5fd6073503
|
@ -36,10 +36,10 @@ export function generateFileId(length: number = 5) {
|
||||||
* @param conditions
|
* @param conditions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function multiAssert(conditions: Map<boolean, any>) {
|
function multiAssert(conditions: Map<boolean, { message: string, status: number }>) {
|
||||||
conditions.forEach((err, cond) => {
|
for (let [cond, err] of conditions.entries()) {
|
||||||
if (cond) throw err
|
if (cond) return err
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type FileUploadSettings = Partial<Pick<FilePointer, "mime" | "owner">> &
|
export type FileUploadSettings = Partial<Pick<FilePointer, "mime" | "owner">> &
|
||||||
|
@ -97,12 +97,12 @@ async function pushWebStream(stream: Readable, webStream: ReadableStream) {
|
||||||
|
|
||||||
namespace StreamHelpers {
|
namespace StreamHelpers {
|
||||||
|
|
||||||
interface UploadStream {
|
export interface UploadStream {
|
||||||
uploaded: number // number of bytes uploaded
|
uploaded: number // number of bytes uploaded
|
||||||
stream : Readable
|
stream : Readable
|
||||||
}
|
}
|
||||||
|
|
||||||
class StreamBuffer {
|
export class StreamBuffer {
|
||||||
|
|
||||||
readonly targetSize: number
|
readonly targetSize: number
|
||||||
filled: number = 0
|
filled: number = 0
|
||||||
|
@ -160,50 +160,77 @@ export default class Files {
|
||||||
.catch(console.error)
|
.catch(console.error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateUpload(metadata: FileUploadSettings & { size : number, uploadId: string }) {
|
||||||
|
return multiAssert(
|
||||||
|
new Map()
|
||||||
|
.set(!metadata.filename, {status: 400, message: "missing filename"})
|
||||||
|
.set(metadata.filename.length > 128, {status: 400, message: "filename too long"})
|
||||||
|
.set(!metadata.mime, {status: 400, message: "missing mime type"})
|
||||||
|
.set(metadata.mime.length > 128, {status: 400, message: "mime type too long"})
|
||||||
|
.set(
|
||||||
|
metadata.uploadId.match(id_check_regex)?.[0] != metadata.uploadId
|
||||||
|
|| metadata.uploadId.length > this.config.maxUploadIdLength,
|
||||||
|
{ status: 400, message: "invalid file ID" }
|
||||||
|
)
|
||||||
|
.set(
|
||||||
|
this.files[metadata.uploadId] &&
|
||||||
|
(metadata.owner
|
||||||
|
? this.files[metadata.uploadId].owner != metadata.owner
|
||||||
|
: true),
|
||||||
|
{ status: 403, message: "you don't own this file" }
|
||||||
|
)
|
||||||
|
.set(
|
||||||
|
this.files[metadata.uploadId]?.reserved,
|
||||||
|
{
|
||||||
|
status: 400,
|
||||||
|
message: "already uploading this file. if your file is stuck in this state, contact an administrator"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
writeFileStream(metadata: FileUploadSettings & { size: number }) {
|
writeFileStream(metadata: FileUploadSettings & { size: number }) {
|
||||||
|
|
||||||
let uploadId = (metadata.uploadId || generateFileId()).toString()
|
let uploadId = (metadata.uploadId || generateFileId()).toString()
|
||||||
let processor = new Promise((resolve, reject) => {
|
|
||||||
|
|
||||||
multiAssert(
|
let validation = this.validateUpload(
|
||||||
new Map()
|
{...metadata, uploadId}
|
||||||
.set(!metadata.filename, {status: 400, message: "missing filename"})
|
)
|
||||||
.set(metadata.filename.length > 128, {status: 400, message: "filename too long"})
|
if (validation) return validation
|
||||||
.set(!metadata.mime, {status: 400, message: "missing mime type"})
|
|
||||||
.set(metadata.mime.length > 128, {status: 400, message: "mime type too long"})
|
let buf = new StreamHelpers.StreamBuffer(this.api, metadata.size)
|
||||||
.set(
|
let fs_obj = this
|
||||||
uploadId.match(id_check_regex)?.[0] != uploadId
|
|
||||||
|| uploadId.length > this.config.maxUploadIdLength,
|
return new Writable({
|
||||||
{ status: 400, message: "invalid file ID" }
|
async write(data: Buffer) {
|
||||||
|
let positionInBuf = 0
|
||||||
|
while (positionInBuf < data.byteLength) {
|
||||||
|
let ns = (await buf.getNextStream())
|
||||||
|
if (!ns) {
|
||||||
|
this.destroy()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let bytesToPush = Math.min(
|
||||||
|
data.byteLength,
|
||||||
|
fs_obj.config.maxDiscordFileSize-ns.uploaded
|
||||||
)
|
)
|
||||||
.set(
|
|
||||||
this.files[uploadId] &&
|
|
||||||
(metadata.owner
|
|
||||||
? this.files[uploadId].owner != metadata.owner
|
|
||||||
: true),
|
|
||||||
{ status: 403, message: "you don't own this file" }
|
|
||||||
)
|
|
||||||
.set(
|
|
||||||
this.files[uploadId]?.reserved,
|
|
||||||
{
|
|
||||||
status: 400,
|
|
||||||
message: "already uploading this file. if your file is stuck in this state, contact an administrator"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
stream: new Writable({
|
|
||||||
write(data: any) {
|
|
||||||
|
|
||||||
|
ns.stream.push(data.subarray(positionInBuf, positionInBuf + bytesToPush))
|
||||||
|
ns.uploaded += bytesToPush
|
||||||
|
buf.filled += bytesToPush
|
||||||
|
positionInBuf += bytesToPush
|
||||||
|
|
||||||
|
if (ns.uploaded == fs_obj.config.maxDiscordFileSize)
|
||||||
|
buf.buffer.splice(0, 1)
|
||||||
|
|
||||||
|
if (buf.filled == buf.targetSize) {
|
||||||
|
this.destroy()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
processor
|
})
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue