spoof user agent to firefox 143 on linux to bypass instagram bot protection

This commit is contained in:
m5r
2025-09-25 19:14:35 +02:00
parent b4b89cb0c0
commit 2219e72bd2
2 changed files with 24 additions and 10 deletions

View File

@@ -1,6 +1,6 @@
import type { ClearURLsRules } from "./types"; import type { ClearURLsRules } from "./types";
export async function cleanUrl(inputUrl: string, rules: ClearURLsRules, maxRedirects = 5, visited = new Set<string>()): Promise<string> { export async function cleanUrl(inputUrl: string, rules: ClearURLsRules, maxRedirects = 5, visited = new Set<string>()) {
try { try {
const currentUrl = new URL(inputUrl); const currentUrl = new URL(inputUrl);
@@ -18,6 +18,7 @@ export async function cleanUrl(inputUrl: string, rules: ClearURLsRules, maxRedir
// Then check for HTTP redirects // Then check for HTTP redirects
const redirectTarget = await followRedirect(currentUrl.href); const redirectTarget = await followRedirect(currentUrl.href);
console.log("redirectTarget", redirectTarget);
if (redirectTarget && redirectTarget !== currentUrl.href) { if (redirectTarget && redirectTarget !== currentUrl.href) {
return await cleanUrl(redirectTarget, rules, maxRedirects, visited); return await cleanUrl(redirectTarget, rules, maxRedirects, visited);
} }
@@ -29,7 +30,7 @@ export async function cleanUrl(inputUrl: string, rules: ClearURLsRules, maxRedir
} }
} }
async function followRedirect(url: string): Promise<string | null> { async function followRedirect(url: string) {
// @ts-ignore - Skip redirect following in tests to avoid external HTTP calls // @ts-ignore - Skip redirect following in tests to avoid external HTTP calls
if (typeof global !== "undefined" && global.process?.env?.NODE_ENV === "test") { if (typeof global !== "undefined" && global.process?.env?.NODE_ENV === "test") {
return null; return null;
@@ -39,6 +40,19 @@ async function followRedirect(url: string): Promise<string | null> {
const response = await fetch(url, { const response = await fetch(url, {
method: "HEAD", method: "HEAD",
redirect: "manual", redirect: "manual",
headers: {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:143.0) Gecko/20100101 Firefox/143.0",
Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "en-US,en;q=0.5",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Sec-GPC": "1",
"Upgrade-Insecure-Requests": "1",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "none",
"Sec-Fetch-User": "?1",
Connection: "keep-alive",
},
}); });
if (response.status >= 300 && response.status < 400) { if (response.status >= 300 && response.status < 400) {
@@ -59,7 +73,7 @@ async function followRedirect(url: string): Promise<string | null> {
} }
} }
function cleanUrlParameters(url: URL, providers: ClearURLsRules["providers"]): string { function cleanUrlParameters(url: URL, providers: ClearURLsRules["providers"]) {
const matchingProvider = findMatchingProvider(url.href, providers); const matchingProvider = findMatchingProvider(url.href, providers);
if (!matchingProvider) { if (!matchingProvider) {
@@ -169,7 +183,7 @@ function cleanFragmentsByRules(url: URL, rules: string[]) {
return url; return url;
} }
function extractFragments(url: URL): Map<string, string | null> { function extractFragments(url: URL) {
const fragments = new Map<string, string | null>(); const fragments = new Map<string, string | null>();
const hash = url.hash.slice(1); // Remove the # const hash = url.hash.slice(1); // Remove the #
@@ -191,7 +205,7 @@ function extractFragments(url: URL): Map<string, string | null> {
return fragments; return fragments;
} }
function fragmentsToString(fragments: Map<string, string | null>): string { function fragmentsToString(fragments: Map<string, string | null>) {
const parts: string[] = []; const parts: string[] = [];
for (const [key, value] of fragments) { for (const [key, value] of fragments) {
if (value !== null) { if (value !== null) {
@@ -203,7 +217,7 @@ function fragmentsToString(fragments: Map<string, string | null>): string {
return parts.length > 0 ? parts.join("&") : ""; return parts.length > 0 ? parts.join("&") : "";
} }
function isException(url: string, exceptions: string[]): boolean { function isException(url: string, exceptions: string[]) {
for (const exception of exceptions) { for (const exception of exceptions) {
try { try {
const regex = new RegExp(exception, "i"); const regex = new RegExp(exception, "i");
@@ -217,7 +231,7 @@ function isException(url: string, exceptions: string[]): boolean {
return false; return false;
} }
function checkClearUrlsRedirections(url: string, providers: ClearURLsRules["providers"]): string | null { function checkClearUrlsRedirections(url: string, providers: ClearURLsRules["providers"]) {
const matchingProvider = findMatchingProvider(url, providers); const matchingProvider = findMatchingProvider(url, providers);
if (!matchingProvider || !matchingProvider.redirections) { if (!matchingProvider || !matchingProvider.redirections) {

View File

@@ -8,15 +8,15 @@ type Env = {
export { RulesCache }; export { RulesCache };
export default { export default {
async fetch(request, env, ctx): Promise<Response> { async fetch(request, env, ctx) {
if (request.method !== "GET" && request.method !== "DELETE") { if (request.method !== "GET" && request.method !== "DELETE") {
return new Response("Method not allowed", { return new Response("Method not allowed", {
status: 405, status: 405,
headers: { headers: {
"Allow": "GET, DELETE", Allow: "GET, DELETE",
"Content-Type": "text/plain", "Content-Type": "text/plain",
"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Origin": "*",
} },
}); });
} }