diff --git a/src/handlers/handler-input.ts b/src/handlers/handler-input.ts index 7c7693e..7877c84 100644 --- a/src/handlers/handler-input.ts +++ b/src/handlers/handler-input.ts @@ -1,5 +1,6 @@ import { JSDOM } from "jsdom"; -import { generateProxyUrl } from "../utils/generate"; +import { generateParserUrl, generateProxyUrl } from "../utils/generate"; +import getConfig from "../config/main"; export class HandlerInput { private data: string; @@ -23,6 +24,10 @@ export class HandlerInput { this.redirectPath = redirectPath; } + getUrl(): string { + return this.url; + } + parseDom(): JSDOM { if (this.dom) { return this.dom; @@ -30,24 +35,78 @@ export class HandlerInput { this.dom = new JSDOM(this.data, { url: this.url }); - const links = this.dom.window.document.getElementsByTagName("a"); - for (const link of links) { - try { - link.href = generateProxyUrl( - this.requestUrl, - link.href, - this.engine, - this.redirectPath, - ); - } catch (_err) { - // ignore TypeError: Invalid URL + const bytag = + (dom: JSDOM, tag: string) => dom.window.document.getElementsByTagName(tag); + const bycss = + (dom: JSDOM, css: string) => dom.window.document.querySelectorAll(css); + + const parserUrl = (href: string) => generateParserUrl( + this.requestUrl, + href, + this.engine, + this.redirectPath, + ); + const proxyUrl = (href: string) => generateProxyUrl( + this.requestUrl, + href, + ); + + this.modifyLinks( + bytag(this.dom, "a"), + "href", + parserUrl, + ); + this.modifyLinks( + bycss(this.dom, "frame,iframe"), + "src", + parserUrl, + ); + + if (getConfig().proxy_res) { + this.modifyLinks( + bycss(this.dom, "img,image,video,audio,embed,track,source"), + "src", + proxyUrl, + ); + + this.modifyLinks( + bytag(this.dom, "object"), + "data", + proxyUrl, + ); + + const sources = bytag(this.dom, "source"); + for (const source of sources) { + // split srcset by comma + // @ts-ignore + source.srcset = source.srcset.split(",").map( + (src: string) => { + // split src by space + const parts = src.split(" "); + try { + // first part is URL + parts[0] = proxyUrl(parts[0]); + } catch (_err) { } + // join by space after splitting + return parts.join(" "); + } + ).join(","); // join by comma } } return this.dom; } - getUrl(): string { - return this.url; + private modifyLinks( + nodeList: NodeListOf | HTMLCollectionOf, + property: string, + generateLink: (value: string) => string, + ) { + for (const node of nodeList) { + try { + // @ts-ignore + node[property] = generateLink(node[property]); + } catch (_err) { } + } } } diff --git a/src/utils/generate.ts b/src/utils/generate.ts index 4d5a006..a275585 100644 --- a/src/utils/generate.ts +++ b/src/utils/generate.ts @@ -6,7 +6,7 @@ export function generateRequestUrl( return new URL(`${protocol}://${host}${originalUrl}`); } -export function generateProxyUrl( +export function generateParserUrl( requestUrl: URL, href: string, engine?: string, @@ -22,3 +22,11 @@ export function generateProxyUrl( return `${requestUrl.origin}/${redirect_url}${urlParam}${engineParam}${hash}`; } + +export function generateProxyUrl( + requestUrl: URL, + href: string, +): string { + const urlParam = `?url=${encodeURIComponent(href)}`; + return `${requestUrl.origin}/proxy${urlParam}`; +}