139 lines
4.3 KiB
JavaScript
139 lines
4.3 KiB
JavaScript
// vim: tabstop=4 shiftwidth=4 expandtab
|
|
|
|
function makeid(length) {
|
|
let result = '';
|
|
const characters = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
const charactersLength = characters.length;
|
|
let counter = 0;
|
|
while (counter < length) {
|
|
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
counter += 1;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
async function checkAuth(request) {
|
|
const auth = request.headers.get("Authorization");
|
|
const auth_check = await AUTH.get(auth)
|
|
console.log(auth, auth_check)
|
|
return Boolean(auth_check);
|
|
}
|
|
|
|
function getHost(request) {
|
|
return request.headers.get("Host")
|
|
}
|
|
|
|
async function add(request,host,path) {
|
|
const auth = await checkAuth(request)
|
|
if (!auth)
|
|
return new Response("Only GET requests allowed to unauthed users", {status:403});
|
|
if (!request.headers.get("content-type"))
|
|
return new Response("No data provided", {status:400})
|
|
if (!path) return new Response("No path provided",{status:400})
|
|
if (path === "_") {
|
|
var x = 0
|
|
while (true) {
|
|
path = makeid(4)
|
|
const lookup = await KV.get(path)
|
|
if (!lookup) break
|
|
if (x >= 5) return new Response("Failed to generate a unique ID in 5 attempts", {status:500});
|
|
x += 1
|
|
}
|
|
}
|
|
path = path.toLowerCase()
|
|
|
|
// URL shortening
|
|
const data = await request.formData()
|
|
const dest = data.get("u")
|
|
console.log(dest)
|
|
try {
|
|
var u = new URL(dest)
|
|
if (u.host !== host) {
|
|
await KV.put(path, dest)
|
|
} else {
|
|
path = u.pathname.split("/")[1]
|
|
}
|
|
await FILES.delete(path)
|
|
return new Response(`https://${host}/${path}`, {status:201})
|
|
} catch (e) {
|
|
if (e instanceof TypeError) {
|
|
await FILES.put(path, dest)
|
|
var type = dest.type
|
|
if (type === "undefined") type = "text/plain" // dammit sharex
|
|
await KV.put(path,dest.type)
|
|
return new Response(`https://${host}/${path}`, {status:201})
|
|
// return new Response("No valid URL provided",{status:400});
|
|
}
|
|
else throw e;
|
|
};
|
|
|
|
return new Response(`No URL or file provided`, {status:400})
|
|
}
|
|
|
|
async function remove(request,host,path) {
|
|
const auth = await checkAuth(request)
|
|
if (!auth)
|
|
return new Response("Only GET requests allowed to unauthed users", {status:403});
|
|
if (!path) return new Response("No path provided",{status:400})
|
|
path = path.toLowerCase()
|
|
await KV.delete(path)
|
|
await FILES.delete(path)
|
|
return new Response(`DELETE https://${host}/${path}`, {status:200})
|
|
}
|
|
|
|
async function get(request,host,path) {
|
|
const auth = await checkAuth(request)
|
|
if (!path && auth) {
|
|
const { keys } = await KV.list()
|
|
let paths = ""
|
|
keys.forEach(element => paths += `${element.name}\n`);
|
|
return new Response(paths,{status:200})
|
|
}
|
|
if (!path) return Response.redirect(REDIR_URL,301)
|
|
path = path.toLowerCase()
|
|
|
|
const dest_file = await FILES.get(path)
|
|
if (dest_file) {
|
|
const mime = await KV.get(path)
|
|
const headers = new Headers()
|
|
dest_file.writeHttpMetadata(headers)
|
|
headers.set("etag", dest_file.httpEtag)
|
|
if (mime.startsWith("text/")) {
|
|
headers.set("content-type", "text/plain")
|
|
headers.set("x-content-type", mime)
|
|
} else {
|
|
headers.set("content-type", mime)
|
|
}
|
|
return new Response(dest_file.body, { headers, } )
|
|
}
|
|
const dest = await KV.get(path)
|
|
if (dest) return Response.redirect(dest, 302)
|
|
return new Response("Path not found", {status:404})
|
|
}
|
|
|
|
async function handleRequest(request) {
|
|
const host = getHost(request)
|
|
const url = new URL(request.url)
|
|
var pathname = url.pathname.split("/")
|
|
var path = pathname[1]
|
|
// if (pathname.length > 2) var
|
|
switch (request.method) {
|
|
case "PUT":
|
|
case "POST":
|
|
case "PATCH":
|
|
return add(request,host,path)
|
|
case "DELETE":
|
|
return remove(request,host,path)
|
|
case "HEAD":
|
|
case "GET":
|
|
return get(request,host,path)
|
|
default:
|
|
return new Response("Method not allowed", {status:405})
|
|
}
|
|
}
|
|
|
|
addEventListener('fetch', event => {
|
|
const { request } = event;
|
|
return event.respondWith(handleRequest(request));
|
|
});
|