From f89d6342d14b4af8d20f9f697a5a041ffdf78cdf Mon Sep 17 00:00:00 2001 From: hyuan280 Date: Wed, 21 Jan 2026 16:36:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DCookie=E8=A7=A3?= =?UTF-8?q?=E7=A0=81=E4=BA=8C=E8=BF=9B=E5=88=B6=E6=95=B0=E6=8D=AE=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E8=AF=B7=E6=B1=82=E5=8F=91=E9=80=81=E6=97=B6UnicodeEn?= =?UTF-8?q?codeError?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/utils/http.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/app/utils/http.py b/app/utils/http.py index 6befa33b..c4d91d4c 100644 --- a/app/utils/http.py +++ b/app/utils/http.py @@ -10,6 +10,7 @@ import requests import urllib3 from requests import Response, Session from urllib3.exceptions import InsecureRequestWarning +from urllib.parse import unquote, quote from app.core.config import settings from app.log import logger @@ -17,6 +18,25 @@ from app.log import logger urllib3.disable_warnings(InsecureRequestWarning) +def _url_decode_if_latin(original: str) -> str: + """ + 解码URL编码的字符串,只解码文本,二进程数据保持不变 + :param original: URL编码字符串 + :return: 解码后的字符串或原始二进制数据 + """ + try: + # 先解码 + decoded = unquote(original, encoding='latin-1') + # 再完整编码 + fully_encoded = quote(decoded, safe='') + # 验证 + decoded_again = unquote(fully_encoded, encoding='latin-1') + if decoded_again == decoded: + return decoded + except Exception as e: + logger.error(f"latin-1解码URL编码失败:{e}") + return original + def cookie_parse(cookies_str: str, array: bool = False) -> Union[list, dict]: """ 解析cookie,转化为字典或者数组 @@ -26,14 +46,14 @@ def cookie_parse(cookies_str: str, array: bool = False) -> Union[list, dict]: """ if not cookies_str: return {} - from urllib.parse import unquote + cookie_dict = {} cookies = cookies_str.split(";") for cookie in cookies: cstr = cookie.split("=", 1) # 只分割第一个=,因为value可能包含= if len(cstr) > 1: # URL解码Cookie值(但保留Cookie名不解码) - cookie_dict[cstr[0].strip()] = unquote(cstr[1].strip()) + cookie_dict[cstr[0].strip()] = _url_decode_if_latin(cstr[1].strip()) if array: return [{"name": k, "value": v} for k, v in cookie_dict.items()] return cookie_dict