Spaces:
Sleeping
Sleeping
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)
|