-
-
Notifications
You must be signed in to change notification settings - Fork 450
Description
Hi, I encountered a reproducible crash in curl_cffi when using Session.get(..., stream=True) to read from a long-lived streaming endpoint (SSE or chunked stream).
Summary of the issue
When reading only the first line of a streaming response, if the stream has not fully initialized or not exited normally, calling:
response.close()
session.close()
will occasionally cause a hard crash (Python process exits without exception, likely a segfault from libcurl).
This happens only when the streaming connection is not cleanly closed on the server side or when the read is interrupted early. It seems the internal curl easy handle or connection state is still “half-initialized”, and freeing it leads to an invalid pointer free.
Minimal Reproduction
from curl_cffi import requests
import time
session = requests.Session()
session.keep_alive = True
response = session.get(url, stream=True, timeout=1.5)
# Read only the first event/chunk
it = response.iter_lines()
chunk = next(it)
# ❗ Crash happens here
response.close()
session.close()
If the server does not close the stream gracefully, or the stream initialization is incomplete, calling close() crashes the interpreter.
Expected behavior
Closing a session or response should never crash Python, even if the underlying curl handle is in a partially initialized or interrupted streaming state.
Actual behavior
The Python interpreter exits abruptly (no Python exception, likely segmentation fault from curl handle cleanup).
Additional Notes
This only affects stream=True long-lived endpoints (SSE, chunked streams).
Not closing the response/session avoids the crash, but leads to resource leak.
Setting keep_alive=False reduces but does not eliminate the crash.
The issue likely occurs during cleanup of an active or half-initialized libcurl easy handle.
Environment
curl_cffi version: 0.13.0
Python version: 3.13.9
Platform: Windows 11
Endpoint: long-lived SSE/streaming API (never ends unless interrupted)
Request
Is it possible to make response.close() and session.close() safe in all cases by ensuring that any partially initialized curl handle is put into a valid cleanup state before being freed?