Skip to content

Commit fc52c68

Browse files
committed
chore(api): guard PSL lookup with 1s thread timeout
1 parent e75380b commit fc52c68

1 file changed

Lines changed: 24 additions & 4 deletions

File tree

api/desecapi/models/domains.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
from functools import cached_property
4+
from threading import Thread
45

56
import dns
67
import psl_dns
@@ -96,13 +97,32 @@ def __init__(self, *args, **kwargs):
9697

9798
@cached_property
9899
def public_suffix(self):
99-
try:
100-
public_suffix = psl.get_public_suffix(self.name)
101-
is_public_suffix = psl.is_public_suffix(self.name)
102-
except (Timeout, NoNameservers):
100+
result: dict[str, object] = {}
101+
102+
def _worker() -> None:
103+
try:
104+
result["public_suffix"] = psl.get_public_suffix(self.name)
105+
result["is_public_suffix"] = psl.is_public_suffix(self.name)
106+
except Exception as exc:
107+
result["error"] = exc
108+
109+
thread = Thread(target=_worker, name="psl_lookup", daemon=True)
110+
thread.start()
111+
thread.join(timeout=1.0)
112+
if thread.is_alive():
103113
public_suffix = self.name.rpartition(".")[2]
104114
is_public_suffix = "." not in self.name # TLDs are public suffixes
105115

116+
if "error" in result:
117+
if isinstance(result["error"], (Timeout, NoNameservers)):
118+
public_suffix = self.name.rpartition(".")[2]
119+
is_public_suffix = "." not in self.name # TLDs are public suffixes
120+
else:
121+
raise result["error"] # type: ignore[misc]
122+
else:
123+
public_suffix = result["public_suffix"] # type: ignore[assignment]
124+
is_public_suffix = result["is_public_suffix"] # type: ignore[assignment]
125+
106126
if is_public_suffix:
107127
return public_suffix
108128

0 commit comments

Comments
 (0)