Skip to content

Commit dea8cf4

Browse files
Merge pull request #279 from iakov-kaiumov/socket-error
Raise an exception on socket error
2 parents 2b8367e + 64707ee commit dea8cf4

2 files changed

Lines changed: 22 additions & 11 deletions

File tree

whois/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ def whois(
3333
executable_opts: Optional[list[str]] = None,
3434
inc_raw: bool = False,
3535
quiet: bool = False,
36+
ignore_socket_errors: bool = True,
3637
convert_punycode: bool = True,
3738
) -> dict[str, Any]:
3839
"""
@@ -42,6 +43,7 @@ def whois(
4243
flags: flags to pass to the whois client (default 0)
4344
inc_raw: whether to include the raw text from whois in the result (default False)
4445
quiet: whether to avoid printing output (default False)
46+
ignore_socket_errors: whether to ignore socket errors (default True)
4547
convert_punycode: whether to convert the given URL punycode (default True)
4648
"""
4749
# clean domain to expose netloc
@@ -74,7 +76,7 @@ def whois(
7476
nic_client = NICClient()
7577
if convert_punycode:
7678
domain = domain.encode("idna").decode("utf-8")
77-
text = nic_client.whois_lookup(None, domain, flags, quiet=quiet)
79+
text = nic_client.whois_lookup(None, domain, flags, quiet=quiet, ignore_socket_errors=ignore_socket_errors)
7880
entry = WhoisEntry.load(domain, text)
7981
if inc_raw:
8082
entry["raw"] = text

whois/whois.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,17 @@ def whois(
201201
many_results: bool = False,
202202
quiet: bool = False,
203203
timeout: int = 10,
204+
ignore_socket_errors: bool = True
204205
) -> str:
205206
"""Perform initial lookup with TLD whois server
206207
then, if the quick flag is false, search that result
207208
for the region-specific whois server and do a lookup
208209
there for contact details. If `quiet` is `True`, will
209210
not send a message to logger when a socket error
210211
is encountered. Uses `timeout` as a number of seconds
211-
to set as a timeout on the socket
212+
to set as a timeout on the socket. If `ignore_socket_errors`
213+
is `False`, will raise an exception instead of returning
214+
a string containing the error.
212215
"""
213216
response = b""
214217
s = self.get_socket()
@@ -233,24 +236,27 @@ def whois(
233236
response += d
234237
if not d:
235238
break
236-
s.close()
237239

238240
nhost = None
239241
response_str = response.decode("utf-8", "replace")
240242
if 'with "=xxx"' in response_str:
241-
return self.whois(query, hostname, flags, True)
243+
return self.whois(query, hostname, flags, True, quiet=quiet, ignore_socket_errors=ignore_socket_errors)
242244
if flags & NICClient.WHOIS_RECURSE and nhost is None:
243245
nhost = self.findwhois_server(response_str, hostname, query)
244246
if nhost is not None and nhost != "":
245-
response_str += self.whois(query, nhost, 0, quiet=True)
247+
response_str += self.whois(query, nhost, 0, quiet=quiet, ignore_socket_errors=ignore_socket_errors)
246248
except socket.error as e:
247-
# 'response' is assigned a value (also a str) even on socket timeout
248249
if not quiet:
249250
logger.error(
250251
"Error trying to connect to socket: closing socket - {}".format(e)
251252
)
253+
if ignore_socket_errors:
254+
# 'response' is assigned a value (also a str) even on socket timeout
255+
response_str = "Socket not responding: {}".format(e)
256+
else:
257+
raise e
258+
finally:
252259
s.close()
253-
response_str = "Socket not responding: {}".format(e)
254260
return response_str
255261

256262
def choose_server(self, domain: str) -> Optional[str]:
@@ -407,13 +413,15 @@ def choose_server(self, domain: str) -> Optional[str]:
407413
# return server
408414

409415
def whois_lookup(
410-
self, options: Optional[dict], query_arg: str, flags: int, quiet: bool = False
416+
self, options: Optional[dict], query_arg: str, flags: int, quiet: bool = False, ignore_socket_errors: bool = True
411417
) -> str:
412418
"""Main entry point: Perform initial lookup on TLD whois server,
413419
or other server to get region-specific whois server, then if quick
414420
flag is false, perform a second lookup on the region-specific
415421
server for contact records. If `quiet` is `True`, no message
416-
will be printed to STDOUT when a socket error is encountered."""
422+
will be printed to STDOUT when a socket error is encountered.
423+
If `ignore_socket_errors` is `False`, will raise an exception
424+
instead of returning a string containing the error."""
417425
nichost = None
418426
# whoud happen when this function is called by other than main
419427
if options is None:
@@ -433,15 +441,16 @@ def whois_lookup(
433441
options["country"] + NICClient.QNICHOST_TAIL,
434442
flags,
435443
quiet=quiet,
444+
ignore_socket_errors=ignore_socket_errors
436445
)
437446
elif self.use_qnichost:
438447
nichost = self.choose_server(query_arg)
439448
if nichost is not None:
440-
result = self.whois(query_arg, nichost, flags, quiet=quiet)
449+
result = self.whois(query_arg, nichost, flags, quiet=quiet, ignore_socket_errors=ignore_socket_errors)
441450
else:
442451
result = ""
443452
else:
444-
result = self.whois(query_arg, options["whoishost"], flags, quiet=quiet)
453+
result = self.whois(query_arg, options["whoishost"], flags, quiet=quiet, ignore_socket_errors=ignore_socket_errors)
445454
return result
446455

447456

0 commit comments

Comments
 (0)