A small web app for watching movies and shows easily
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

84 lines
2.4 KiB

import { Fetcher, makeSimpleProxyFetcher } from "@movie-web/providers";
import { sendExtensionRequest } from "@/backend/extension/messaging";
import { getApiToken, setApiToken } from "@/backend/helpers/providerApi";
import { getProviderApiUrls, getProxyUrls } from "@/utils/proxyUrls";
function makeLoadbalancedList(getter: () => string[]) {
let listIndex = -1;
return () => {
const fetchers = getter();
if (listIndex === -1 || listIndex >= fetchers.length) {
listIndex = Math.floor(Math.random() * fetchers.length);
}
const proxyUrl = fetchers[listIndex];
listIndex = (listIndex + 1) % fetchers.length;
return proxyUrl;
};
}
export const getLoadbalancedProxyUrl = makeLoadbalancedList(getProxyUrls);
export const getLoadbalancedProviderApiUrl =
makeLoadbalancedList(getProviderApiUrls);
async function fetchButWithApiTokens(
input: RequestInfo | URL,
init?: RequestInit | undefined,
): Promise<Response> {
const apiToken = await getApiToken();
const headers = new Headers(init?.headers);
if (apiToken) headers.set("X-Token", apiToken);
const response = await fetch(
input,
init
? {
...init,
headers,
}
: undefined,
);
const newApiToken = response.headers.get("X-Token");
if (newApiToken) setApiToken(newApiToken);
return response;
}
export function makeLoadBalancedSimpleProxyFetcher() {
const fetcher: Fetcher = async (a, b) => {
const currentFetcher = makeSimpleProxyFetcher(
getLoadbalancedProxyUrl(),
fetchButWithApiTokens,
);
return currentFetcher(a, b);
};
return fetcher;
}
function makeFinalHeaders(
readHeaders: string[],
headers: Record<string, string>,
): Headers {
const lowercasedHeaders = readHeaders.map((v) => v.toLowerCase());
return new Headers(
Object.entries(headers).filter((entry) =>
lowercasedHeaders.includes(entry[0].toLowerCase()),
),
);
}
export function makeExtensionFetcher() {
const fetcher: Fetcher = async (url, ops) => {
const result = (await sendExtensionRequest<any>({
url,
...ops,
})) as any;
if (!result?.success) throw new Error(`extension error: ${result?.error}`);
const res = result.response;
return {
body: res.body,
finalUrl: res.finalUrl,
statusCode: res.statusCode,
headers: makeFinalHeaders(ops.readHeaders, res.headers),
};
};
return fetcher;
}