diff --git a/Proxatore.php b/Proxatore.php new file mode 100644 index 0000000..96a1b0f --- /dev/null +++ b/Proxatore.php @@ -0,0 +1,597 @@ + ['facebook.com', 'm.facebook.com'], + 'instagram' => ['instagram.com'], + //'juxt' => ['juxt.pretendo.network'], + 'reddit' => ['old.reddit.com', 'reddit.com'], + 'spotify' => ['open.spotify.com'], + 'telegram' => ['t.me', 'telegram.me'], + 'tiktok' => ['tiktok.com'], + 'twitter' => ['twitter.com'], + 'x' => ['x.com'], + 'xiaohongshu' => ['xiaohongshu.com'], + 'youtube' => ['youtube.com', 'm.youtube.com'], +]; + +const PLATFORMS_ALIASES = [ + 'x' => 'twitter', +]; + +const PLATFORMS_PROXIES = [ + 'instagram' => ['ddinstagram.com', 'd.ddinstagram.com'], + 'tiktok' => ['vxtiktok.com'], + 'twitter' => ['fxtwitter.com', 'vxtwitter.com'], + 'x' => ['fixupx.com', 'stupidpenisx.com'], +]; + +const PLATFORMS_REDIRECTS = [ + 'vm.tiktok.com' => 'tiktok', + //'youtu.be' => 'youtube', +]; + +const PLATFORMS_HACKS = ['twitter', 'x']; + +const PLATFORMS_ORDERED = ['telegram']; + +const PLATFORMS_VIDEO = ['facebook', 'instagram']; + +const PLATFORMS_PARAMS = [ + 'facebook' => true, + 'xiaohongshu' => true, + 'youtube' => ['v'], +]; + +const EMBEDS = [ + 'reddit' => ['embed.reddit.com'], +]; + +const EMBEDS_PREFIXES_SIMPLE = [ + 'tiktok' => 'www.tiktok.com/embed/v3/', + 'twitter' => 'platform.twitter.com/embed/Tweet.html?id=', +]; + +const EMBEDS_PREFIXES_PARAMS = [ + 'youtube' => 'www.youtube.com/embed/[v]', +]; + +const EMBEDS_SUFFIXES = [ + 'instagram' => '/embed/captioned/', + 'telegram' => '?embed=1&mode=tme', +]; + +define('EMBEDS_PREFIXES_FULL', [ + 'facebook' => 'www.facebook.com/plugins/post.php?href=' . urlencode('https://www.facebook.com/'), +]); + +define('SCRIPT_NAME', /* $_SERVER['SCRIPT_NAME'] . */ '/'); +define('HISTORY_FILE', './' . $_SERVER['SCRIPT_NAME'] . '.history.jsonl'); + +function lstrip($str, $sub) { + return implode($sub, array_slice(explode($sub, $str), 1)); +} + +function urlLast($url) { + return end(explode('/', trim(parse_url($url, PHP_URL_PATH), '/'))); +} + +function parseAbsoluteUrl($str) { + $strlow = strtolower($str); + if (str_starts_with($strlow, 'http://') || str_starts_with($strlow, 'https://')) { + return implode('://', array_slice(explode('://', $str), 1)); + } +} + +function redirectTo($internalUrl) { + header('Location: ' . SCRIPT_NAME . $internalUrl); + die(); +} + +function fetchContent($url, $redirects=-1) { + $ch = curl_init(); + //$useragent = 'Mozilla/5.0 (X11; Linux x86_64; rv:129.0) Gecko/20100101 Firefox/129.0'; + //$useragent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0'; + $useragent = 'curl/' . curl_version()['version']; + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_MAXREDIRS, $redirects); + curl_setopt($ch, CURLOPT_USERAGENT, $useragent); + $body = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + curl_close($ch); + return [ + 'body' => $body, + 'code' => $code, + 'url' => curl_getinfo($ch, CURLINFO_REDIRECT_URL), + ]; +} + +function makeCanonicalUrl($item) { + if (!$item) { + return NULL; + } + return 'https://' . (PLATFORMS[$item['platform']][0] ?: $item['platform']) . '/' . $item['relativeurl']; +} + +function makeEmbedUrl($platform, $relativeUrl) { + $url = NULL; + if (isset(EMBEDS_PREFIXES_SIMPLE[$platform])) { + $url = EMBEDS_PREFIXES_SIMPLE[$platform] . urlLast($relativeUrl); + } else if (isset(EMBEDS_PREFIXES_PARAMS[$platform])) { + $url = EMBEDS_PREFIXES_PARAMS[$platform]; + foreach (PLATFORMS_PARAMS[$platform] as $key) { + parse_str(parse_url($relativeUrl, PHP_URL_QUERY), $params); + $url = str_replace("[$key]", $params[$key], $url); + } + } else if (isset(EMBEDS_PREFIXES_FULL[$platform])) { + $url = EMBEDS_PREFIXES_FULL[$platform] . urlencode($relativeUrl); + } else { + $url = (EMBEDS[$platform][0] ?: PLATFORMS[$platform][0] ?: PLATFORMS_PROXIES[$platform][0] ?: $platform) . '/' . trim($relativeUrl, '/') . (EMBEDS_SUFFIXES[$platform] ?? ''); + } + return "https://{$url}"; +// switch ($platform) { +// case 'tiktok': +// return 'https://www.tiktok.com/embed/v3/' . urlLast($relativeUrl); +// case 'twitter': +// return 'https://platform.twitter.com/embed/Tweet.html?id=' . urlLast($relativeUrl); +// default: +// return 'https://' . (EMBEDS[$platform][0] ?: PLATFORMS_PROXIES[$platform][0] ?: PLATFORMS[$platform][0] ?: '') . '/' . $relativeUrl . (EMBEDS_SUFFIXES[$platform] ?? ''); +// } +} + +function makeScrapeUrl($platform, $relativeUrl) { + return 'https://' . ((in_array($platform, PLATFORMS_HACKS) ? (PLATFORMS_PROXIES[$platform][0] ?: PLATFORMS[$platform][0]) : PLATFORMS[$platform][0]) ?: $platform) . '/' . $relativeUrl; +} + +function parseMetaTags($doc) { + $metaTags = []; + foreach ($doc->getElementsByTagName('meta') as $meta) { + if ($meta->hasAttribute('name') || $meta->hasAttribute('property')) { + $metaTags[$meta->getAttribute('name') ?: $meta->getAttribute('property')] = $meta->getAttribute('content'); + } + } + return $metaTags; +} + +function loadHistory() { + $history = []; + if (file_exists(HISTORY_FILE)) { + $lines = file(HISTORY_FILE, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + foreach ($lines as $line) { + $history[] = json_decode($line, true); + } + } + return $history; +} + +function saveHistory($entry) { + $history = loadHistory(); + $history = array_filter($history, function ($item) use ($entry) { + return $item['platform'] !== $entry['platform'] || $item['relativeurl'] !== $entry['relativeurl']; + }); + $history[] = $entry; + $lines = array_map(fn($item) => json_encode($item, JSON_UNESCAPED_SLASHES), $history); + file_put_contents(HISTORY_FILE, implode(PHP_EOL, $lines) . PHP_EOL, LOCK_EX); +} + +function searchHistory($keyword) { + $results = []; + $history = loadHistory(); + foreach ($history as $entry) { + if (stripos(json_encode($entry, JSON_UNESCAPED_SLASHES), $keyword) !== false) { + $results[] = $entry; + } + } + return $results; +} + +$path = $_SERVER['REQUEST_URI'];//parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); +$immediateResult = null; + +if (isset($_GET['proxatore-search']) && ($search = $_GET['proxatore-search']) !== '') { + //if (str_starts_with(strtolower($search), 'https://')) { + // redirectTo(lstrip($search, 'https://')); + if ($url = parseAbsoluteUrl($search)) { + redirectTo($url); + } else { + $searchResults = searchHistory($search); + } +} else { + $path = trim($path, '/'); + if ($url = parseAbsoluteUrl($path)) { + //$path = $url; + redirectTo($url); + } + + $segments = explode('/', $path); + if (SCRIPT_NAME !== '/') { + array_shift($segments); + } + + $platform = null; + $upstream = $segments[0] ?? null; + $relativeUrl = implode('/', array_slice($segments, 1)); + + if (($upstream === '__proxy__' || $upstream === '__media__') && $segments[1] === 'youtube') { + if ($video = preg_replace("/[^A-Za-z0-9-_]/", '', substr($relativeUrl, -11))) { + header("Location: " . shell_exec("yt-dlp -g '{$video}'")); + die(); + } + } + + if (isset(PLATFORMS[$upstream])) { + if (isset(PLATFORMS_ALIASES[$upstream])) { + redirectTo(PLATFORMS_ALIASES[$upstream] . '/' . $relativeUrl); + } + $platform = $upstream; + $domain = PLATFORMS[$upstream][0]; + } else { + foreach ([PLATFORMS_PROXIES, PLATFORMS, EMBEDS] as $array) { + foreach ($array as $platform => $domains) { + if (in_array($upstream, $domains) || in_array(lstrip($upstream, 'www.'), $domains)) { + redirectTo($platform . '/' . $relativeUrl); + } + } + unset($platform); + } + } + + if (!$platform && isset(PLATFORMS_REDIRECTS[$upstream])) { + // TODO: only strip query params for platforms that don't need them + $relativeUrl = trim(parse_url(fetchContent("$upstream/$relativeUrl", 1)['url'], PHP_URL_PATH), '/'); + $platform = PLATFORMS_REDIRECTS[$upstream]; + redirectTo($platform . '/' . $relativeUrl); + } else if (!$platform && (str_ends_with($upstream, '.wordpress.com') || str_ends_with($upstream, '.blogspot.com'))) { + $platform = $upstream; + } + + if ($relativeUrl && $platform && ($content = fetchContent(makeScrapeUrl($platform, $relativeUrl)))['body']) { + http_response_code($content['code']); + // if (!in_array($platform, PLATFORMS_TRACKING)) { + // $relativeUrl = parse_url($relativeUrl, PHP_URL_PATH); + // } + if (isset(PLATFORMS_PARAMS[$platform])) { + if (PLATFORMS_PARAMS[$platform] !== true) { + parse_str(parse_url($relativeUrl, PHP_URL_QUERY), $params); + $relativeUrl = parse_url($relativeUrl, PHP_URL_PATH) . '?'; + foreach ($params as $key => $value) { + if (in_array($key, PLATFORMS_PARAMS[$platform])) { + $relativeUrl .= "{$key}={$value}&"; + } + } + } + } else { + $relativeUrl = parse_url($relativeUrl, PHP_URL_PATH); + } + $doc = new DOMDocument(); + $doc->loadHTML($content['body']); + $metaTags = parseMetaTags($doc); + $immediateResult = [ + 'platform' => $platform, + 'relativeurl' => $relativeUrl, + //'datetime' => date('Y-m-d H:i:s'), + //'request_time' => time(), + 'locale' => $metaTags['og:locale'] ?? '', + 'type' => $metaTags['og:type'] ?? '', + 'image' => $metaTags['og:image'] ?? '', + 'video' => $metaTags['og:video'] ?: $metaTags['og:video:url'] ?: '', + 'videotype' => $metaTags['og:video:type'] ?? '', + 'title' => $metaTags['og:title'] ?: $metaTags['og:title'] ?: '', + //'author' => $metaTags['og:site_name'] ?? '', + 'description' => $metaTags['og:description'] ?: $metaTags['description'] ?: '', + 'images' => [], + ]; + //if ((in_array($platform, PLATFORMS_VIDEO) && !$immediateResult['video']) || !$immediateResult['image']) { + $html = fetchContent(makeEmbedUrl($platform, $relativeUrl))['body']; + if (!$immediateResult['video'] && ($vidpos = strpos($html, '.mp4'))) { + //$startpos = 0;//strpos(strrev(substr($html, 0, $vidpos)), '"'); + $endpos = strpos($html, '"', $vidpos); //strpos(substr($html, $vidpos), '"'); + $vidstr = substr($html, 0, $endpos); + //echo $vidstr; + $startpos = $endpos - strpos(strrev($vidstr), '"'); + $vidstr = substr($html, $startpos, $endpos-$startpos+1); + //echo '|' . $vidpos . '|' . $startpos . '|' . $endpos; //substr($html, $startpos, $endpos); + $vidstr = html_entity_decode($vidstr); + //$vidstr = json_decode('"' . json_decode('"' . ($vidstr) . '"') . ''); + $vidstr = json_decode('"' . json_decode('"' . $vidstr . '"')) ?: json_decode('"' . json_decode('"' . $vidstr) . '"'); + //$vidstr = json_decode('"' . $vidstr . '"'); + //echo $vidstr; + $immediateResult['video'] = $vidstr; + //echo '|'.$startpos.'|'.$endpos.'|'; + } + //if (!$immediateResult['image']) { + $doc->loadHTML($html); + foreach ($doc->getElementsByTagName('img') as $img) { + array_push($immediateResult['images'], $img->getAttribute('src')); + } + if (sizeof($immediateResult['images'])) { + //$immediateResult['image'] = $imgs[0]; + } + //} + //} + //if ($immediateResult['title'] || $immediateResult['description']) { + // saveHistory($immediateResult); + //} else + if ($content['code'] >= 400) { + $searchResults = searchHistory(json_encode([ + 'platform' => $platform, + 'relativeurl' => $relativeUrl, + ], JSON_UNESCAPED_SLASHES));//('"platform":"' . $platform . '","relativeurl":"' . $relativeUrl . '"'); + if (sizeof($searchResults)) { + $immediateResult = $searchResults[0]; + } + } else { + saveHistory($immediateResult); + } + $immediateResult['description'] = preg_replace('/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/', '$0', $immediateResult['description']); + $searchResults = [$immediateResult]; + } else { + http_response_code(404); + } +} +?> + + + + + +<?= APPNAME ?> + + + + + + + + + + + + + + + + + +
+

+ + Supported Platforms:

Source Code: Proxatore.php

'; + } ?> + + +
+

+ + +

+
+ + + + + + + +
+
+

+ + +

+

+

+ Original on / + Permalink +

+
+
+ + + + +
+ ⬅️ Previous + ➡️ Next +
+ + + +
+ +