From 217e861a99d3ef71944fb14338265721622a30d3 Mon Sep 17 00:00:00 2001 From: drunkwinter <38593134+drunkwinter@users.noreply.github.com> Date: Fri, 13 Oct 2023 02:00:07 +0200 Subject: [PATCH] [fix] interceptors exception (#221) Interceptors would try to handle `data:` url's --- src/components/interceptors/request.js | 20 +++++++++++++------- src/components/interceptors/xhrOpen.js | 20 ++++++++++++-------- src/components/requestPreprocessor.js | 18 ++++++++++-------- src/utils/index.js | 16 ---------------- 4 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/components/interceptors/request.js b/src/components/interceptors/request.js index 46c6214..d2b8815 100644 --- a/src/components/interceptors/request.js +++ b/src/components/interceptors/request.js @@ -1,4 +1,3 @@ -import { parseRelativeUrl } from '../../utils'; import * as logger from '../../utils/logger'; export default function attach(onRequestCreate) { @@ -8,19 +7,26 @@ export default function attach(onRequestCreate) { window.Request = new Proxy(window.Request, { construct(target, args) { - const [url, options] = args; + let [url, options] = args; try { - const parsedUrl = parseRelativeUrl(url); - const modifiedUrl = onRequestCreate(parsedUrl, options); + if (typeof url === 'string') { + if (url.indexOf('/') === 0) { + url = window.location.origin + url; + } - if (modifiedUrl) { - args[0] = modifiedUrl.toString(); + if (url.indexOf('https://') !== -1) { + const modifiedUrl = onRequestCreate(url, options); + + if (modifiedUrl) { + args[0] = modifiedUrl; + } + } } } catch (err) { logger.error(err, `Failed to intercept Request()`); } - return Reflect.construct(...arguments); + return Reflect.construct(target, args); }, }); } diff --git a/src/components/interceptors/xhrOpen.js b/src/components/interceptors/xhrOpen.js index d0bcfdf..cf54615 100644 --- a/src/components/interceptors/xhrOpen.js +++ b/src/components/interceptors/xhrOpen.js @@ -1,23 +1,27 @@ -import { parseRelativeUrl } from '../../utils'; import * as logger from '../../utils/logger'; import { nativeXMLHttpRequestOpen } from './natives'; export default function attach(onXhrOpenCalled) { - XMLHttpRequest.prototype.open = function(method, url) { + XMLHttpRequest.prototype.open = function(...args) { + let [method, url] = args; try { - let parsedUrl = parseRelativeUrl(url); + if (typeof url === 'string') { + if (url.indexOf('/') === 0) { + url = window.location.origin + url; + } - if (parsedUrl) { - const modifiedUrl = onXhrOpenCalled(method, parsedUrl, this); + if (url.indexOf('https://') !== -1) { + const modifiedUrl = onXhrOpenCalled(method, url, this); - if (modifiedUrl) { - arguments[1] = modifiedUrl.toString(); + if (modifiedUrl) { + args[1] = modifiedUrl; + } } } } catch (err) { logger.error(err, `Failed to intercept XMLHttpRequest.open()`); } - nativeXMLHttpRequestOpen.apply(this, arguments); + nativeXMLHttpRequestOpen.apply(this, args); }; } diff --git a/src/components/requestPreprocessor.js b/src/components/requestPreprocessor.js index 48fd772..41ade8a 100644 --- a/src/components/requestPreprocessor.js +++ b/src/components/requestPreprocessor.js @@ -13,17 +13,18 @@ import * as unlocker from './unlocker'; * - Add "content check ok" flags to request bodys */ export function handleXhrOpen(method, url, xhr) { - let proxyUrl = unlockGoogleVideo(url); + const url_obj = new URL(url); + let proxyUrl = unlockGoogleVideo(url_obj); if (proxyUrl) { // Exclude credentials from XMLHttpRequest Object.defineProperty(xhr, 'withCredentials', { set: () => {}, get: () => false, }); - return proxyUrl; + return proxyUrl.toString(); } - if (url.pathname.indexOf('/youtubei/') === 0) { + if (url_obj.pathname.indexOf('/youtubei/') === 0) { // Store auth headers in storage for further usage. interceptors.attachGenericInterceptor(xhr, 'setRequestHeader', ([headerName, headerValue]) => { if (Config.GOOGLE_AUTH_HEADER_NAMES.includes(headerName)) { @@ -32,7 +33,7 @@ export function handleXhrOpen(method, url, xhr) { }); } - if (Config.SKIP_CONTENT_WARNINGS && method === 'POST' && ['/youtubei/v1/player', '/youtubei/v1/next'].includes(url.pathname)) { + if (Config.SKIP_CONTENT_WARNINGS && method === 'POST' && ['/youtubei/v1/player', '/youtubei/v1/next'].includes(url_obj.pathname)) { // Add content check flags to player and next request (this will skip content warnings) interceptors.attachGenericInterceptor(xhr, 'send', (args) => { if (typeof args[0] === 'string') { @@ -49,16 +50,17 @@ export function handleXhrOpen(method, url, xhr) { * - Add "content check ok" flags to request bodys */ export function handleFetchRequest(url, requestOptions) { - let newGoogleVideoUrl = unlockGoogleVideo(url); + const url_obj = new URL(url); + const newGoogleVideoUrl = unlockGoogleVideo(url_obj); if (newGoogleVideoUrl) { // Exclude credentials from Fetch Request if (requestOptions.credentials) { requestOptions.credentials = 'omit'; } - return newGoogleVideoUrl; + return newGoogleVideoUrl.toString(); } - if (url.pathname.indexOf('/youtubei/') === 0 && isObject(requestOptions.headers)) { + if (url_obj.pathname.indexOf('/youtubei/') === 0 && isObject(requestOptions.headers)) { // Store auth headers in authStorage for further usage. for (let headerName in requestOptions.headers) { if (Config.GOOGLE_AUTH_HEADER_NAMES.includes(headerName)) { @@ -67,7 +69,7 @@ export function handleFetchRequest(url, requestOptions) { } } - if (Config.SKIP_CONTENT_WARNINGS && ['/youtubei/v1/player', '/youtubei/v1/next'].includes(url.pathname)) { + if (Config.SKIP_CONTENT_WARNINGS && ['/youtubei/v1/player', '/youtubei/v1/next'].includes(url_obj.pathname)) { // Add content check flags to player and next request (this will skip content warnings) requestOptions.body = setContentCheckOk(requestOptions.body); } diff --git a/src/utils/index.js b/src/utils/index.js index e0150c2..bde7eb2 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -142,19 +142,3 @@ export function waitForElement(elementSelector, timeout) { return deferred; } - -export function parseRelativeUrl(url) { - if (typeof url !== 'string') { - return null; - } - - if (url.indexOf('/') === 0) { - url = window.location.origin + url; - } - - try { - return url.indexOf('https://') === 0 ? new window.URL(url) : null; - } catch { - return null; - } -}