@opengis/fastify-table
Version:
core-plugins
66 lines (65 loc) • 2.68 kB
JavaScript
import config from "../../../config.js";
const { chunkSize = 1048576 } = config;
import { prefix } from "../../plugins/upload/index.js";
import startUpload from "../../plugins/upload/startUpload.js";
import uploadChunk from "../../plugins/upload/uploadChunk.js";
import getUploadStatus from "../../plugins/upload/getUploadStatus.js";
const policy = "L0"; // public
export default function plugin(app) {
// provide server with metadata for chunked upload
app.post(`/${prefix}/start`, { config: { policy, description: "Init chunked upload" } }, async (req, reply) => {
const { fileName, size, subdir, id } = req.body || {};
if (!fileName || !size) {
return reply
.code(400)
.send({ error: "fileName and size required", code: 400 });
}
const result = await startUpload({ fileName, size, subdir, id });
if (result.code) {
return reply
.status(result.code)
.send({ error: result.error, code: result.code });
}
return result;
});
// disable default parser for PATCH /upload/:id
// allows accept all content types (req.body = raw buffer)
// limit body size to 50MB by default, depends on upload chunk size
app.addContentTypeParser("*", { parseAs: "buffer", bodyLimit: chunkSize * 50 }, (req, body, done) => {
done(null, body);
});
// upload chunks
app.patch(`/${prefix}/:id`, { config: { policy, description: "Upload chunk of data" } }, async (req, reply) => {
if (!req.headers["content-range"]) {
return reply
.status(411)
.send({ error: "Content-Range required", code: 411 });
}
const match = req.headers["content-range"].match(/bytes (\d+)-(\d+)\/(\d+)/);
if (!match) {
return { error: "Invalid Content-Range", code: 400 };
}
const offset = parseInt(match[1], 10);
const end = parseInt(match[2], 10);
const size = parseInt(match[3], 10);
const result = await uploadChunk({
id: req.params.id,
body: req.body,
offset,
end,
size,
});
if (result.code) {
return reply
.status(result.code)
.send({ error: result.error, code: result.code });
}
return result;
});
// check upload status
app.get(`/${prefix}/:id`, { config: { policy, description: "Check chunked upload status" } }, async (req) => {
const { id } = req.params;
const status = await getUploadStatus({ id });
return status;
});
}