logging: `SMTPHandler.emit()` leaks the SMTP connection when sending fails
未關閉
還沒有人認領這個 Issue。
stdlib
type-bug
- 主要語言
- Python
- 星號
- 77.2k
- 分支
- 36k
- PR 合併指標
- PR 指標待擷取
描述
Bug report
Bug description:
SMTPHandler.emit() only closes its SMTP connection on the success path: smtp.quit() is the last statement of the try block (Lib/logging/handlers.py#L1109-L1154).
If starttls(), login() or send_message() raises, control jumps to except Exception: self.handleError(record) and the connection is never closed — cleanup is left to the garbage collector.
Reproducer
import gc, logging, logging.handlers, socket, threading, time
logging.raiseExceptions = False
open_conns = []
def handle(conn):
conn.sendall(b"220 fake ESMTP\r\n")
for line in conn.makefile("rb"):
cmd = line.strip().upper()
if cmd.startswith(b"EHLO"):
conn.sendall(b"250-fake\r\n250 AUTH PLAIN LOGIN\r\n")
elif cmd.startswith(b"AUTH"):
conn.sendall(b"535 authentication failed\r\n")
else:
conn.sendall(b"250 ok\r\n")
open_conns.remove(conn) # reached when the client closes the connection
conn.close()
def serve(listener):
while True:
conn, _ = listener.accept()
open_conns.append(conn)
threading.Thread(target=handle, args=(conn,), daemon=True).start()
listener = socket.create_server(("127.0.0.1", 0))
threading.Thread(target=serve, args=(listener,), daemon=True).start()
h = logging.handlers.SMTPHandler(("127.0.0.1", listener.getsockname()[1]),
"me@example.com", "you@example.com", "subject",
credentials=("user", "wrong-password"))
for i in range(5):
h.emit(logging.makeLogRecord({"msg": "hello"})) # SMTPAuthenticationError
time.sleep(0.5)
print("open connections after 5 failed emits:", len(open_conns))
gc.collect(); time.sleep(0.5)
print("after gc.collect():", len(open_conns))
Output on main:
open connections after 5 failed emits: 5
after gc.collect(): 0
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
- gh-155950
貢獻指南
從這裡開始
- 先讀完整個 Issue,再讀專案的貢獻指南。
- 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
- Fork 儲存庫,在一個分支上完成修改。
- 送出 Pull Request,並在描述裡引用這個 Issue 編號。
研究方向
從 Lib/logging/handlers.py 中的 SMTPHandler.emit() 開始,並執行提供的驗證失敗重現程式。完成的標準是,starttls()、login() 或 send_message() 失敗的路徑不再讓 SMTP 連線保持開啟狀態,並根據重現程式檢查行為;連結的 PR gh-155950 表示相關工作已經在進行中。
由索引模型根據 Issue 內容生成。
評估
- 技術堆疊
- python
- 領域
- backend
- Issue 類型
- 缺陷
- 難度
- 2/5
- 預估耗時
- 1-3 小時
- 活躍度
- 停滯
- 描述清晰度
- 描述清楚
- 新手友好度
- 25/100