add project size ratelimiting
This commit is contained in:
parent
e86e86dbe2
commit
3325b20aed
@ -13,6 +13,7 @@ import {
|
|||||||
createFile,
|
createFile,
|
||||||
deleteFile,
|
deleteFile,
|
||||||
generateCode,
|
generateCode,
|
||||||
|
getProjectSize,
|
||||||
getSandboxFiles,
|
getSandboxFiles,
|
||||||
renameFile,
|
renameFile,
|
||||||
saveFile,
|
saveFile,
|
||||||
@ -155,8 +156,16 @@ io.on("connection", async (socket) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("createFile", async (name: string) => {
|
socket.on("createFile", async (name: string, callback) => {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
const size: number = await getProjectSize(data.sandboxId)
|
||||||
|
// limit is 200mb
|
||||||
|
if (size > 200 * 1024 * 1024) {
|
||||||
|
io.emit("rateLimit", "Rate limited: project size exceeded. Please delete some files.")
|
||||||
|
callback({success: false})
|
||||||
|
}
|
||||||
|
|
||||||
await createFileRL.consume(data.userId, 1)
|
await createFileRL.consume(data.userId, 1)
|
||||||
|
|
||||||
const id = `projects/${data.sandboxId}/${name}`
|
const id = `projects/${data.sandboxId}/${name}`
|
||||||
@ -177,6 +186,8 @@ io.on("connection", async (socket) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
await createFile(id)
|
await createFile(id)
|
||||||
|
|
||||||
|
callback({success: true})
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
io.emit("rateLimit", "Rate limited: file creation. Please slow down.")
|
io.emit("rateLimit", "Rate limited: file creation. Please slow down.")
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import e from "cors"
|
||||||
import {
|
import {
|
||||||
R2FileBody,
|
R2FileBody,
|
||||||
R2Files,
|
R2Files,
|
||||||
@ -134,6 +135,13 @@ export const deleteFile = async (fileId: string) => {
|
|||||||
return res.ok
|
return res.ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getProjectSize = async (id: string) => {
|
||||||
|
const res = await fetch(
|
||||||
|
`https://storage.ishaan1013.workers.dev/api/size?sandboxId=${id}`
|
||||||
|
)
|
||||||
|
return (await res.json()).size
|
||||||
|
}
|
||||||
|
|
||||||
export const generateCode = async ({
|
export const generateCode = async ({
|
||||||
fileName,
|
fileName,
|
||||||
code,
|
code,
|
||||||
|
@ -16,7 +16,23 @@ export default {
|
|||||||
const path = url.pathname;
|
const path = url.pathname;
|
||||||
const method = request.method;
|
const method = request.method;
|
||||||
|
|
||||||
if (path === '/api') {
|
if (path === '/api/size' && method === 'GET') {
|
||||||
|
const params = url.searchParams;
|
||||||
|
const sandboxId = params.get('sandboxId');
|
||||||
|
|
||||||
|
if (sandboxId) {
|
||||||
|
const res = await env.R2.list({ prefix: `projects/${sandboxId}` });
|
||||||
|
|
||||||
|
// sum up the size of all files
|
||||||
|
let size = 0;
|
||||||
|
for (const file of res.objects) {
|
||||||
|
size += file.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Response(JSON.stringify({ size }), { status: 200 });
|
||||||
|
} else return invalidRequest;
|
||||||
|
}
|
||||||
|
else if (path === '/api') {
|
||||||
if (method === 'GET') {
|
if (method === 'GET') {
|
||||||
const params = url.searchParams;
|
const params = url.searchParams;
|
||||||
const sandboxId = params.get('sandboxId');
|
const sandboxId = params.get('sandboxId');
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
"use client"
|
"use client";
|
||||||
|
|
||||||
import { validateName } from "@/lib/utils"
|
import { validateName } from "@/lib/utils";
|
||||||
import Image from "next/image"
|
import Image from "next/image";
|
||||||
import { useEffect, useRef } from "react"
|
import { useEffect, useRef } from "react";
|
||||||
import { Socket } from "socket.io-client"
|
import { Socket } from "socket.io-client";
|
||||||
|
|
||||||
export default function New({
|
export default function New({
|
||||||
socket,
|
socket,
|
||||||
@ -11,31 +11,38 @@ export default function New({
|
|||||||
stopEditing,
|
stopEditing,
|
||||||
addNew,
|
addNew,
|
||||||
}: {
|
}: {
|
||||||
socket: Socket
|
socket: Socket;
|
||||||
type: "file" | "folder"
|
type: "file" | "folder";
|
||||||
stopEditing: () => void
|
stopEditing: () => void;
|
||||||
addNew: (name: string, type: "file" | "folder") => void
|
addNew: (name: string, type: "file" | "folder") => void;
|
||||||
}) {
|
}) {
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const createNew = () => {
|
const createNew = () => {
|
||||||
const name = inputRef.current?.value
|
const name = inputRef.current?.value;
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
const valid = validateName(name, "", type)
|
const valid = validateName(name, "", type);
|
||||||
if (valid.status) {
|
if (valid.status) {
|
||||||
if (type === "file") {
|
if (type === "file") {
|
||||||
socket.emit("createFile", name)
|
socket.emit(
|
||||||
|
"createFile",
|
||||||
|
name,
|
||||||
|
({ success }: { success: boolean }) => {
|
||||||
|
if (success) {
|
||||||
|
addNew(name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
addNew(name, type)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stopEditing()
|
stopEditing();
|
||||||
}
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
inputRef.current?.focus()
|
inputRef.current?.focus();
|
||||||
}, [])
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full flex items-center h-7 px-1 hover:bg-secondary rounded-sm cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
|
<div className="w-full flex items-center h-7 px-1 hover:bg-secondary rounded-sm cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
|
||||||
@ -52,8 +59,8 @@ export default function New({
|
|||||||
/>
|
/>
|
||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
e.preventDefault()
|
e.preventDefault();
|
||||||
createNew()
|
createNew();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
@ -63,5 +70,5 @@ export default function New({
|
|||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user