Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -170,6 +170,20 @@ FORWARD_HEADERS = {
|
|
| 170 |
"Authorization",
|
| 171 |
}
|
| 172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 173 |
@app.route("/cors-proxy", methods=["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"], strict_slashes=False)
|
| 174 |
def cors_proxy():
|
| 175 |
# Preflight 対応
|
|
@@ -183,16 +197,33 @@ def cors_proxy():
|
|
| 183 |
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
|
| 184 |
},
|
| 185 |
)
|
|
|
|
| 186 |
# cookie パラメータ取得
|
| 187 |
cookie_param = request.args.get("cookie")
|
| 188 |
-
|
| 189 |
-
|
|
|
|
|
|
|
|
|
|
| 190 |
if cookie_param:
|
| 191 |
-
cookies = {}
|
| 192 |
for item in cookie_param.split(";"):
|
| 193 |
if "=" in item:
|
| 194 |
k, v = item.split("=", 1)
|
| 195 |
cookies[k.strip()] = v.strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 196 |
url = request.args.get("url")
|
| 197 |
if not url:
|
| 198 |
return "url パラメータが必要です", 400
|
|
@@ -200,13 +231,12 @@ def cors_proxy():
|
|
| 200 |
if not url.startswith(("http://", "https://")):
|
| 201 |
return "http または https のURLのみ使用できます", 400
|
| 202 |
|
| 203 |
-
# 追加転送ヘッダ取得
|
| 204 |
extra_headers = set()
|
| 205 |
send_param = request.args.get("send")
|
| 206 |
if send_param:
|
| 207 |
extra_headers = {h.strip() for h in send_param.split(",") if h.strip()}
|
| 208 |
|
| 209 |
-
# 転送対象ヘッダを動的に構築(小文字比較で安全に)
|
| 210 |
allowed_headers = {h.lower() for h in FORWARD_HEADERS}
|
| 211 |
allowed_headers.update(h.lower() for h in extra_headers)
|
| 212 |
|
|
@@ -215,58 +245,70 @@ def cors_proxy():
|
|
| 215 |
if k.lower() in allowed_headers
|
| 216 |
}
|
| 217 |
|
| 218 |
-
# gzip 問題回避
|
| 219 |
headers.pop("Accept-Encoding", None)
|
| 220 |
|
| 221 |
-
# url パラメータと send パラメータは転送しない
|
| 222 |
forward_params = request.args.to_dict(flat=True)
|
| 223 |
forward_params.pop("url", None)
|
| 224 |
forward_params.pop("send", None)
|
| 225 |
forward_params.pop("cookie", None)
|
|
|
|
|
|
|
| 226 |
resp = requests.request(
|
| 227 |
method=request.method,
|
| 228 |
url=url,
|
| 229 |
headers=headers,
|
| 230 |
data=request.get_data(),
|
| 231 |
params=forward_params,
|
| 232 |
-
cookies=cookies,
|
| 233 |
timeout=300,
|
| 234 |
)
|
| 235 |
|
| 236 |
response = Response(resp.content, resp.status_code)
|
| 237 |
|
| 238 |
-
# CORS ヘッダ付与
|
| 239 |
response.headers["Access-Control-Allow-Origin"] = "*"
|
| 240 |
response.headers["Access-Control-Allow-Headers"] = "*"
|
| 241 |
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PATCH, PUT, DELETE, OPTIONS"
|
| 242 |
|
| 243 |
-
# Content-Type は元のまま
|
| 244 |
if "Content-Type" in resp.headers:
|
| 245 |
response.headers["Content-Type"] = resp.headers["Content-Type"]
|
| 246 |
|
| 247 |
return response
|
| 248 |
|
|
|
|
| 249 |
@app.errorhandler(404)
|
| 250 |
def cors_proxy_404(e):
|
| 251 |
baseurl = request.args.get("baseurl23896")
|
| 252 |
if not baseurl:
|
| 253 |
return abort(404)
|
| 254 |
|
| 255 |
-
# baseurl23896 以外のパラメータをそのまま渡す
|
| 256 |
forward_params = {
|
| 257 |
k: v for k, v in request.args.items()
|
| 258 |
if k != "baseurl23896"
|
| 259 |
}
|
|
|
|
| 260 |
cookie_param = request.args.get("cookie")
|
| 261 |
-
|
| 262 |
-
|
|
|
|
|
|
|
| 263 |
if cookie_param:
|
| 264 |
-
cookies = {}
|
| 265 |
for item in cookie_param.split(";"):
|
| 266 |
if "=" in item:
|
| 267 |
k, v = item.split("=", 1)
|
| 268 |
cookies[k.strip()] = v.strip()
|
| 269 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
target_url = baseurl.rstrip("/") + request.path
|
| 271 |
if forward_params:
|
| 272 |
target_url += "?" + urlencode(forward_params, doseq=True)
|
|
@@ -280,7 +322,7 @@ def cors_proxy_404(e):
|
|
| 280 |
if k.lower() not in ["host", "content-length"]
|
| 281 |
},
|
| 282 |
data=request.get_data(),
|
| 283 |
-
cookies=cookies,
|
| 284 |
allow_redirects=False,
|
| 285 |
timeout=10,
|
| 286 |
)
|
|
@@ -293,6 +335,7 @@ def cors_proxy_404(e):
|
|
| 293 |
"transfer-encoding",
|
| 294 |
"connection",
|
| 295 |
]
|
|
|
|
| 296 |
headers = [
|
| 297 |
(k, v) for k, v in resp.headers.items()
|
| 298 |
if k.lower() not in excluded_headers
|
|
@@ -300,6 +343,7 @@ def cors_proxy_404(e):
|
|
| 300 |
|
| 301 |
return Response(resp.content, resp.status_code, headers)
|
| 302 |
|
|
|
|
| 303 |
#------------------
|
| 304 |
|
| 305 |
|
|
|
|
| 170 |
"Authorization",
|
| 171 |
}
|
| 172 |
|
| 173 |
+
def parse_cookie_txt(text):
|
| 174 |
+
cookies = {}
|
| 175 |
+
for line in text.splitlines():
|
| 176 |
+
line = line.strip()
|
| 177 |
+
if not line or line.startswith("#"):
|
| 178 |
+
continue
|
| 179 |
+
parts = line.split("\t")
|
| 180 |
+
if len(parts) >= 7:
|
| 181 |
+
name = parts[5]
|
| 182 |
+
value = parts[6]
|
| 183 |
+
cookies[name] = value
|
| 184 |
+
return cookies
|
| 185 |
+
|
| 186 |
+
|
| 187 |
@app.route("/cors-proxy", methods=["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"], strict_slashes=False)
|
| 188 |
def cors_proxy():
|
| 189 |
# Preflight 対応
|
|
|
|
| 197 |
"Access-Control-Allow-Methods": "GET, POST, PATCH, PUT, DELETE, OPTIONS",
|
| 198 |
},
|
| 199 |
)
|
| 200 |
+
|
| 201 |
# cookie パラメータ取得
|
| 202 |
cookie_param = request.args.get("cookie")
|
| 203 |
+
cookie_txt_url = request.args.get("cookie_txt_url")
|
| 204 |
+
|
| 205 |
+
cookies = {}
|
| 206 |
+
|
| 207 |
+
# cookie= から
|
| 208 |
if cookie_param:
|
|
|
|
| 209 |
for item in cookie_param.split(";"):
|
| 210 |
if "=" in item:
|
| 211 |
k, v = item.split("=", 1)
|
| 212 |
cookies[k.strip()] = v.strip()
|
| 213 |
+
|
| 214 |
+
# cookie_txt_url から
|
| 215 |
+
if cookie_txt_url:
|
| 216 |
+
try:
|
| 217 |
+
txt_resp = requests.get(cookie_txt_url, timeout=10)
|
| 218 |
+
txt_resp.raise_for_status()
|
| 219 |
+
txt_cookies = parse_cookie_txt(txt_resp.text)
|
| 220 |
+
cookies.update(txt_cookies)
|
| 221 |
+
except requests.RequestException:
|
| 222 |
+
return "cookie_txt_url の取得に失敗しました", 400
|
| 223 |
+
|
| 224 |
+
if not cookies:
|
| 225 |
+
cookies = None
|
| 226 |
+
|
| 227 |
url = request.args.get("url")
|
| 228 |
if not url:
|
| 229 |
return "url パラメータが必要です", 400
|
|
|
|
| 231 |
if not url.startswith(("http://", "https://")):
|
| 232 |
return "http または https のURLのみ使用できます", 400
|
| 233 |
|
| 234 |
+
# 追加転送ヘッダ取得
|
| 235 |
extra_headers = set()
|
| 236 |
send_param = request.args.get("send")
|
| 237 |
if send_param:
|
| 238 |
extra_headers = {h.strip() for h in send_param.split(",") if h.strip()}
|
| 239 |
|
|
|
|
| 240 |
allowed_headers = {h.lower() for h in FORWARD_HEADERS}
|
| 241 |
allowed_headers.update(h.lower() for h in extra_headers)
|
| 242 |
|
|
|
|
| 245 |
if k.lower() in allowed_headers
|
| 246 |
}
|
| 247 |
|
|
|
|
| 248 |
headers.pop("Accept-Encoding", None)
|
| 249 |
|
|
|
|
| 250 |
forward_params = request.args.to_dict(flat=True)
|
| 251 |
forward_params.pop("url", None)
|
| 252 |
forward_params.pop("send", None)
|
| 253 |
forward_params.pop("cookie", None)
|
| 254 |
+
forward_params.pop("cookie_txt_url", None)
|
| 255 |
+
|
| 256 |
resp = requests.request(
|
| 257 |
method=request.method,
|
| 258 |
url=url,
|
| 259 |
headers=headers,
|
| 260 |
data=request.get_data(),
|
| 261 |
params=forward_params,
|
| 262 |
+
cookies=cookies,
|
| 263 |
timeout=300,
|
| 264 |
)
|
| 265 |
|
| 266 |
response = Response(resp.content, resp.status_code)
|
| 267 |
|
|
|
|
| 268 |
response.headers["Access-Control-Allow-Origin"] = "*"
|
| 269 |
response.headers["Access-Control-Allow-Headers"] = "*"
|
| 270 |
response.headers["Access-Control-Allow-Methods"] = "GET, POST, PATCH, PUT, DELETE, OPTIONS"
|
| 271 |
|
|
|
|
| 272 |
if "Content-Type" in resp.headers:
|
| 273 |
response.headers["Content-Type"] = resp.headers["Content-Type"]
|
| 274 |
|
| 275 |
return response
|
| 276 |
|
| 277 |
+
|
| 278 |
@app.errorhandler(404)
|
| 279 |
def cors_proxy_404(e):
|
| 280 |
baseurl = request.args.get("baseurl23896")
|
| 281 |
if not baseurl:
|
| 282 |
return abort(404)
|
| 283 |
|
|
|
|
| 284 |
forward_params = {
|
| 285 |
k: v for k, v in request.args.items()
|
| 286 |
if k != "baseurl23896"
|
| 287 |
}
|
| 288 |
+
|
| 289 |
cookie_param = request.args.get("cookie")
|
| 290 |
+
cookie_txt_url = request.args.get("cookie_txt_url")
|
| 291 |
+
|
| 292 |
+
cookies = {}
|
| 293 |
+
|
| 294 |
if cookie_param:
|
|
|
|
| 295 |
for item in cookie_param.split(";"):
|
| 296 |
if "=" in item:
|
| 297 |
k, v = item.split("=", 1)
|
| 298 |
cookies[k.strip()] = v.strip()
|
| 299 |
+
|
| 300 |
+
if cookie_txt_url:
|
| 301 |
+
try:
|
| 302 |
+
txt_resp = requests.get(cookie_txt_url, timeout=10)
|
| 303 |
+
txt_resp.raise_for_status()
|
| 304 |
+
txt_cookies = parse_cookie_txt(txt_resp.text)
|
| 305 |
+
cookies.update(txt_cookies)
|
| 306 |
+
except requests.RequestException:
|
| 307 |
+
return abort(400)
|
| 308 |
+
|
| 309 |
+
if not cookies:
|
| 310 |
+
cookies = None
|
| 311 |
+
|
| 312 |
target_url = baseurl.rstrip("/") + request.path
|
| 313 |
if forward_params:
|
| 314 |
target_url += "?" + urlencode(forward_params, doseq=True)
|
|
|
|
| 322 |
if k.lower() not in ["host", "content-length"]
|
| 323 |
},
|
| 324 |
data=request.get_data(),
|
| 325 |
+
cookies=cookies,
|
| 326 |
allow_redirects=False,
|
| 327 |
timeout=10,
|
| 328 |
)
|
|
|
|
| 335 |
"transfer-encoding",
|
| 336 |
"connection",
|
| 337 |
]
|
| 338 |
+
|
| 339 |
headers = [
|
| 340 |
(k, v) for k, v in resp.headers.items()
|
| 341 |
if k.lower() not in excluded_headers
|
|
|
|
| 343 |
|
| 344 |
return Response(resp.content, resp.status_code, headers)
|
| 345 |
|
| 346 |
+
|
| 347 |
#------------------
|
| 348 |
|
| 349 |
|