Moved to dependency free nodejs mobile request proxy

This commit is contained in:
WardPearce
2025-01-25 09:05:53 +13:00
parent 95b324599a
commit e0299c03bd
9 changed files with 125 additions and 64 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId "us.materialio.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 81
versionName "1.6.30"
versionCode 82
versionName "1.7.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "Materialious",
"version": "1.6.30",
"version": "1.7.0",
"description": "Modern material design for Invidious.",
"author": {
"name": "Ward Pearce",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "materialious",
"version": "1.6.30",
"version": "1.7.0",
"private": true,
"scripts": {
"dev": "vite dev",
@@ -75,4 +75,4 @@
"vidstack": "^1.12.9",
"youtubei.js": "^12.2.0"
}
}
}
@@ -2,7 +2,7 @@
import 'vidstack/bundle';
import { page } from '$app/stores';
import { getBestThumbnail, proxyGoogleImage } from '$lib/images';
import { getBestThumbnail } from '$lib/images';
import { padTime, videoLength } from '$lib/time';
import { Capacitor } from '@capacitor/core';
import { ScreenOrientation, type ScreenOrientationResult } from '@capacitor/screen-orientation';
@@ -366,7 +366,11 @@
await loadPlayerPos();
});
if (Capacitor.getPlatform() === 'android' && data.video.adaptiveFormats.length > 0) {
if (
Capacitor.getPlatform() === 'android' &&
data.video.adaptiveFormats.length > 0 &&
data.video.fallbackPatch === undefined
) {
if (get(playerAndroidBgPlayer)) {
const highestBitrateAudio = data.video.adaptiveFormats
.filter((format) => format.type.startsWith('audio/'))
@@ -605,9 +609,7 @@
>
<media-provider>
{#if !audioMode}
<media-poster
class="vds-poster"
src={proxyGoogleImage(getBestThumbnail(data.video.videoThumbnails, 1251, 781))}
<media-poster class="vds-poster" src={getBestThumbnail(data.video.videoThumbnails, 1251, 781)}
></media-poster>
{/if}
</media-provider>
+1 -1
View File
@@ -16,7 +16,7 @@ async function getPo(identifier: string): Promise<string | undefined> {
const requestKey = 'O43z0dpjhgX20SCx4KAo';
const bgConfig = {
fetch: fetch,
fetch: Capacitor.getPlatform() === 'android' ? capacitorFetch : fetch,
globalObj: window,
requestKey,
identifier
+108 -4
View File
@@ -1,5 +1,109 @@
const corsAnywhere = require('cors-anywhere');
const http = require('http');
const https = require('https');
corsAnywhere.createServer({
originWhitelist: [],
}).listen(3000, 'localhost');
const HOST = 'localhost';
const PORT = 3000;
const MAX_REDIRECTS = 5;
const ORIGIN = `https://${HOST}`;
function setCorsHeaders(res) {
res.setHeader('Access-Control-Allow-Origin', ORIGIN);
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', '*');
res.setHeader('Access-Control-Allow-Credentials', 'true');
}
function fetchWithRedirects(targetUrl, options, redirectCount = 0) {
return new Promise((resolve, reject) => {
const httpClient = targetUrl.protocol.startsWith('https') ? https : http;
const req = httpClient.request(targetUrl, options, (res) => {
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
if (redirectCount >= MAX_REDIRECTS) {
return reject(new Error('Too many redirects'));
}
let redirectHeaderLocation = res.headers.location;
// Handle relative URLs
if (redirectHeaderLocation.startsWith('/')) {
redirectHeaderLocation = targetUrl.host + redirectHeaderLocation;
}
// Add http:// if missing from the Location header
if (!redirectHeaderLocation.startsWith('http')) {
redirectHeaderLocation = 'http://' + redirectHeaderLocation;
}
try {
// Attempt to create the redirect URL
let redirectUrl = new URL(redirectHeaderLocation);
return resolve(fetchWithRedirects(redirectUrl, options, redirectCount + 1));
} catch (error) {
// Catch invalid URL errors
return reject(new Error(`Invalid URL in redirect: ${error.message}`));
}
}
resolve(res); // Resolve with the final response if not a redirect
});
req.on('error', reject);
req.end();
});
}
const server = http.createServer(async (req, res) => {
setCorsHeaders(res);
if (req.method === 'OPTIONS') {
res.writeHead(200, { 'Content-Type': 'text/plain' });
return res.end();
}
if (!req.url || req.url === '/') {
res.writeHead(400, { 'Content-Type': 'text/plain' });
return res.end('No URL provided to fetch.');
}
const targetUrl = req.url.slice(1); // Remove leading '/'
let parsedTarget;
try {
if (!targetUrl.startsWith('http')) {
targetUrl = 'http://' + targetUrl;
}
parsedTarget = new URL(targetUrl);
} catch (error) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
return res.end(`Invalid URL: ${error.message}`);
}
const options = {
method: req.method,
headers: {
...req.headers,
host: parsedTarget.hostname, // Ensure correct host header
},
};
try {
const proxyRes = await fetchWithRedirects(parsedTarget, options);
res.writeHead(proxyRes.statusCode, {
...proxyRes.headers,
'Access-Control-Allow-Origin': ORIGIN,
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': '*',
'Access-Control-Allow-Credentials': 'true',
});
proxyRes.pipe(res); // Pipe response data back to the client
} catch (error) {
console.error('Proxy error:', error);
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end(`Error: ${error.message}`);
}
});
server.listen(PORT, () => {
console.log(`Server is running on http://${HOST}:${PORT}`);
});
+1 -43
View File
@@ -6,49 +6,7 @@
"packages": {
"": {
"name": "cors-patch",
"version": "0.0.1",
"dependencies": {
"cors-anywhere": "^0.4.4"
}
},
"node_modules/cors-anywhere": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/cors-anywhere/-/cors-anywhere-0.4.4.tgz",
"integrity": "sha512-8OBFwnzMgR4mNrAeAyOLB2EruS2z7u02of2bOu7i9kKYlZG+niS7CTHLPgEXKWW2NAOJWRry9RRCaL9lJRjNqg==",
"dependencies": {
"http-proxy": "1.11.1",
"proxy-from-env": "0.0.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/eventemitter3": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
"integrity": "sha512-DOFqA1MF46fmZl2xtzXR3MPCRsXqgoFqdXcrCVYM3JNnfUeHTm/fh/v/iU7gBFpwkuBmoJPAm5GuhdDfSEJMJA=="
},
"node_modules/http-proxy": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.11.1.tgz",
"integrity": "sha512-qz7jZarkVG3G6GMq+4VRJPSN4NkIjL4VMTNhKGd8jc25BumeJjWWvnY3A7OkCGa8W1TTxbaK3dcE0ijFalITVA==",
"dependencies": {
"eventemitter3": "1.x.x",
"requires-port": "0.x.x"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/proxy-from-env": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-0.0.1.tgz",
"integrity": "sha512-B9Hnta3CATuMS0q6kt5hEezOPM+V3dgaRewkFtFoaRQYTVNsHqUvFXmndH06z3QO1ZdDnRELv5vfY6zAj/gG7A=="
},
"node_modules/requires-port": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-0.0.1.tgz",
"integrity": "sha512-AzPDCliPoWDSvEVYRQmpzuPhGGEnPrQz9YiOEvn+UdB9ixBpw+4IOZWtwctmpzySLZTy7ynpn47V14H4yaowtA=="
"version": "0.0.1"
}
}
}
@@ -1,8 +1,5 @@
{
"name": "cors-patch",
"version": "0.0.1",
"main": "./index.js",
"dependencies": {
"cors-anywhere": "^0.4.4"
}
}
"main": "./index.js"
}
+1 -1
View File
@@ -5,7 +5,7 @@ import json
import os
import re
LATEST_VERSION = "1.6.30"
LATEST_VERSION = "1.7.0"
WORKING_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "materialious")
ROOT_PACKAGE = os.path.join(WORKING_DIR, "package.json")