~nhanb/gae-proxy

ref: 8b32b9e23963d1c96198b8b299209c8eb307b75b gae-proxy/app.py -rw-r--r-- 2.2 KiB
8b32b9e2Bùi Thành Nhân fix response header popping 1 year, 2 months ago
                                                                                
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
"""
Dumb (bespoke "protocol" & grossly inefficient) http(s) proxy on Google Cloud Functions.
It also attempts to solve CloudFlare's javascript challenge where necessary.

To use, simply send request to proxy just as you would to the target, but provide some
extra http headers:

- X-Proxy-Key: For authentication.
- X-Proxy-Target-Host: So the proxy knows what hostname to proxy to.
- X-Proxy-Target-Scheme: Optional. Defaults to https.

To deploy:

    $ export GAEPROXY_KEY='my-secret-proxy-key'
    $ gcloud app deploy
"""
import os

import cloudscraper
from flask import Flask, Response, request

http = cloudscraper.create_scraper(
    browser={"browser": "firefox", "platform": "windows", "mobile": False}
)

PROXY_KEY = os.environ["GAEPROXY_KEY"]


app = Flask(__name__)


@app.route("/", defaults={"path": ""}, methods=["GET", "POST", "PUT", "DELETE"])
@app.route("/<path:path>", methods=["GET", "POST", "PUT", "DELETE"])
def hello_world(path):
    auth_key = request.headers.get("X-Proxy-Key")
    if auth_key != PROXY_KEY:
        return "Go away", 403

    target_headers = {
        key: val
        for key, val in dict(request.headers).items()
        if not (
            key.startswith("X-Appengine-")
            or key
            in (
                "Accept-Encoding",
                "Content-Length",
                "Transfer-Encoding",
                "X-Amzn-Trace-Id",
                "X-Cloud-Trace-Context",
                "X-Forwarded-For",
                "X-Forwarded-Proto",
            )
        )
    }
    target_headers.pop("X-Proxy-Key")
    target_headers.pop("Host")

    target_host = target_headers.pop("X-Proxy-Target-Host")
    target_scheme = target_headers.pop("X-Proxy-Target-Scheme", "https")
    target_path = "/".join(request.full_path.split("/")[1:])
    target_url = f"{target_scheme}://{target_host}/{target_path}"

    send = getattr(http, request.method.lower())
    target_resp = send(target_url, headers=target_headers)

    resp_headers = dict(target_resp.headers)
    resp_headers.pop("content-encoding", None)
    resp_headers.pop("transfer-encoding", None)

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