Skip to content

Commit

Permalink
Enabled TCP Keep Alive on httpcore (httpx)
Browse files Browse the repository at this point in the history
Currently there is no way to enable TCP KeepAlive directly on httpx
module

ref. PR:#1172
  • Loading branch information
CastagnaIT committed Sep 13, 2023
1 parent 6e60317 commit d5bae5e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/httpcore/_backends/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
)
from .._utils import is_socket_readable
from .base import SOCKET_OPTION, NetworkBackend, NetworkStream
from .tcp_keep_alive import enable_tcp_keep_alive


class TLSinTLSStream(NetworkStream): # pragma: no cover
Expand Down Expand Up @@ -217,6 +218,8 @@ def connect_tcp(
for option in socket_options:
sock.setsockopt(*option) # pragma: no cover
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
# Enable TCP Keep-Alive
enable_tcp_keep_alive(sock)
return SyncStream(sock)

def connect_unix_socket(
Expand Down
38 changes: 38 additions & 0 deletions packages/httpcore/_backends/tcp_keep_alive.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2021 Stefano Gottardo - @CastagnaIT
Helper to enable TCP Keep Alive
SPDX-License-Identifier: MIT
See LICENSES/MIT.md for more information.
"""
import socket
import sys

TCP_KEEP_IDLE = 45
TCP_KEEPALIVE_INTERVAL = 10
TCP_KEEP_CNT = 6


def enable_tcp_keep_alive(sock):
"""Enable TCP Keep-Alive (by default disabled)"""
# More info on PR: https://github.com/CastagnaIT/plugin.video.netflix/pull/1065
sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if sys.platform == 'linux':
# TCP Keep Alive Probes for Linux/Android
if hasattr(socket, 'TCP_KEEPIDLE'):
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, TCP_KEEP_IDLE)
if hasattr(socket, 'TCP_KEEPINTVL'):
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, TCP_KEEPALIVE_INTERVAL)
if hasattr(socket, 'TCP_KEEPCNT'):
sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, TCP_KEEP_CNT)
elif sys.platform == 'darwin':
# TCP Keep Alive Probes for MacOS
# NOTE: The socket constants from MacOS netinet/tcp.h are not exported by python's socket module
# The MacOS TCP_KEEPALIVE(0x10) constant should be the same thing of the linux TCP_KEEPIDLE constant
sock.setsockopt(socket.IPPROTO_TCP, getattr(socket, 'TCP_KEEPIDLE', 0x10), TCP_KEEP_IDLE)
sock.setsockopt(socket.IPPROTO_TCP, getattr(socket, 'TCP_KEEPINTVL', 0x101), TCP_KEEPALIVE_INTERVAL)
sock.setsockopt(socket.IPPROTO_TCP, getattr(socket, 'TCP_KEEPCNT', 0x102), TCP_KEEP_CNT)
elif sys.platform == 'win32':
# TCP Keep Alive Probes for Windows
sock.ioctl(socket.SIO_KEEPALIVE_VALS, (1, TCP_KEEP_IDLE * 1000, TCP_KEEPALIVE_INTERVAL * 1000))

0 comments on commit d5bae5e

Please sign in to comment.