Compare commits

..

4 Commits

Author SHA1 Message Date
diced
41e197ed4a feat(v3.7.12): version 2025-01-30 19:05:14 -08:00
diced
2f12b63753 fix: potential xss 2025-01-30 19:04:41 -08:00
diced
b5f09673ac fix: should fix ranged requests? 2025-01-22 23:00:48 -08:00
diced
eb71c2bb54 fix: s3 range requests 2025-01-09 22:54:03 -08:00
6 changed files with 48 additions and 8 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "zipline",
"version": "3.7.11",
"version": "3.7.12",
"license": "MIT",
"scripts": {
"dev": "npm-run-all build:server dev:run",

View File

@@ -46,6 +46,15 @@ export class S3 extends Datasource {
}
public get(file: string, start: number = 0, end: number = Infinity): Promise<Readable> {
if (start === 0 && end === Infinity) {
return new Promise((res) => {
this.s3.getObject(this.config.bucket, file, (err, stream) => {
if (err) res(null);
else res(stream);
});
});
}
return new Promise((res) => {
this.s3.getPartialObject(
this.config.bucket,

View File

@@ -96,7 +96,10 @@ export default function Login({
setLoading(false);
}
} else {
await router.push((router.query.url as string) || '/dashboard');
let redirectUrl = (router.query.url as string) || '/dashboard';
if (!redirectUrl.startsWith('/dashboard')) redirectUrl = '/dashboard';
await router.push(redirectUrl);
}
};

View File

@@ -21,7 +21,7 @@ function dbFileDecorator(fastify: FastifyInstance, _, done) {
let [rangeStart, rangeEnd] = parseRangeHeader(this.request.headers.range);
if (rangeStart >= rangeEnd)
return this.code(416)
.header('Content-Range', `bytes */${size - 1}`)
.header('Content-Range', `bytes 0/${size - 1}`)
.send();
if (rangeEnd === Infinity) rangeEnd = size - 1;

View File

@@ -5,6 +5,7 @@ import fastifyPlugin from 'fastify-plugin';
import { createBrotliCompress, createDeflate, createGzip } from 'zlib';
import pump from 'pump';
import { Transform } from 'stream';
import { parseRangeHeader } from 'lib/utils/range';
function rawFileDecorator(fastify: FastifyInstance, _, done) {
fastify.decorateReply('rawFile', rawFile);
@@ -12,13 +13,30 @@ function rawFileDecorator(fastify: FastifyInstance, _, done) {
async function rawFile(this: FastifyReply, id: string) {
const { download, compress = 'false' } = this.request.query as { download?: string; compress?: string };
const data = await this.server.datasource.get(id);
if (!data) return this.notFound();
const size = await this.server.datasource.size(id);
if (size === null) return this.notFound();
const mimetype = await guess(extname(id).slice(1));
const size = await this.server.datasource.size(id);
// eslint-disable-next-line prefer-const
let [rangeStart, rangeEnd] = parseRangeHeader(this.request.headers.range);
if (rangeStart >= rangeEnd)
return this.code(416)
.header('Content-Range', `bytes 0/${size - 1}`)
.send();
if (rangeEnd === Infinity) rangeEnd = size - 1;
const data = await this.server.datasource.get(id, rangeStart, rangeEnd + 1);
// only send content-range if the client asked for it
if (this.request.headers.range) {
this.code(206);
this.header('Content-Range', `bytes ${rangeStart}-${rangeEnd}/${size}`);
}
this.header('Content-Length', rangeEnd - rangeStart + 1);
this.header('Content-Type', download ? 'application/octet-stream' : mimetype);
this.header('Accept-Ranges', 'bytes');
if (
this.server.config.core.compression.enabled &&
@@ -28,7 +46,7 @@ function rawFileDecorator(fastify: FastifyInstance, _, done) {
)
if (size > this.server.config.core.compression.threshold && mimetype.match(/^(image|video|text)/))
return this.send(useCompress.call(this, data));
this.header('Content-Length', size);
return this.send(data);
}
}

View File

@@ -100,6 +100,16 @@ async function start() {
done();
});
server.setErrorHandler((error, request, reply) => {
console.error(error);
reply.status(500).send({
statusCode: 500,
error: 'Internal Server Error',
message: error.message,
});
});
server.get('/favicon.ico', async (_, reply) => {
if (!existsSync('./public/favicon.ico')) return reply.notFound();