feat(api): streaming des fichiers livres avec support Range
Réponses 206 partielles avec Content-Range/Accept-Ranges pour la lecture PDF, types MIME explicites par format, en-tête Content-Disposition UTF-8 et nosniff. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Param, Query, Res, UseGuards } from "@nestjs/common";
|
||||
import { Controller, Get, Headers, Param, Query, Res, UseGuards } from "@nestjs/common";
|
||||
import { FastifyReply } from "fastify";
|
||||
import { lookup } from "mime-types";
|
||||
import { BookQueryDto, BookQuerySchema } from "@readabook/shared";
|
||||
@ -40,10 +40,17 @@ export class BooksController {
|
||||
}
|
||||
|
||||
@Get(":id/file")
|
||||
file(@Param("id") id: string, @Res() reply: FastifyReply) {
|
||||
const { book, stream } = this.books.streamFile(Number(id));
|
||||
reply.header("Content-Type", lookup(book.filePath) || "application/octet-stream");
|
||||
reply.header("Content-Disposition", `inline; filename="${encodeURIComponent(book.title)}.${book.format}"`);
|
||||
file(@Param("id") id: string, @Headers("range") range: string | undefined, @Res() reply: FastifyReply) {
|
||||
const { book, stream, contentLength, contentType, end, partial, size, start } = this.books.streamFile(Number(id), range);
|
||||
if (partial) {
|
||||
reply.code(206);
|
||||
reply.header("Content-Range", `bytes ${start}-${end}/${size}`);
|
||||
}
|
||||
reply.header("Accept-Ranges", "bytes");
|
||||
reply.header("Content-Length", String(contentLength));
|
||||
reply.header("Content-Type", contentType || lookup(book.filePath) || "application/octet-stream");
|
||||
reply.header("Content-Disposition", `inline; filename*=UTF-8''${encodeURIComponent(`${book.title}.${book.format}`)}`);
|
||||
reply.header("X-Content-Type-Options", "nosniff");
|
||||
return reply.send(stream);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user