From 2547909f1819e1b87b055d4b45b69eeeac5dfea6 Mon Sep 17 00:00:00 2001 From: Maiko Sinkyaet Tan Date: Sat, 23 Mar 2024 11:11:51 +0800 Subject: [PATCH] fix(pixiv): download image failed due to early-closed stream (#181) * fix(pixiv): download image failed due to octet-stream content-type * fix: redirect all headers * fix: remove content -length * fix: get correct self url * fix: migrate to arraybuffer temporarily * fix format --------- Co-authored-by: SaarChaffee --- packages/pixiv/src/index.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/pixiv/src/index.ts b/packages/pixiv/src/index.ts index 11c9394b7..5aeb2aff9 100644 --- a/packages/pixiv/src/index.ts +++ b/packages/pixiv/src/index.ts @@ -1,5 +1,4 @@ import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto' -import { Readable } from 'node:stream' import { ReadableStream } from 'node:stream/web' import {} from '@koishijs/assets' import {} from '@koishijs/plugin-server' @@ -47,15 +46,15 @@ class PixivImageSource extends ImageSource { const url = ctx.request.url.replace(/^\/booru\/pixiv\/proxy\//, '') const decrypted = Cipher.decrypt(decodeURIComponent(url), config.aesKey) if (typeof decrypted !== 'string' || !decrypted.startsWith('https://i.pximg.net/')) return next() - const file = await this.http(decrypted, { + const file = await this.http(decrypted, { headers: { Referer: 'https://www.pixiv.net/' }, - responseType: 'stream', + responseType: 'arraybuffer', }) - ctx.set('Content-Type', file.headers['content-type']) - ctx.set('Cache-Control', 'public, max-age=31536000') + ctx.set(Object.fromEntries(file.headers.entries())) + ctx.remove('Content-Length') ctx.response.status = file.status ctx.response.message = file.statusText - ctx.body = Readable.fromWeb(file.data) + ctx.body = Buffer.from(file.data) return next() }) } @@ -204,7 +203,9 @@ class PixivImageSource extends ImageSource { return url.replace(/^https?:\/\/i\.pximg\.net/, trimSlash(proxy)) } else if (this.config.bypassMethod === 'route' && this.config.route && this.ctx.get('server')) { const encrypted = Cipher.encrypt(url, this.config.aesKey) - return trimSlash(this.ctx.server.selfUrl) + trimSlash(this.config.route) + '/' + encodeURIComponent(encrypted) + return ( + trimSlash(this.ctx.server.config.selfUrl) + trimSlash(this.config.route) + '/' + encodeURIComponent(encrypted) + ) } else if (this.config.bypassMethod === 'asset' && this.ctx.get('assets')) { const filename = url.split('/').pop().split('?')[0] const file = await this.http(url, { headers: { Referer: 'https://www.pixiv.net/' } })