From ebc05521694cd177323a67c6fc6fd40d58fe4d96 Mon Sep 17 00:00:00 2001 From: DarkCat09 Date: Wed, 16 Aug 2023 13:17:47 +0400 Subject: [PATCH 1/2] Custom exceptions, redirect in case of non-html content --- src/errors.ts | 3 +++ src/handlers/google.ts | 4 +++- src/handlers/main.ts | 14 ++++++++++--- src/handlers/readability.ts | 2 +- src/routes/get.ts | 41 +++++++++++++++++++++---------------- 5 files changed, 41 insertions(+), 23 deletions(-) create mode 100644 src/errors.ts diff --git a/src/errors.ts b/src/errors.ts new file mode 100644 index 0000000..f686ce2 --- /dev/null +++ b/src/errors.ts @@ -0,0 +1,3 @@ +export class EngineParseError extends Error {} +export class InvalidParameterError extends Error {} +export class NotHtmlMimetypeError extends Error {} diff --git a/src/handlers/google.ts b/src/handlers/google.ts index e3ca526..ce8f84a 100644 --- a/src/handlers/google.ts +++ b/src/handlers/google.ts @@ -9,7 +9,9 @@ export default async function google( ); if (!googleAnchors) { - throw new Error("Failed to find anchors in search result [google]"); + throw new EngineParseError( + "Failed to find anchors in search result [google]" + ); } const results = [...googleAnchors]; diff --git a/src/handlers/main.ts b/src/handlers/main.ts index 1a77b66..475d9b4 100644 --- a/src/handlers/main.ts +++ b/src/handlers/main.ts @@ -8,6 +8,8 @@ import readability from "./readability"; import google from "./google"; import { generateProxyUrl } from "../utils"; +import { InvalidParameterError, NotHtmlMimetypeError } from "../errors"; + export default async function handlePage( url: string, requestUrl: URL, @@ -15,18 +17,24 @@ export default async function handlePage( ): Promise { if (engine && engineList.indexOf(engine) === -1) { - throw new Error("Invalid engine"); + throw new InvalidParameterError("Invalid engine"); } const response = await axios.get(url); + const mime: string | undefined = ( + response.headers["content-type"]?.toString() + ); + + if (mime && mime.indexOf("text/html") === -1) { + throw new NotHtmlMimetypeError(); + } + const window = new JSDOM(response.data, { url: url }).window; [...window.document.getElementsByTagName("a")].forEach((link) => { link.href = generateProxyUrl(requestUrl, link.href, engine); }); - // maybe implement image proxy? - if (engine) { return engines[engine](window); } diff --git a/src/handlers/readability.ts b/src/handlers/readability.ts index f4388ea..08a718a 100644 --- a/src/handlers/readability.ts +++ b/src/handlers/readability.ts @@ -9,7 +9,7 @@ export default async function readability( const parsed = reader.parse(); if (!parsed) { - throw new Error("Failed to parse [readability]"); + throw new EngineParseError("Failed to parse [readability]"); } return { diff --git a/src/routes/get.ts b/src/routes/get.ts index 227908f..8fb84be 100644 --- a/src/routes/get.ts +++ b/src/routes/get.ts @@ -4,34 +4,39 @@ import { GetRequest } from "../types/requests"; import handlePage from "../handlers/main"; import { generateRequestUrl } from "../utils"; +import { NotHtmlMimetypeError } from "../errors"; + export default async function getRoute(fastify: FastifyInstance) { fastify.get("/get", async (request: GetRequest, reply) => { const remoteUrl = request.query.url; const engine = request.query.engine; - let format: string; + let parsed; + try { + parsed = await handlePage( + remoteUrl, + generateRequestUrl( + request.protocol, + request.hostname, + request.originalUrl + ), + engine + ); + } + catch (err) { + if (err instanceof NotHtmlMimetypeError) { + return reply.redirect(301, remoteUrl); + } + else { + throw err; + } + } if (request.query.format === "text") { reply.type("text/plain; charset=utf-8"); - format = "text"; - } else { - reply.type("text/html; charset=utf-8"); - format = "html"; - } - - const parsed = await handlePage( - remoteUrl, - generateRequestUrl( - request.protocol, - request.hostname, - request.originalUrl - ), - engine - ); - - if (format === "text") { return parsed.textContent; } else { + reply.type("text/html; charset=utf-8"); return reply.view("/templates/get.ejs", { parsed: parsed }); } }); From 399992fce0d56aec094f5e56854eec94e0557f3b Mon Sep 17 00:00:00 2001 From: Artemy Date: Wed, 16 Aug 2023 12:23:14 +0300 Subject: [PATCH 2/2] fix: imports --- src/handlers/google.ts | 1 + src/handlers/readability.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/handlers/google.ts b/src/handlers/google.ts index ce8f84a..116e02c 100644 --- a/src/handlers/google.ts +++ b/src/handlers/google.ts @@ -1,5 +1,6 @@ import { DOMWindow } from "jsdom"; import { IHandlerOutput } from "./handler.interface"; +import { EngineParseError } from "../errors"; export default async function google( window: DOMWindow diff --git a/src/handlers/readability.ts b/src/handlers/readability.ts index 08a718a..191a754 100644 --- a/src/handlers/readability.ts +++ b/src/handlers/readability.ts @@ -1,6 +1,7 @@ import { Readability } from "@mozilla/readability"; import { IHandlerOutput } from "./handler.interface"; import { DOMWindow } from "jsdom"; +import { EngineParseError } from "../errors"; export default async function readability( window: DOMWindow