| | from flask import Flask, request, jsonify |
| | import base64 |
| | import re |
| | from urllib.parse import unquote |
| |
|
| | app = Flask(__name__) |
| |
|
| | |
| | HARDCODED_IPS = [ |
| | |
| | "108.181.32.57", |
| | |
| | "108.181.32.71", |
| | |
| | "185.16.39.166", |
| | |
| | |
| | "108.181.32.67", |
| | "108.181.34.42", |
| | "108.181.34.69", |
| | |
| | "108.181.32.61", |
| | "108.181.32.64", |
| | "108.181.32.65", |
| | "185.16.39.164", |
| | |
| | |
| |
|
| | "108.181.33.119", |
| | "108.181.34.151", |
| | "108.181.34.157", |
| | "108.181.90.163", |
| | "108.181.34.177", |
| | "208.87.241.1", |
| | "208.87.241.149", |
| | "208.87.242.125", |
| | "208.87.242.233", |
| | "108.181.11.171", |
| | "108.181.6.9", |
| | "108.181.33.135", |
| | "108.181.9.39", |
| | "108.181.11.193", |
| | "108.181.21.229", |
| | "108.181.5.31", |
| | "108.181.3.54", |
| | "108.181.5.51", |
| | "108.181.11.173", |
| | |
| | |
| |
|
| | |
| | |
| | ] |
| |
|
| | def swap_ip_in_url_working(template_url, new_ip): |
| | """ |
| | Working version that uses standard base64 with padding for r parameter |
| | """ |
| | if not template_url or not new_ip: |
| | return None |
| | |
| | try: |
| | |
| | old_ip_match = re.search(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', template_url) |
| | if not old_ip_match: |
| | return None |
| | |
| | old_ip = old_ip_match.group(0) |
| | |
| | |
| | new_url = template_url.replace(old_ip, new_ip) |
| | |
| | |
| | r_match = re.search(r'[&?]r=([^&]+)', new_url) |
| | if r_match: |
| | original_r = r_match.group(1) |
| | |
| | |
| | url_decoded_r = unquote(original_r) |
| | |
| | |
| | padding = 4 - len(url_decoded_r) % 4 |
| | if padding != 4: |
| | url_decoded_r += '=' * padding |
| | |
| | |
| | base64_fixed = url_decoded_r.replace('_', '/').replace('-', '+') |
| | decoded_r = base64.b64decode(base64_fixed).decode('utf-8') |
| | |
| | |
| | new_decoded_r = decoded_r.replace(old_ip, new_ip) |
| | |
| | |
| | new_encoded_r = base64.b64encode(new_decoded_r.encode()).decode() |
| | |
| | |
| | new_url = new_url.replace(f"r={original_r}", f"r={new_encoded_r}") |
| | |
| | return new_url |
| | |
| | except Exception as e: |
| | print(f"Error processing URL for IP {new_ip}: {str(e)}") |
| | return None |
| |
|
| | @app.route('/') |
| | def home(): |
| | return """ |
| | <h1>IP Swapper API</h1> |
| | <p>Use POST /generate with JSON payload containing 'template_url'</p> |
| | <p>Example:</p> |
| | <pre> |
| | curl -X POST https://your-app.hf.space/generate \\ |
| | -H "Content-Type: application/json" \\ |
| | -d '{"template_url": "https://108.181.8.179/__cpi.php?s=...&r=...&__cpo=1"}' |
| | </pre> |
| | """ |
| |
|
| | @app.route('/generate', methods=['POST']) |
| | def generate_urls(): |
| | """ |
| | Generate URLs for all IPs in the hardcoded list |
| | """ |
| | data = request.get_json() |
| | |
| | if not data or 'template_url' not in data: |
| | return jsonify({"error": "template_url is required"}), 400 |
| | |
| | template_url = data['template_url'].strip() |
| | |
| | |
| | ip_list = data.get('ip_list', HARDCODED_IPS) |
| | |
| | |
| | results = [] |
| | for ip in ip_list: |
| | new_url = swap_ip_in_url_working(template_url, ip) |
| | if new_url: |
| | results.append(new_url) |
| | |
| | return jsonify({ |
| | "generated_urls": results, |
| | "count": len(results), |
| | "method": "standard_base64_with_padding" |
| | }) |
| |
|
| | @app.route('/generate_single', methods=['POST']) |
| | def generate_single(): |
| | """ |
| | Generate URL for a specific IP |
| | """ |
| | data = request.get_json() |
| | |
| | if not data or 'template_url' not in data or 'ip' not in data: |
| | return jsonify({"error": "template_url and ip are required"}), 400 |
| | |
| | template_url = data['template_url'].strip() |
| | ip = data['ip'].strip() |
| | |
| | new_url = swap_ip_in_url_working(template_url, ip) |
| | |
| | if new_url: |
| | return jsonify({ |
| | "original_url": template_url, |
| | "generated_url": new_url, |
| | "ip": ip, |
| | "success": True |
| | }) |
| | else: |
| | return jsonify({ |
| | "error": "Failed to generate URL", |
| | "ip": ip, |
| | "success": False |
| | }), 400 |
| |
|
| | @app.route('/test_r_param', methods=['POST']) |
| | def test_r_param(): |
| | """ |
| | Test if the r parameter decodes correctly for a generated URL |
| | """ |
| | data = request.get_json() |
| | |
| | if not data or 'url' not in data: |
| | return jsonify({"error": "url is required"}), 400 |
| | |
| | url = data['url'].strip() |
| | |
| | |
| | r_match = re.search(r'[&?]r=([^&]+)', url) |
| | |
| | if not r_match: |
| | return jsonify({"error": "No r parameter found in URL"}), 400 |
| | |
| | r_value = r_match.group(1) |
| | |
| | try: |
| | |
| | decoded = base64.b64decode(r_value).decode('utf-8') |
| | |
| | return jsonify({ |
| | "r_parameter": r_value, |
| | "decoded_successfully": True, |
| | "decoded_value": decoded, |
| | "contains_corruption": "\\" in decoded or "%" in decoded |
| | }) |
| | except Exception as e: |
| | return jsonify({ |
| | "r_parameter": r_value, |
| | "decoded_successfully": False, |
| | "error": str(e) |
| | }) |
| |
|
| | @app.route('/health', methods=['GET']) |
| | def health(): |
| | return jsonify({ |
| | "status": "healthy", |
| | "ip_count": len(HARDCODED_IPS), |
| | "method": "standard_base64_with_padding" |
| | }) |
| |
|
| | @app.route('/ips', methods=['GET']) |
| | def list_ips(): |
| | """ |
| | List all available IPs |
| | """ |
| | return jsonify({ |
| | "ip_count": len(HARDCODED_IPS), |
| | "ips": HARDCODED_IPS |
| | }) |
| |
|
| | if __name__ == '__main__': |
| | app.run(host='0.0.0.0', port=7860, debug=True) |