import { englishPage } from "./language"
const md5 = require('./lib-md5.js')
async function handleRequest(request) {
let {pathname} = new URL(request.url.toLowerCase())
if (pathname.endsWith('/')) pathname = pathname.substring(0, pathname.length - 1)
if (pathname === '/imgbed.html') {
return new Response(englishPage(request) ? HOMEPAGE_EN : HOMEPAGE,
{headers: {"Content-Type": "text/html; charset=utf-8",
"Access-Control-Allow-Origin": "*"}})
} else if (pathname === '/imgbed/upload') {
return handleUploadImg(request)
} else if (pathname.startsWith('/p/')) {
return handleAccessImg(request)
}
}
const KVSPACE = "img_bed"
async function handleUploadImg(request) {
if (request.method != "POST") {
return new Response("", {status: 404})
}
const {fileType, imgType, imgData} = await decodeBase64Image(request)
if (fileType != 'image') {
return new Response(`It's not image but ${fileType}!`)
}
const {protocol, host} = new URL(request.url)
const imgID = `${Date.now()}-${Math.random()}-${imgData.byteLength}-${imgType}`
const imgURL = `${protocol}//${host}/p/` + md5(imgID).toLocaleLowerCase().substring(0, 16) + '.' + imgType
const kv = new EdgeKV({namespace: KVSPACE})
const expiration = Math.floor(new Date().getTime() / 1000) + 300 // Automatically expires after 5 minutes
await kv.put(imgURL, imgData, {expiration: expiration})
return new Response(imgURL)
}
async function decodeBase64Image(request) {
// data:image/png;base64,/9j/4AAQSkZJRgABA...
let base64Image = await request.text()
const splitImage = base64Image.split(',')
const fileType = splitImage[0].split(':')[1].split('/')[0]
if (fileType != 'image') {
return {fileType: fileType, imageType: null, imgData: null}
}
const imgType = splitImage[0].split(';')[0].split('/')[1]
var decodedImage = atob(splitImage[1])
var arrayBuffer = new ArrayBuffer(decodedImage.length);
var uint8Array = new Uint8Array(arrayBuffer);
for (var i = 0; i < decodedImage.length; i++) {
uint8Array[i] = decodedImage.charCodeAt(i);
}
return {fileType: fileType, imgType: imgType, imgData: arrayBuffer}
}
async function handleAccessImg(request) {
let imgURL = request.url
if (imgURL.endsWith('/')) imgURL = imgURL.substring(0, imgURL.length - 1)
const kv = new EdgeKV({namespace: KVSPACE})
const img = await kv.get(imgURL, {type: "stream"})
if (img) {
return new Response(img, {headers: {"content-type": contentTypeOfFile(imgURL)}})
} else {
return new Response("Img not found", {status: 404})
}
}
function contentTypeOfFile(fileName) {
const ext = fileName.split('.').pop()
return 'image/' + ext
}
const HOMEPAGE_EN = `
<!DOCTYPE html>
<html>
<head>
<style>
#dropzone {
width: 300px;
height: 300px;
border: 2px dashed #aaa;
margin: 0 auto;
margin-top: 50px;
display: flex;
justify-content: center;
align-items: center;
}
#dropzone img {
max-width: 100%;
max-height: 100%;
}
#upload-button {
display: block;
margin: 20px auto;
}
#response-body {
width: 80%;
margin: 0 auto;
margin-top: 50px;
white-space: pre-wrap;
word-wrap: break-word;
border: 1px solid #aaa;
padding: 20px;
}
#copy-button {
display: block;
margin: 20px auto;
}
</style>
</head>
<body>
<div id="dropzone" style="text-align:center">Drag and drop or Ctrl+V </br> to paste image here</div>
<input id="upload-button" type="button" value="Upload Image">
<pre id="response-body"></pre>
<input id="copy-button" type="button" value="Copy Link">
<p style="text-align:center;color:gray;">Link is for testing purposes only and will automatically expire after 5 minutes</p>
<script>
var dropzone = document.getElementById('dropzone');
var uploadButton = document.getElementById('upload-button');
var responseBody = document.getElementById('response-body');
var copyButton = document.getElementById('copy-button');
dropzone.addEventListener('dragover', function (event) {
event.preventDefault();
dropzone.style.borderStyle = 'solid';
});
dropzone.addEventListener('dragleave', function (event) {
event.preventDefault();
dropzone.style.borderStyle = 'dashed';
});
dropzone.addEventListener('drop', function (event) {
event.preventDefault();
dropzone.style.borderStyle = 'dashed';
var file = event.dataTransfer.files[0];
var reader = new FileReader();
reader.onload = function () {
var img = document.createElement('img');
img.src = reader.result;
dropzone.innerHTML = '';
dropzone.appendChild(img);
};
reader.readAsDataURL(file);
});
document.addEventListener('paste', function (event) {
if (event.clipboardData && event.clipboardData.items) {
for (var i = 0; i < event.clipboardData.items.length; i++) {
var item = event.clipboardData.items[i];
if (item.type.indexOf('image') !== -1) {
var file = item.getAsFile();
var reader = new FileReader();
reader.onload = function () {
var img = document.createElement('img');
img.src = reader.result;
dropzone.innerHTML = '';
dropzone.appendChild(img);
};
reader.readAsDataURL(file);
}
}
}
});
uploadButton.addEventListener('click', function () {
var imgData = dropzone.firstChild.src;
var formData = new FormData();
fetch('/imgbed/upload/', {
method: 'POST',
body: imgData
})
.then((response) => response.text())
.then((body) => {
responseBody.textContent = body;
})
.catch((error) => {
console.error('Error:', error);
});
});
copyButton.addEventListener('click', function () {
const textarea = document.createElement('textarea');
textarea.value = responseBody.textContent;
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
document.body.removeChild(textarea);
});
</script>
</body>
</html>
`
addEventListener("fetch", event => {
return event.respondWith(handleRequest(event.request))
})