mirror of
https://github.com/laochan-eacnet/backend.git
synced 2026-10-05 04:57:58 +03:00
add lz77 decompression
This commit is contained in:
@@ -9,6 +9,7 @@ import { Logger } from "@cordisjs/logger";
|
||||
import { crypto } from "./middlewares/crypto.js";
|
||||
import { binaryBody } from "./middlewares/binarybody.js";
|
||||
import { parseKxml } from "./middlewares/parseKxml.js";
|
||||
import { decompress } from "./middlewares/decompress.js";
|
||||
|
||||
function tryResolve<T>(token: InjectionToken<T>): T | undefined {
|
||||
if (!container.isRegistered(token))
|
||||
@@ -33,6 +34,7 @@ async function main() {
|
||||
const app = new Koa<DefaultState, ILaochanContext>()
|
||||
.use(binaryBody)
|
||||
.use(crypto)
|
||||
.use(decompress)
|
||||
.use(parseKxml)
|
||||
.use(async (ctx, next) => {
|
||||
if (typeof ctx.query.f !== 'string') {
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Next } from "koa";
|
||||
import { Context } from "../types.js";
|
||||
import { lz77Decode } from "../utils/lz77.js";
|
||||
|
||||
export async function decompress(ctx: Context, next: Next) {
|
||||
if (!(ctx.request.body instanceof Buffer)) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (typeof ctx.request.headers['x-compress'] !== 'string') {
|
||||
return next();
|
||||
}
|
||||
|
||||
// no compression for response
|
||||
ctx.set('X-Compress', 'none');
|
||||
|
||||
if (ctx.request.headers['x-compress'] == 'none') {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (ctx.request.headers['x-compress'] != 'lz77') {
|
||||
throw new Error('unsupported compression mehotd');
|
||||
}
|
||||
|
||||
ctx.request.body = lz77Decode(ctx.request.body);
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
export function lz77Decode(data: Buffer): Buffer {
|
||||
let offset = 0;
|
||||
const output: number[] = [];
|
||||
|
||||
while (offset < data.length) {
|
||||
const flag = data[offset];
|
||||
offset += 1;
|
||||
|
||||
for (let bit = 0; bit < 8; bit++) {
|
||||
if (flag & (1 << bit)) {
|
||||
output.push(data[offset]);
|
||||
offset += 1;
|
||||
|
||||
} else {
|
||||
if (offset >= data.length)
|
||||
break;
|
||||
|
||||
const lookbackFlag = data.readUInt16BE(offset);
|
||||
const lookbackLength = (lookbackFlag & 0x000f) + 3;
|
||||
const lookbackOffset = lookbackFlag >> 4;
|
||||
|
||||
offset += 2;
|
||||
if (lookbackFlag == 0)
|
||||
break;
|
||||
|
||||
for (let i = 0; i < lookbackLength; i++) {
|
||||
let loffset = output.length - lookbackOffset;
|
||||
|
||||
if (loffset <= 0 || loffset >= output.length) {
|
||||
output.push(0);
|
||||
} else {
|
||||
output.push(output[loffset]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Buffer.from(output);
|
||||
}
|
||||
Reference in New Issue
Block a user