UNPKG

ignitetnt

Version:

IGNITE OS — Advanced proxy-enabled gaming platform with comprehensive filter bypass system

221 lines (202 loc) • 7.08 kB
// Netlify serverless proxy function // Handles CORS and URL rewriting to bypass network filters exports.handler = async (event, context) => { // Handle preflight requests if (event.httpMethod === 'OPTIONS') { return { statusCode: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': '*' }, body: '' }; } try { const { target, url } = event.queryStringParameters || {}; let targetUrl; // Decode target URL if (target) { // Base64 decode with URL-safe characters let decoded = target; while (decoded.length % 4) { decoded += '='; } targetUrl = Buffer.from(decoded.replace(/-/g, '+').replace(/_/g, '/'), 'base64').toString(); } else if (url) { targetUrl = decodeURIComponent(url); } else { return { statusCode: 400, headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' }, body: JSON.stringify({ error: 'Missing target URL' }) }; } // Validate URL if (!targetUrl.startsWith('http')) { return { statusCode: 400, headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' }, body: JSON.stringify({ error: 'Invalid URL protocol' }) }; } // Create fetch options const fetchOptions = { method: event.httpMethod, headers: { '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', 'Accept': event.headers.accept || '*/*', 'Accept-Language': 'en-US,en;q=0.9', 'Accept-Encoding': 'gzip, deflate, br', 'Cache-Control': 'no-cache', 'Pragma': 'no-cache', 'Sec-Fetch-Dest': 'empty', 'Sec-Fetch-Mode': 'cors', 'Sec-Fetch-Site': 'cross-site', 'Referer': 'https://www.google.com/', 'Origin': 'https://www.google.com' } }; // Add body for non-GET requests if (event.httpMethod !== 'GET' && event.httpMethod !== 'HEAD' && event.body) { fetchOptions.body = event.body; fetchOptions.headers['Content-Type'] = event.headers['content-type'] || 'application/json'; } // Make the request with timeout const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout fetchOptions.signal = controller.signal; const response = await fetch(targetUrl, fetchOptions); clearTimeout(timeoutId); if (!response.ok) { return { statusCode: response.status, headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' }, body: JSON.stringify({ error: `Target server returned ${response.status}`, status: response.status, statusText: response.statusText }) }; } // Get content type const contentType = response.headers.get('content-type') || 'application/octet-stream'; // Response headers const responseHeaders = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 'Access-Control-Allow-Headers': '*', 'Content-Type': contentType, 'Cache-Control': 'public, max-age=300', 'X-Frame-Options': 'ALLOWALL' }; // Handle different content types if (contentType.includes('application/json')) { const data = await response.json(); return { statusCode: 200, headers: responseHeaders, body: JSON.stringify(data) }; } else if (contentType.includes('text/')) { const text = await response.text(); // Modify HTML to inject proxy configurations if (contentType.includes('text/html')) { const modifiedHtml = injectProxyScript(text, targetUrl); return { statusCode: 200, headers: responseHeaders, body: modifiedHtml }; } return { statusCode: 200, headers: responseHeaders, body: text }; } else { // Binary content - encode as base64 const buffer = await response.arrayBuffer(); return { statusCode: 200, headers: { ...responseHeaders, 'Content-Encoding': 'base64' }, body: Buffer.from(buffer).toString('base64'), isBase64Encoded: true }; } } catch (error) { console.error('Proxy error:', error); return { statusCode: 500, headers: { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' }, body: JSON.stringify({ error: 'Proxy request failed', details: error.message }) }; } }; // Inject proxy configuration into HTML responses function injectProxyScript(html, baseUrl) { const proxyScript = ` <script> // Override fetch to use proxy const originalFetch = window.fetch; window.fetch = function(url, options = {}) { if (typeof url === 'string' && !url.startsWith('data:') && !url.startsWith('blob:')) { const absoluteUrl = new URL(url, '${baseUrl}').href; const proxyUrl = '/.netlify/functions/proxy?url=' + encodeURIComponent(absoluteUrl); return originalFetch(proxyUrl, options); } return originalFetch(url, options); }; // Override XMLHttpRequest const OriginalXHR = window.XMLHttpRequest; window.XMLHttpRequest = function() { const xhr = new OriginalXHR(); const originalOpen = xhr.open; xhr.open = function(method, url, ...args) { if (typeof url === 'string' && !url.startsWith('data:') && !url.startsWith('blob:')) { const absoluteUrl = new URL(url, '${baseUrl}').href; const proxyUrl = '/.netlify/functions/proxy?url=' + encodeURIComponent(absoluteUrl); return originalOpen.call(this, method, proxyUrl, ...args); } return originalOpen.call(this, method, url, ...args); }; return xhr; }; // Override window.open const originalOpen = window.open; window.open = function(url, ...args) { if (typeof url === 'string' && !url.startsWith('data:') && !url.startsWith('blob:')) { const absoluteUrl = new URL(url, '${baseUrl}').href; const proxyUrl = '/.netlify/functions/proxy?url=' + encodeURIComponent(absoluteUrl); return originalOpen(proxyUrl, ...args); } return originalOpen(url, ...args); }; </script> `; // Inject before closing head tag, or at the beginning if no head if (html.includes('</head>')) { return html.replace('</head>', proxyScript + '</head>'); } else { return proxyScript + html; } }