u
This commit is contained in:
@@ -2,7 +2,7 @@ import crypto from 'node:crypto';
|
||||
import fs from 'node:fs';
|
||||
import https from 'node:https';
|
||||
import path from 'node:path';
|
||||
import { URL } from 'node:url';
|
||||
import { URL, pathToFileURL } from 'node:url';
|
||||
|
||||
import {
|
||||
ACCESS_KEY,
|
||||
@@ -32,6 +32,9 @@ function send(res, status, body = '', headers = {}) {
|
||||
}
|
||||
|
||||
function readBody(req) {
|
||||
if (req.method === 'GET' || req.method === 'HEAD' || req.method === 'DELETE') {
|
||||
return Promise.resolve(Buffer.alloc(0));
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
const chunks = [];
|
||||
req.on('data', (chunk) => chunks.push(chunk));
|
||||
@@ -169,10 +172,17 @@ function abortMultipart(uploadId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function debug(...args) {
|
||||
if (process.env.S3_BACKUP_DEBUG) {
|
||||
console.error(...args);
|
||||
}
|
||||
}
|
||||
|
||||
async function handle(req, res) {
|
||||
const body = await readBody(req);
|
||||
debug(`${req.method} ${req.url} len=${body.length}`);
|
||||
if (!authOk(req, body)) {
|
||||
console.error(`${req.method} ${req.url} -> 403 auth failed`);
|
||||
debug(`auth failed ${req.method} ${req.url}`);
|
||||
return send(res, 403, xml('<Error><Code>AccessDenied</Code><Message>Access Denied</Message></Error>'));
|
||||
}
|
||||
|
||||
@@ -195,6 +205,10 @@ async function handle(req, res) {
|
||||
return send(res, 200, listBucketXml(query.get('prefix') || ''));
|
||||
}
|
||||
|
||||
if (req.method === 'HEAD' && !key) {
|
||||
return send(res, 200, '');
|
||||
}
|
||||
|
||||
if (req.method === 'GET' && key) {
|
||||
const file = objectPath(key);
|
||||
if (!fs.existsSync(file)) {
|
||||
@@ -258,7 +272,6 @@ async function handle(req, res) {
|
||||
}
|
||||
|
||||
export function startServer() {
|
||||
ensureCerts(HOST);
|
||||
fs.mkdirSync(DATA_DIR, { recursive: true });
|
||||
fs.mkdirSync(TMP_DIR, { recursive: true });
|
||||
|
||||
@@ -272,7 +285,17 @@ export function startServer() {
|
||||
}
|
||||
);
|
||||
|
||||
return new Promise((resolve) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
server.on('error', (err) => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
reject(new Error(`Port ${PORT} is already in use`));
|
||||
return;
|
||||
}
|
||||
reject(err);
|
||||
});
|
||||
server.on('secureConnection', (tlsSocket) => {
|
||||
debug(`tls ${tlsSocket.remoteAddress}:${tlsSocket.remotePort}`);
|
||||
});
|
||||
server.listen(PORT, BIND, () => {
|
||||
console.log(`S3 endpoint https://${HOST}:${PORT}/${BUCKET} -> ${DATA_DIR}`);
|
||||
resolve(server);
|
||||
@@ -280,6 +303,9 @@ export function startServer() {
|
||||
});
|
||||
}
|
||||
|
||||
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||
startServer();
|
||||
if (process.env.S3_BACKUP_CHILD || import.meta.url === pathToFileURL(process.argv[1]).href) {
|
||||
startServer().catch((err) => {
|
||||
console.error(err.message || err);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user