Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 4 additions & 28 deletions tornado/curl_httpclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,6 @@ def initialize( # type: ignore
self._fds: dict[int, int] = {}
self._timeout: object | None = None

# libcurl has bugs that sometimes cause it to not report all
# relevant file descriptors and timeouts to TIMERFUNCTION/
# SOCKETFUNCTION. Mitigate the effects of such bugs by
# forcing a periodic scan of all active requests.
self._force_timeout_callback = ioloop.PeriodicCallback(
self._handle_force_timeout, 1000
)
self._force_timeout_callback.start()

# Work around a bug in libcurl 7.29.0: Some fields in the curl
# multi object are initialized lazily, and its destructor will
# segfault if it is destroyed without having been used. Add
Expand All @@ -80,7 +71,6 @@ def initialize( # type: ignore
self._multi.remove_handle(dummy_curl_handle)

def close(self) -> None:
self._force_timeout_callback.stop()
if self._timeout is not None:
self.io_loop.remove_timeout(self._timeout)
for curl in self._curls:
Expand All @@ -91,7 +81,6 @@ def close(self) -> None:
# Set below properties to None to reduce the reference count of current
# instance, because those properties hold some methods of current
# instance that will case circular reference.
self._force_timeout_callback = None # type: ignore
self._multi = None

def fetch_impl(
Expand Down Expand Up @@ -185,19 +174,6 @@ def _handle_timeout(self) -> None:
if new_timeout >= 0:
self._set_timeout(new_timeout)

def _handle_force_timeout(self) -> None:
"""Called by IOLoop periodically to ask libcurl to process any
events it may have forgotten about.
"""
while True:
try:
ret, num_handles = self._multi.socket_all()
except pycurl.error as e:
ret = e.args[0]
if ret != pycurl.E_CALL_MULTI_PERFORM:
break
self._finish_pending_requests()

def _finish_pending_requests(self) -> None:
"""Process any requests that were completed by the last
call to multi.socket_action.
Expand Down Expand Up @@ -487,12 +463,12 @@ def write_function(b: bytes | bytearray) -> int:
raise ValueError("Body must be None for GET request")
request_buffer = BytesIO(utf8(request.body or ""))

def ioctl(cmd: int) -> None:
if cmd == curl.IOCMD_RESTARTREAD: # type: ignore
request_buffer.seek(0)
def seek(offset: int, origin: int) -> int:
request_buffer.seek(offset, origin)
return pycurl.SEEKFUNC_OK

curl.setopt(pycurl.READFUNCTION, request_buffer.read)
curl.setopt(pycurl.IOCTLFUNCTION, ioctl)
curl.setopt(pycurl.SEEKFUNCTION, seek)
if request.method == "POST":
curl.setopt(pycurl.POSTFIELDSIZE, len(request.body or ""))
else:
Expand Down
Loading