try to do more resiliant url handling
This commit is contained in:
@@ -24,6 +24,11 @@ export interface SearchResult {
|
||||
thumbnailUrl: string;
|
||||
}
|
||||
|
||||
export interface ThumbnailResponse {
|
||||
data: NodeJS.ReadableStream;
|
||||
contentType: string;
|
||||
}
|
||||
|
||||
const USE_INVIDIOUS = process.env.USE_INVIDIOUS || true;
|
||||
const INVIDIOUS_BASE_URL = process.env.INVIDIOUS_BASE_URL || 'http://invidious.nor';
|
||||
const INVIDIOUS_API_ENDPOINT = `${INVIDIOUS_BASE_URL}/api/v1`;
|
||||
@@ -76,3 +81,22 @@ export const searchInvidious = async (query: string): Promise<SearchResult[]> =>
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export const fetchThumbnail = async (thumbnailUrl: string): Promise<ThumbnailResponse> => {
|
||||
let path = thumbnailUrl;
|
||||
if (thumbnailUrl.startsWith('http://') || thumbnailUrl.startsWith('https://')) {
|
||||
const url = new URL(thumbnailUrl);
|
||||
path = url.pathname + url.search;
|
||||
}
|
||||
path = path.replace(/^\/+/, ''); // Strip leading slash
|
||||
|
||||
const response = await fetch(getInvidiousThumbnailURL(path));
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return {
|
||||
data: response.body,
|
||||
contentType: response.headers.get('content-type') || 'image/jpeg'
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import express from "express";
|
||||
import expressWs from "express-ws";
|
||||
import { MediaPlayer } from "./MediaPlayer";
|
||||
import { searchInvidious, getInvidiousThumbnailURL } from "./InvidiousAPI";
|
||||
import { searchInvidious, getInvidiousThumbnailURL, fetchThumbnail } from "./InvidiousAPI";
|
||||
import fetch from "node-fetch";
|
||||
|
||||
const app = express();
|
||||
@@ -118,17 +118,9 @@ apiRouter.get("/thumbnail", withErrorHandling(async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const thumbnailUrlWithoutLeadingSlash = thumbnailUrl.startsWith('/') ? thumbnailUrl.slice(1) : thumbnailUrl;
|
||||
const response = await fetch(getInvidiousThumbnailURL(thumbnailUrlWithoutLeadingSlash));
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
// Forward the content type header
|
||||
res.set('Content-Type', response.headers.get('content-type') || 'image/jpeg');
|
||||
|
||||
// Pipe the thumbnail data directly to the response
|
||||
response.body.pipe(res);
|
||||
const { data, contentType } = await fetchThumbnail(thumbnailUrl);
|
||||
res.set('Content-Type', contentType);
|
||||
data.pipe(res);
|
||||
} catch (error) {
|
||||
console.error('Failed to proxy thumbnail:', error);
|
||||
res.status(500)
|
||||
|
||||
Reference in New Issue
Block a user