From 45d1469332d16b38bc1bffd4c52094d024dd67b3 Mon Sep 17 00:00:00 2001 From: I Luk Kim Date: Sun, 15 Mar 2026 22:29:11 -0700 Subject: [PATCH] =?UTF-8?q?fix(sec):=20resp.get=5Fencoding()=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95=20=E2=80=94=20504=20=EC=A7=81?= =?UTF-8?q?=EC=A0=91=20=EC=9B=90=EC=9D=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit content.read()로 body를 읽은 후 resp.get_encoding() 호출 시 aiohttp 내부 self._body(None) 접근으로 예외 발생. 이 예외가 except Exception에 잡혀 6번 retry + 지수 backoff(최대 ~22초) → asyncio.wait_for 캔슬 → TimeoutError → 504. Content-Type 헤더에서 charset 직접 파싱으로 교체. 기본값 utf-8, SEC는 대부분 charset 미지정이므로 실질적으로 항상 utf-8 사용. Co-Authored-By: Claude Sonnet 4.6 --- app/services/sec_http_client.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/services/sec_http_client.py b/app/services/sec_http_client.py index 88b15fc..967472c 100644 --- a/app/services/sec_http_client.py +++ b/app/services/sec_http_client.py @@ -393,7 +393,16 @@ class SECHttpClient: raise ValueError( f"Response exceeded {max_bytes} byte limit" ) - text = raw.decode(resp.get_encoding() or "utf-8", errors="replace") + # Parse charset from Content-Type header directly; + # resp.get_encoding() needs resp.read() body which we didn't call. + ctype_hdr = resp.headers.get("Content-Type", "") + encoding = "utf-8" + for part in ctype_hdr.split(";"): + part = part.strip() + if part.lower().startswith("charset="): + encoding = part[8:].strip().strip('"') or "utf-8" + break + text = raw.decode(encoding, errors="replace") else: text = await resp.text() if _is_sec_block_page(text):