[Python] Support CONNECT flask server

Discussão em 'Python' iniciado por Stack, Março 25, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to build a basic proxy server thats accessible form the internet to forward requests but also log them to firebase database. I deployed my code on Google Cloud Run by creating an instance and then using ssh to add my python code and service file. I also setup a firewall rule to allow requests on port 5000 which is what I use to access the proxy.

    The proxy works fine for almost all requests except for CONNECT type. How can I modify my code below to work for CONNECT too? When a CONNECT is attempted I get [25/Mar/2025 01:40:07] "CONNECT api.ipify.org:443 HTTP/1.1" 405 -

    The proxy is an http proxy and I access it such as curl -x http://22.22.5.30:5200 http://httpbin.org/ip

    from flask import Flask, request, Response
    import requests
    import socket
    import firebase_admin
    from firebase_admin import credentials, firestore
    from datetime import datetime

    # === FIREBASE SETUP ===
    cred = credentials.Certificate("service.json")
    firebase_admin.initialize_app(cred)
    db = firestore.client()
    collection_name = "requests"

    # === FLASK SETUP ===
    app = Flask(__name__)
    LOCAL_IP = socket.gethostbyname(socket.gethostname())
    PORT = 5100

    def log_to_firestore(entry):
    try:
    db.collection(collection_name).add(entry)
    except Exception as e:
    print(f"Firestore Error: {e}")

    @app.route('/', defaults={'path': ''}, methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
    @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'])
    def proxy(path):
    if request.url.startswith('http'):
    target_url = request.url
    else:
    target_url = request.args.get('url')
    if not target_url:
    if path and '://' in path:
    target_url = path
    else:
    return "Missing target URL", 400

    try:
    request_data = request.get_data()
    headers = {k: v for k, v in request.headers.items() if k.lower() != 'host'}

    # Forward the request
    response = requests.request(
    method=request.method,
    url=target_url,
    headers=headers,
    data=request_data,
    cookies=request.cookies,
    allow_redirects=False
    )

    # Prepare Firestore log entry
    entry = {
    "timestamp": datetime.utcnow().isoformat(),
    "method": request.method,
    "target_url": target_url,
    "request": {
    "headers": dict(request.headers),
    "body": request_data.decode(errors='ignore'),
    },
    "response": {
    "status": response.status_code,
    "headers": dict(response.headers),
    "body": response.text[:1000] # Limit for Firestore size
    }
    }

    log_to_firestore(entry)

    return Response(response.content,
    status=response.status_code,
    headers=dict(response.headers))

    except Exception as e:
    error_entry = {
    "timestamp": datetime.utcnow().isoformat(),
    "method": request.method,
    "target_url": target_url,
    "error": str(e)
    }
    log_to_firestore(error_entry)
    return f"Error: {str(e)}", 500

    if __name__ == '__main__':
    print(f"Proxy Server running at: http://{LOCAL_IP}:{PORT}")
    app.run(host='0.0.0.0', port=PORT, debug=True)

    Continue reading...

Compartilhe esta Página