Spaces:
Sleeping
Sleeping
| from fastapi import FastAPI, Query | |
| from fastapi.responses import Response, HTMLResponse | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from camoufox.async_api import AsyncCamoufox | |
| import asyncio | |
| import random | |
| app = FastAPI() | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| async def home(): | |
| return """ | |
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <title>Enhanced CORS Proxy</title> | |
| <style> | |
| body { font-family: system-ui; max-width: 800px; margin: 50px auto; padding: 20px; background: #0f172a; color: #e2e8f0; } | |
| .container { background: #1e293b; padding: 30px; border-radius: 8px; } | |
| h1 { color: #38bdf8; margin-top: 0; } | |
| input { width: 100%; padding: 12px; margin: 10px 0; border: 1px solid #334155; border-radius: 4px; background: #0f172a; color: #e2e8f0; } | |
| button { background: #38bdf8; color: #0f172a; border: none; padding: 12px 24px; border-radius: 4px; cursor: pointer; font-weight: 600; } | |
| button:hover { background: #0ea5e9; } | |
| pre { background: #0f172a; padding: 15px; border-radius: 4px; overflow-x: auto; border: 1px solid #334155; max-height: 500px; } | |
| code { color: #38bdf8; } | |
| .warning { background: #422006; border: 1px solid #ea580c; padding: 15px; border-radius: 4px; margin: 15px 0; } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <h1>🦊 Enhanced CORS Proxy</h1> | |
| <div class="warning"> | |
| <strong>⚠️ Note:</strong> Some sites may still detect automation. This proxy includes: | |
| <ul> | |
| <li>Human-like mouse movements</li> | |
| <li>Random delays</li> | |
| <li>JavaScript execution waits</li> | |
| <li>Enhanced stealth techniques</li> | |
| </ul> | |
| </div> | |
| <h3>Usage: /proxy?url=YOUR_URL</h3> | |
| <input type="text" id="url" placeholder="https://example.com" value="https://jsonplaceholder.typicode.com/posts/1"> | |
| <button onclick="test()">Test Proxy</button> | |
| <pre id="result" style="display:none;"></pre> | |
| </div> | |
| <script> | |
| async function test() { | |
| const url = document.getElementById('url').value; | |
| const resultEl = document.getElementById('result'); | |
| if (!url) return; | |
| resultEl.style.display = 'block'; | |
| resultEl.textContent = 'Loading... (This may take 10-15 seconds)'; | |
| try { | |
| const response = await fetch('/proxy?url=' + encodeURIComponent(url)); | |
| const data = await response.text(); | |
| try { | |
| resultEl.textContent = JSON.stringify(JSON.parse(data), null, 2); | |
| } catch { | |
| resultEl.textContent = data.substring(0, 2000); | |
| } | |
| } catch (error) { | |
| resultEl.textContent = 'Error: ' + error.message; | |
| } | |
| } | |
| </script> | |
| </body> | |
| </html> | |
| """ | |
| async def human_like_behavior(page): | |
| """Simulate human-like behavior to evade detection""" | |
| # Random mouse movements | |
| viewport_size = page.viewport_size | |
| if viewport_size: | |
| width = viewport_size.get('width', 1920) | |
| height = viewport_size.get('height', 1080) | |
| else: | |
| width, height = 1920, 1080 | |
| for _ in range(random.randint(2, 4)): | |
| x = random.randint(100, width - 100) | |
| y = random.randint(100, height - 100) | |
| await page.mouse.move(x, y) | |
| await asyncio.sleep(random.uniform(0.1, 0.3)) | |
| # Random scroll | |
| await page.evaluate(f"window.scrollTo(0, {random.randint(100, 300)})") | |
| await asyncio.sleep(random.uniform(0.5, 1.0)) | |
| # Scroll back up | |
| await page.evaluate("window.scrollTo(0, 0)") | |
| await asyncio.sleep(random.uniform(0.3, 0.7)) | |
| async def proxy(url: str = Query(...)): | |
| try: | |
| # Enhanced Camoufox configuration | |
| async with AsyncCamoufox( | |
| headless=True, | |
| humanize=True, # Enable humanization features | |
| geoip=True, # Use realistic geolocation | |
| ) as browser: | |
| # Create context with additional options | |
| context = await browser.new_context( | |
| viewport={'width': 1920, 'height': 1080}, | |
| user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', | |
| locale='en-US', | |
| timezone_id='America/New_York', | |
| ) | |
| page = await context.new_page() | |
| # Set extra headers | |
| await page.set_extra_http_headers({ | |
| 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', | |
| 'Accept-Language': 'en-US,en;q=0.9', | |
| 'Accept-Encoding': 'gzip, deflate, br', | |
| 'DNT': '1', | |
| 'Connection': 'keep-alive', | |
| 'Upgrade-Insecure-Requests': '1', | |
| 'Sec-Fetch-Dest': 'document', | |
| 'Sec-Fetch-Mode': 'navigate', | |
| 'Sec-Fetch-Site': 'none', | |
| 'Sec-Fetch-User': '?1', | |
| 'Cache-Control': 'max-age=0', | |
| }) | |
| # Add stealth scripts | |
| await page.add_init_script(""" | |
| // Overwrite the `plugins` property to use a custom getter | |
| Object.defineProperty(navigator, 'webdriver', { | |
| get: () => undefined | |
| }); | |
| // Overwrite the `languages` property | |
| Object.defineProperty(navigator, 'languages', { | |
| get: () => ['en-US', 'en'] | |
| }); | |
| // Overwrite the `plugins` length | |
| Object.defineProperty(navigator.plugins, 'length', { | |
| get: () => 3 | |
| }); | |
| // Mock chrome object | |
| window.chrome = { | |
| runtime: {} | |
| }; | |
| // Mock permissions | |
| const originalQuery = window.navigator.permissions.query; | |
| window.navigator.permissions.query = (parameters) => ( | |
| parameters.name === 'notifications' ? | |
| Promise.resolve({ state: Notification.permission }) : | |
| originalQuery(parameters) | |
| ); | |
| """) | |
| # Navigate with realistic referrer | |
| await page.goto( | |
| url, | |
| wait_until='domcontentloaded', | |
| timeout=30000, | |
| referer='https://www.google.com/' | |
| ) | |
| # Wait for initial load | |
| await asyncio.sleep(random.uniform(2, 3)) | |
| # Simulate human-like behavior | |
| await human_like_behavior(page) | |
| # Wait for network to be idle | |
| await page.wait_for_load_state('networkidle', timeout=15000) | |
| # Additional wait for dynamic content | |
| await asyncio.sleep(random.uniform(1, 2)) | |
| # Get final content | |
| content = await page.content() | |
| await context.close() | |
| return Response(content=content, media_type='text/html') | |
| except Exception as e: | |
| return Response(content=f"Error: {str(e)}", status_code=500) | |
| async def health(): | |
| return {"status": "ok", "proxy": "camoufox-enhanced"} |