File size: 8,016 Bytes
32c9c25
4390011
 
32c9c25
 
45fa01a
4390011
f88c9f2
4390011
45fa01a
32c9c25
4390011
 
 
b4436ad
4390011
32c9c25
 
 
 
 
4390011
 
 
 
32c9c25
b4436ad
f88c9f2
4390011
2143c8e
4390011
32c9c25
 
 
 
 
b4436ad
32c9c25
 
 
4390011
 
32c9c25
 
 
 
4496a6a
b4436ad
32c9c25
4390011
f88c9f2
32c9c25
 
 
 
f88c9f2
 
32c9c25
 
f88c9f2
32c9c25
 
 
 
 
 
 
f88c9f2
32c9c25
 
f88c9f2
32c9c25
 
b4436ad
32c9c25
 
f88c9f2
32c9c25
 
f88c9f2
 
32c9c25
f88c9f2
32c9c25
 
 
 
f88c9f2
32c9c25
 
 
f88c9f2
32c9c25
f88c9f2
32c9c25
 
f88c9f2
32c9c25
 
f88c9f2
32c9c25
f88c9f2
32c9c25
f88c9f2
32c9c25
 
 
 
f88c9f2
 
32c9c25
 
 
f88c9f2
32c9c25
f88c9f2
32c9c25
 
f88c9f2
32c9c25
f88c9f2
32c9c25
 
 
 
 
 
f88c9f2
32c9c25
 
b4436ad
32c9c25
f88c9f2
 
32c9c25
f88c9f2
 
32c9c25
f88c9f2
 
32c9c25
f88c9f2
 
32c9c25
f88c9f2
32c9c25
4496a6a
 
f88c9f2
32c9c25
 
b4436ad
32c9c25
 
 
f88c9f2
32c9c25
4496a6a
32c9c25
 
4496a6a
32c9c25
4496a6a
f88c9f2
32c9c25
4496a6a
32c9c25
 
4496a6a
32c9c25
4496a6a
f88c9f2
32c9c25
 
f88c9f2
b4436ad
32c9c25
 
4496a6a
32c9c25
4496a6a
 
32c9c25
f88c9f2
32c9c25
 
4496a6a
32c9c25
4496a6a
 
f88c9f2
4496a6a
 
32c9c25
f88c9f2
b4436ad
32c9c25
4390011
 
32c9c25
f88c9f2
32c9c25
 
45fa01a
4390011
f88c9f2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
from flask import Flask, request, Response
import requests
import re
import urllib.parse
import logging

logging.basicConfig(level=logging.INFO)

app = Flask(__name__)

HOME_PAGE = """
<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
    <style>
        body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }
        .container { max-width: 600px; margin: 0 auto; }
        input[type="text"] { width: 70%; padding: 10px; margin: 10px 0; }
        button { padding: 10px 20px; background: #4285f4; color: white; border: none; cursor: pointer; }
        .note { margin-top: 20px; color: #666; font-size: 0.9em; }
    </style>
</head>
<body>
    <div class="container">
        <form id="proxyForm">
            <input type="text" id="urlInput" placeholder="Enter URL" required>
            <button type="submit">Access</button>
        </form>
        <div><span><a href="https://lpx55-flask.hf.space" target="_blank">Frameless Space.</a></span></div>
    </div>
    <script>
        document.getElementById('proxyForm').addEventListener('submit', function(e) {
            e.preventDefault();
            const url = document.getElementById('urlInput').value;
            if(url) {
                window.location.href = '/go/' + encodeURIComponent(btoa(url));
            }
        });
    </script>
</body>
</html>
"""
@app.route('/')
def index():
    return HOME_PAGE

@app.route('/go/<path:encoded_url>')
def proxy_path(encoded_url):
    try:
        # Base64 decode the URL
        url = urllib.parse.unquote(encoded_url)
        url = str(base64_decode(url))
        return proxy_request(url)
    except Exception as e:
        logging.error(f"Proxy path error: {e}")
        return f"Proxy error: {str(e)}", 500

def base64_decode(encoded):
    # Add padding to ensure correct decoding
    padding = 4 - (len(encoded) % 4)
    if padding < 4:
        encoded += "=" * padding
    try:
        return bytes.decode(base64.b64decode(encoded))
    except:
        try:
            # Try URL-safe Base64 decoding
            return bytes.decode(base64.urlsafe_b64decode(encoded))
        except:
            # If decoding fails, return the original value
            return encoded

            
def proxy_request(url):
    try:
        # If the URL is not a complete HTTP URL, add the protocol
        if not url.startswith('http'):
            url = 'https://' + url
        logging.info(f"Proxying request: {url}")
        # Create a session to maintain cookies and state
        session = requests.Session()
        # Build request headers
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Language': 'en-US,en;q=0.5',
            'Accept-Encoding': 'identity',  # Disable compression
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1',
        }
        # Send the request
        resp = session.get(url, headers=headers, stream=True, verify=False, timeout=30)
        # Get the response content
        content = resp.content
        content_type = resp.headers.get('Content-Type', 'text/html')
        # If it's HTML content, modify all links
        if 'text/html' in content_type:
            content = rewrite_links(content, url)
        # Create the response object
        response = Response(content)
        # Copy the original response headers
        for key, value in resp.headers.items():
            if key.lower() not in ['content-encoding', 'content-length', 'transfer-encoding',
                                  'connection', 'content-security-policy']:
                response.headers[key] = value
        return response
    except Exception as e:
        logging.error(f"Proxy request failed: {e}")
        return f"Failed to access {url}: {str(e)}", 500

def rewrite_links(content, base_url):
    try:
        # Decode the content
        content_str = content.decode('utf-8', errors='replace')
        # Parse the base URL information
        parsed_base = urllib.parse.urlparse(base_url)
        base_domain = f"{parsed_base.scheme}://{parsed_base.netloc}"
        # Replace all links
        def encode_url(url):
            # Convert relative URL to absolute URL
            if url.startswith('/'):
                absolute_url = base_domain + url
            elif not url.startswith('http') and not url.startswith('data:') and not url.startswith('#'):
                absolute_url = urllib.parse.urljoin(base_url, url)
            else:
                absolute_url = url
            # Encode the URL as Base64 and add the proxy prefix
            if absolute_url.startswith('http'):
                encoded = base64.b64encode(absolute_url.encode()).decode()
                return f"/go/{urllib.parse.quote(encoded)}"
            return url
        # 1. Replace href attributes
        content_str = re.sub(r'href=["\'](.*?)["\']',
                           lambda m: f'href="{encode_url(m.group(1))}"', content_str)
        # 2. Replace src attributes
        content_str = re.sub(r'src=["\'](.*?)["\']',
                           lambda m: f'src="{encode_url(m.group(1))}"', content_str)
        # 3. Replace action attributes (forms)
        content_str = re.sub(r'action=["\'](.*?)["\']',
                           lambda m: f'action="{encode_url(m.group(1))}"', content_str)
        # 4. Replace URLs in CSS
        content_str = re.sub(r'url\([\'"]?(.*?)[\'"]?\)',
                           lambda m: f'url({encode_url(m.group(1))})', content_str)
        # 5. Inject JavaScript handling script
        script = """
        <script>
        (function() {
            // Create Base64 encoding function
            function encodeURL(url) {
                if(url && url.startsWith('http')) {
                    return '/go/' + encodeURIComponent(btoa(url));
                }
                return url;
            }
            // Rewrite XHR
            const originalOpen = XMLHttpRequest.prototype.open;
            XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
                if(url && url.startsWith('http')) {
                    arguments[1] = encodeURL(url);
                }
                return originalOpen.apply(this, arguments);
            };
            // Rewrite Fetch
            const originalFetch = window.fetch;
            window.fetch = function(resource, init) {
                if(typeof resource === 'string' && resource.startsWith('http')) {
                    arguments[0] = encodeURL(resource);
                }
                return originalFetch.apply(this, arguments);
            };
            // Listen for all clicks, handle links
            document.addEventListener('click', function(e) {
                const target = e.target.closest('a');
                if(target && target.href && target.href.startsWith('http') &&
                   !target.href.includes('/go/')) {
                    e.preventDefault();
                    location.href = encodeURL(target.href);
                }
            }, true);
        })();
        </script>
        """
        # Insert the script before the body end tag
        if '</body>' in content_str:
            content_str = content_str.replace('</body>', script + '</body>')
        else:
            content_str += script
        return content_str.encode('utf-8', errors='replace')
    except Exception as e:
        logging.error(f"Link rewriting error: {e}")
        return content

import base64

@app.route('/go', methods=['GET'])
def proxy_get():
    url = request.args.get('url', '')
    if not url:
        return HOME_PAGE
    # Base64 encode the URL and redirect
    encoded_url = base64.b64encode(url.encode()).decode()
    return proxy_request(url)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=7860, debug=True)