File size: 4,433 Bytes
c579494
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
import json
import time
import requests
import urllib3
import base64
from flask import Flask, render_template, request, jsonify

# Suppress InsecureRequestWarning for verify=False
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

app = Flask(__name__)
app.secret_key = os.urandom(24)
app.config['MAX_CONTENT_LENGTH'] = 32 * 1024 * 1024  # 32MB limit

# Standard Jinja2 delimiters are used. 
# Vue.js will be configured to use ['${', '}'] to avoid conflict.

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/api/proxy', methods=['POST'])
def proxy_request():
    try:
        data = request.json
        if not data:
            return jsonify({'error': 'No data provided'}), 400

        method = data.get('method', 'GET').upper()
        url = data.get('url')
        headers = data.get('headers', {})
        body = data.get('body', None)
        params = data.get('params', {})
        
        if not url:
            return jsonify({'error': 'URL is required'}), 400
            
        # Ensure headers is a dict
        if not isinstance(headers, dict):
            headers = {}

        start_time = time.time()
        
        # Prepare arguments
        kwargs = {
            'method': method,
            'url': url,
            'headers': headers,
            'params': params,
            'timeout': 60, # Increased timeout
            'verify': False, # Allow testing local/self-signed endpoints
            'allow_redirects': True
        }

        # Handle Body
        if body:
            content_type = ''
            # Case insensitive search for Content-Type
            for k, v in headers.items():
                if k.lower() == 'content-type':
                    content_type = v.lower()
                    break
            
            if 'application/json' in content_type:
                 if isinstance(body, str):
                     try:
                         # Try to parse to ensure it's valid JSON if we want to send as json kwarg
                         json_body = json.loads(body)
                         kwargs['json'] = json_body
                     except:
                         # Send as raw string if it fails to parse
                         kwargs['data'] = body
                 else:
                     kwargs['json'] = body
            else:
                # x-www-form-urlencoded or plain text
                kwargs['data'] = body.encode('utf-8') if isinstance(body, str) else body

        resp = requests.request(**kwargs)
        
        duration = (time.time() - start_time) * 1000 # ms
        
        # Format response headers
        resp_headers = dict(resp.headers)
        resp_content_type = resp_headers.get('Content-Type', '').lower()
        
        # Determine how to return data
        is_binary = False
        is_json = False
        resp_data = None

        # Check for binary content types (images, pdfs, audio, etc.)
        binary_types = ['image/', 'audio/', 'video/', 'application/pdf', 'application/octet-stream', 'application/zip']
        if any(bt in resp_content_type for bt in binary_types):
            is_binary = True
            resp_data = base64.b64encode(resp.content).decode('utf-8')
        else:
            # Try to parse response body as JSON
            try:
                resp_data = resp.json()
                is_json = True
            except:
                # Fallback to text
                resp_data = resp.text
            
        return jsonify({
            'status': resp.status_code,
            'status_text': resp.reason,
            'headers': resp_headers,
            'data': resp_data,
            'is_json': is_json,
            'is_binary': is_binary,
            'content_type': resp_headers.get('Content-Type', ''),
            'duration': round(duration, 2),
            'size': len(resp.content)
        })

    except requests.exceptions.RequestException as e:
        return jsonify({
            'error': str(e),
            'duration': round((time.time() - (start_time if 'start_time' in locals() else time.time())) * 1000, 2)
        }), 500
    except Exception as e:
        return jsonify({
            'error': f"Internal Server Error: {str(e)}",
            'duration': 0
        }), 500

if __name__ == '__main__':
    port = int(os.environ.get('PORT', 7860))
    app.run(host='0.0.0.0', port=port, debug=True)