Skip to content

Commit b09186f

Browse files
committed
fix(transport): Add correct Sync fallback for AsyncTransport
Previously, the Async Transport fallback pointed to the sync superclass, which does not implment core methods. This now falls back to the correct, implemented sync transport GH-4601
1 parent 35a9a72 commit b09186f

File tree

1 file changed

+107
-107
lines changed

1 file changed

+107
-107
lines changed

sentry_sdk/transport.py

Lines changed: 107 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -593,9 +593,115 @@ def flush(
593593
self._worker.flush(timeout, callback)
594594

595595

596+
class HttpTransport(BaseHttpTransport):
597+
if TYPE_CHECKING:
598+
_pool: Union[PoolManager, ProxyManager]
599+
600+
def _get_pool_options(self: Self) -> Dict[str, Any]:
601+
602+
num_pools = self.options.get("_experiments", {}).get("transport_num_pools")
603+
options = {
604+
"num_pools": 2 if num_pools is None else int(num_pools),
605+
"cert_reqs": "CERT_REQUIRED",
606+
"timeout": urllib3.Timeout(total=self.TIMEOUT),
607+
}
608+
609+
socket_options: Optional[List[Tuple[int, int, int | bytes]]] = None
610+
611+
if self.options["socket_options"] is not None:
612+
socket_options = self.options["socket_options"]
613+
614+
if self.options["keep_alive"]:
615+
if socket_options is None:
616+
socket_options = []
617+
618+
used_options = {(o[0], o[1]) for o in socket_options}
619+
for default_option in KEEP_ALIVE_SOCKET_OPTIONS:
620+
if (default_option[0], default_option[1]) not in used_options:
621+
socket_options.append(default_option)
622+
623+
if socket_options is not None:
624+
options["socket_options"] = socket_options
625+
626+
options["ca_certs"] = (
627+
self.options["ca_certs"] # User-provided bundle from the SDK init
628+
or os.environ.get("SSL_CERT_FILE")
629+
or os.environ.get("REQUESTS_CA_BUNDLE")
630+
or certifi.where()
631+
)
632+
633+
options["cert_file"] = self.options["cert_file"] or os.environ.get(
634+
"CLIENT_CERT_FILE"
635+
)
636+
options["key_file"] = self.options["key_file"] or os.environ.get(
637+
"CLIENT_KEY_FILE"
638+
)
639+
640+
return options
641+
642+
def _make_pool(self: Self) -> Union[PoolManager, ProxyManager]:
643+
if self.parsed_dsn is None:
644+
raise ValueError("Cannot create HTTP-based transport without valid DSN")
645+
646+
proxy = None
647+
no_proxy = self._in_no_proxy(self.parsed_dsn)
648+
649+
# try HTTPS first
650+
https_proxy = self.options["https_proxy"]
651+
if self.parsed_dsn.scheme == "https" and (https_proxy != ""):
652+
proxy = https_proxy or (not no_proxy and getproxies().get("https"))
653+
654+
# maybe fallback to HTTP proxy
655+
http_proxy = self.options["http_proxy"]
656+
if not proxy and (http_proxy != ""):
657+
proxy = http_proxy or (not no_proxy and getproxies().get("http"))
658+
659+
opts = self._get_pool_options()
660+
661+
if proxy:
662+
proxy_headers = self.options["proxy_headers"]
663+
if proxy_headers:
664+
opts["proxy_headers"] = proxy_headers
665+
666+
if proxy.startswith("socks"):
667+
use_socks_proxy = True
668+
try:
669+
# Check if PySocks dependency is available
670+
from urllib3.contrib.socks import SOCKSProxyManager
671+
except ImportError:
672+
use_socks_proxy = False
673+
logger.warning(
674+
"You have configured a SOCKS proxy (%s) but support for SOCKS proxies is not installed. Disabling proxy support. Please add `PySocks` (or `urllib3` with the `[socks]` extra) to your dependencies.",
675+
proxy,
676+
)
677+
678+
if use_socks_proxy:
679+
return SOCKSProxyManager(proxy, **opts)
680+
else:
681+
return urllib3.PoolManager(**opts)
682+
else:
683+
return urllib3.ProxyManager(proxy, **opts)
684+
else:
685+
return urllib3.PoolManager(**opts)
686+
687+
def _request(
688+
self: Self,
689+
method: str,
690+
endpoint_type: EndpointType,
691+
body: Any,
692+
headers: Mapping[str, str],
693+
) -> urllib3.BaseHTTPResponse:
694+
return self._pool.request(
695+
method,
696+
self._auth.get_api_url(endpoint_type),
697+
body=body,
698+
headers=headers,
699+
)
700+
701+
596702
if not ASYNC_TRANSPORT_ENABLED:
597703
# Sorry, no AsyncHttpTransport for you
598-
class AsyncHttpTransport(BaseHttpTransport):
704+
class AsyncHttpTransport(HttpTransport):
599705
def __init__(self: Self, options: Dict[str, Any]) -> None:
600706
super().__init__(options)
601707
logger.warning(
@@ -827,112 +933,6 @@ def kill(self: Self) -> Optional[asyncio.Task[None]]: # type: ignore
827933
return None
828934

829935

830-
class HttpTransport(BaseHttpTransport):
831-
if TYPE_CHECKING:
832-
_pool: Union[PoolManager, ProxyManager]
833-
834-
def _get_pool_options(self: Self) -> Dict[str, Any]:
835-
836-
num_pools = self.options.get("_experiments", {}).get("transport_num_pools")
837-
options = {
838-
"num_pools": 2 if num_pools is None else int(num_pools),
839-
"cert_reqs": "CERT_REQUIRED",
840-
"timeout": urllib3.Timeout(total=self.TIMEOUT),
841-
}
842-
843-
socket_options: Optional[List[Tuple[int, int, int | bytes]]] = None
844-
845-
if self.options["socket_options"] is not None:
846-
socket_options = self.options["socket_options"]
847-
848-
if self.options["keep_alive"]:
849-
if socket_options is None:
850-
socket_options = []
851-
852-
used_options = {(o[0], o[1]) for o in socket_options}
853-
for default_option in KEEP_ALIVE_SOCKET_OPTIONS:
854-
if (default_option[0], default_option[1]) not in used_options:
855-
socket_options.append(default_option)
856-
857-
if socket_options is not None:
858-
options["socket_options"] = socket_options
859-
860-
options["ca_certs"] = (
861-
self.options["ca_certs"] # User-provided bundle from the SDK init
862-
or os.environ.get("SSL_CERT_FILE")
863-
or os.environ.get("REQUESTS_CA_BUNDLE")
864-
or certifi.where()
865-
)
866-
867-
options["cert_file"] = self.options["cert_file"] or os.environ.get(
868-
"CLIENT_CERT_FILE"
869-
)
870-
options["key_file"] = self.options["key_file"] or os.environ.get(
871-
"CLIENT_KEY_FILE"
872-
)
873-
874-
return options
875-
876-
def _make_pool(self: Self) -> Union[PoolManager, ProxyManager]:
877-
if self.parsed_dsn is None:
878-
raise ValueError("Cannot create HTTP-based transport without valid DSN")
879-
880-
proxy = None
881-
no_proxy = self._in_no_proxy(self.parsed_dsn)
882-
883-
# try HTTPS first
884-
https_proxy = self.options["https_proxy"]
885-
if self.parsed_dsn.scheme == "https" and (https_proxy != ""):
886-
proxy = https_proxy or (not no_proxy and getproxies().get("https"))
887-
888-
# maybe fallback to HTTP proxy
889-
http_proxy = self.options["http_proxy"]
890-
if not proxy and (http_proxy != ""):
891-
proxy = http_proxy or (not no_proxy and getproxies().get("http"))
892-
893-
opts = self._get_pool_options()
894-
895-
if proxy:
896-
proxy_headers = self.options["proxy_headers"]
897-
if proxy_headers:
898-
opts["proxy_headers"] = proxy_headers
899-
900-
if proxy.startswith("socks"):
901-
use_socks_proxy = True
902-
try:
903-
# Check if PySocks dependency is available
904-
from urllib3.contrib.socks import SOCKSProxyManager
905-
except ImportError:
906-
use_socks_proxy = False
907-
logger.warning(
908-
"You have configured a SOCKS proxy (%s) but support for SOCKS proxies is not installed. Disabling proxy support. Please add `PySocks` (or `urllib3` with the `[socks]` extra) to your dependencies.",
909-
proxy,
910-
)
911-
912-
if use_socks_proxy:
913-
return SOCKSProxyManager(proxy, **opts)
914-
else:
915-
return urllib3.PoolManager(**opts)
916-
else:
917-
return urllib3.ProxyManager(proxy, **opts)
918-
else:
919-
return urllib3.PoolManager(**opts)
920-
921-
def _request(
922-
self: Self,
923-
method: str,
924-
endpoint_type: EndpointType,
925-
body: Any,
926-
headers: Mapping[str, str],
927-
) -> urllib3.BaseHTTPResponse:
928-
return self._pool.request(
929-
method,
930-
self._auth.get_api_url(endpoint_type),
931-
body=body,
932-
headers=headers,
933-
)
934-
935-
936936
if not HTTP2_ENABLED:
937937
# Sorry, no Http2Transport for you
938938
class Http2Transport(HttpTransport):

0 commit comments

Comments
 (0)