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
  • Loading branch information
CastagnaIT committed Jun 15, 2021
1 parent 60530a5 commit 21054d9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/httpcore/_backends/sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
WriteTimeout,
map_exceptions,
)
from .tcp_keep_alive import enable_tcp_keep_alive
from .._types import TimeoutDict
from .._utils import is_socket_readable

Expand Down Expand Up @@ -137,6 +138,9 @@ def open_tcp_stream(
sock = socket.create_connection(
address, connect_timeout, source_address=source_address # type: ignore
)
# Enable TCP Keep-Alive
enable_tcp_keep_alive(sock)

if ssl_context is not None:
sock = ssl_context.wrap_socket(
sock, server_hostname=hostname.decode("ascii")
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 21054d9

Please sign in to comment.