Upload files to "/"
This commit is contained in:
8
Dockerfile
Normal file
8
Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
||||
FROM node:20-alpine
|
||||
WORKDIR /app
|
||||
COPY server.js ./
|
||||
COPY public ./public
|
||||
RUN mkdir -p data && chown -R node:node /app
|
||||
USER node
|
||||
EXPOSE 3000
|
||||
CMD ["node","server.js"]
|
||||
8
compose.yml
Normal file
8
compose.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
services:
|
||||
signup:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:3000"
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
restart: unless-stopped
|
||||
48
server.js
Normal file
48
server.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import { createServer } from 'http';
|
||||
import { appendFile, mkdir, readFile, stat } from 'fs/promises';
|
||||
import { existsSync, createReadStream } from 'fs';
|
||||
import { resolve, extname } from 'path';
|
||||
|
||||
const PORT = process.env.PORT || 3000;
|
||||
const HOST = '0.0.0.0';
|
||||
const PUBLIC_DIR = resolve('./public');
|
||||
const DATA_DIR = resolve('./data');
|
||||
const CSV = resolve(DATA_DIR, 'signups.csv');
|
||||
const emailSet = new Set();
|
||||
|
||||
const mime = { '.html':'text/html','.js':'application/javascript','.css':'text/css' };
|
||||
|
||||
async function ensureFile() {
|
||||
await mkdir(DATA_DIR, { recursive:true });
|
||||
if(!existsSync(CSV)) await appendFile(CSV, 'timestamp,email\n');
|
||||
}
|
||||
|
||||
function validEmail(e){return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);}
|
||||
|
||||
async function serveFile(path, res){
|
||||
try{
|
||||
const st=await stat(path);
|
||||
res.writeHead(200,{'Content-Type':mime[extname(path)]||'text/plain'});
|
||||
createReadStream(path).pipe(res);
|
||||
}catch{res.writeHead(404).end('Not found');}
|
||||
}
|
||||
|
||||
createServer(async (req,res)=>{
|
||||
if(req.url==='/api/subscribe' && req.method==='POST'){
|
||||
let body='';for await(const c of req)body+=c;
|
||||
try{
|
||||
const {email}=JSON.parse(body);
|
||||
if(!validEmail(email)){res.writeHead(400).end('Invalid');return;}
|
||||
if(emailSet.has(email)){res.writeHead(200).end('OK');return;}
|
||||
const line=`${new Date().toISOString()},${email}\n`;
|
||||
await appendFile(CSV,line);emailSet.add(email);
|
||||
res.writeHead(200).end('Saved');
|
||||
}catch{res.writeHead(500).end('Error');}
|
||||
return;
|
||||
}
|
||||
const path = req.url==='/'?resolve(PUBLIC_DIR,'index.html'):resolve(PUBLIC_DIR,req.url.slice(1));
|
||||
serveFile(path,res);
|
||||
}).listen(PORT,HOST,async()=>{
|
||||
await ensureFile();
|
||||
console.log(`Running on http://${HOST}:${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user