PyFunceble-dev 4.3.0a21__py3-none-any.whl → 4.3.0a24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. PyFunceble/checker/availability/base.py +7 -6
  2. PyFunceble/checker/availability/domain.py +18 -0
  3. PyFunceble/checker/availability/extras/base.py +4 -4
  4. PyFunceble/checker/availability/extras/dns.py +1 -1
  5. PyFunceble/checker/availability/extras/etoxic.py +3 -3
  6. PyFunceble/checker/availability/extras/parked.py +22 -20
  7. PyFunceble/checker/availability/extras/rules.py +5 -13
  8. PyFunceble/checker/availability/extras/subject_switch.py +4 -5
  9. PyFunceble/checker/availability/ip.py +18 -0
  10. PyFunceble/checker/availability/params.py +1 -1
  11. PyFunceble/checker/availability/status.py +9 -4
  12. PyFunceble/checker/availability/url.py +6 -0
  13. PyFunceble/checker/base.py +4 -0
  14. PyFunceble/checker/reputation/base.py +5 -2
  15. PyFunceble/checker/reputation/domain.py +11 -0
  16. PyFunceble/checker/reputation/ip.py +11 -0
  17. PyFunceble/checker/reputation/status.py +1 -1
  18. PyFunceble/checker/reputation/url.py +12 -1
  19. PyFunceble/checker/syntax/base.py +4 -1
  20. PyFunceble/checker/syntax/domain.py +4 -0
  21. PyFunceble/checker/syntax/ip.py +4 -0
  22. PyFunceble/checker/syntax/ipv4.py +10 -13
  23. PyFunceble/checker/syntax/ipv6.py +9 -11
  24. PyFunceble/checker/syntax/params.py +1 -1
  25. PyFunceble/checker/syntax/second_lvl_domain.py +3 -4
  26. PyFunceble/checker/syntax/subdomain.py +3 -4
  27. PyFunceble/checker/syntax/url.py +9 -6
  28. PyFunceble/checker/utils/whois.py +7 -11
  29. PyFunceble/cli/continuous_integration/base.py +14 -14
  30. PyFunceble/cli/credential_loader.py +4 -6
  31. PyFunceble/cli/entry_points/clean.py +0 -1
  32. PyFunceble/cli/entry_points/production.py +1 -1
  33. PyFunceble/cli/entry_points/pyfunceble/cli.py +11 -2
  34. PyFunceble/cli/execution_time.py +2 -2
  35. PyFunceble/cli/filesystem/cleanup.py +1 -3
  36. PyFunceble/cli/filesystem/dir_base.py +5 -1
  37. PyFunceble/cli/filesystem/dir_structure/backup.py +1 -2
  38. PyFunceble/cli/filesystem/dir_structure/base.py +0 -1
  39. PyFunceble/cli/filesystem/dir_structure/restore.py +5 -7
  40. PyFunceble/cli/filesystem/status_file.py +2 -3
  41. PyFunceble/cli/migrators/alembic.py +2 -4
  42. PyFunceble/cli/migrators/csv_file/inactive_source_delete.py +0 -1
  43. PyFunceble/cli/migrators/csv_file/whois_registrar_add.py +0 -1
  44. PyFunceble/cli/migrators/db_base.py +2 -2
  45. PyFunceble/cli/migrators/file_cleanup/base.py +3 -3
  46. PyFunceble/cli/migrators/file_cleanup/hashes_file.py +2 -3
  47. PyFunceble/cli/migrators/file_cleanup/mining_file.py +2 -3
  48. PyFunceble/cli/migrators/file_cleanup/production_config_file.py +2 -3
  49. PyFunceble/cli/migrators/mariadb/base.py +2 -4
  50. PyFunceble/cli/migrators/mariadb/file_and_status.py +1 -1
  51. PyFunceble/cli/migrators/mariadb/whois_record_idna_subject.py +0 -2
  52. PyFunceble/cli/processes/migrator.py +0 -1
  53. PyFunceble/cli/processes/workers/base.py +0 -1
  54. PyFunceble/cli/processes/workers/chancy_producer.py +1 -2
  55. PyFunceble/cli/processes/workers/dir_files_sorter.py +6 -14
  56. PyFunceble/cli/processes/workers/file_sorter.py +2 -9
  57. PyFunceble/cli/processes/workers/migrator.py +0 -1
  58. PyFunceble/cli/processes/workers/producer.py +2 -4
  59. PyFunceble/cli/processes/workers/tester.py +2 -3
  60. PyFunceble/cli/scripts/iana.py +14 -10
  61. PyFunceble/cli/scripts/production.py +2 -2
  62. PyFunceble/cli/scripts/public_suffix.py +2 -2
  63. PyFunceble/cli/system/integrator.py +1 -1
  64. PyFunceble/cli/system/launcher.py +14 -11
  65. PyFunceble/cli/utils/stdout.py +1 -1
  66. PyFunceble/cli/utils/testing.py +6 -16
  67. PyFunceble/config/compare.py +10 -9
  68. PyFunceble/config/loader.py +7 -4
  69. PyFunceble/converter/input_line2subject.py +2 -2
  70. PyFunceble/converter/internal_url.py +1 -1
  71. PyFunceble/converter/rpz_input_line2subject.py +2 -4
  72. PyFunceble/converter/subject2complements.py +4 -1
  73. PyFunceble/converter/url2netloc.py +3 -3
  74. PyFunceble/converter/wildcard2subject.py +3 -3
  75. PyFunceble/helpers/command.py +1 -1
  76. PyFunceble/helpers/dict.py +4 -4
  77. PyFunceble/helpers/file.py +2 -2
  78. PyFunceble/helpers/list.py +10 -7
  79. PyFunceble/helpers/merge.py +2 -2
  80. PyFunceble/helpers/regex.py +9 -11
  81. PyFunceble/query/dns/nameserver.py +9 -19
  82. PyFunceble/query/dns/query_tool.py +64 -205
  83. PyFunceble/query/dns/resolver.py +64 -51
  84. PyFunceble/query/netinfo/address.py +4 -6
  85. PyFunceble/query/netinfo/base.py +1 -1
  86. PyFunceble/query/netinfo/hostbyaddr.py +5 -8
  87. PyFunceble/query/requests/adapter/base.py +3 -3
  88. PyFunceble/query/requests/adapter/http.py +0 -1
  89. PyFunceble/query/requests/requester.py +6 -6
  90. PyFunceble/query/whois/converter/expiration_date.py +19 -8
  91. PyFunceble/query/whois/converter/month2unified.py +4 -6
  92. PyFunceble/query/whois/converter/registrar.py +18 -5
  93. PyFunceble/query/whois/query_tool.py +15 -18
  94. PyFunceble/storage.py +1 -1
  95. {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/METADATA +109 -108
  96. {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/RECORD +100 -100
  97. {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/WHEEL +1 -1
  98. {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/entry_points.txt +0 -0
  99. {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/licenses/LICENSE +0 -0
  100. {pyfunceble_dev-4.3.0a21.dist-info → pyfunceble_dev-4.3.0a24.dist-info}/top_level.txt +0 -0
@@ -64,6 +64,7 @@ class Subject2Complements(ConverterBase):
64
64
  """
65
65
 
66
66
  _include_given: bool = False
67
+ domain_syntax_checker: Optional[DomainSyntaxChecker] = None
67
68
 
68
69
  def __init__(
69
70
  self,
@@ -74,6 +75,8 @@ class Subject2Complements(ConverterBase):
74
75
  if include_given is not None:
75
76
  self.include_given = include_given
76
77
 
78
+ self.domain_syntax_checker = DomainSyntaxChecker()
79
+
77
80
  super().__init__(data_to_convert=data_to_convert)
78
81
 
79
82
  @ConverterBase.data_to_convert.setter
@@ -143,7 +146,7 @@ class Subject2Complements(ConverterBase):
143
146
  _ = aggressive
144
147
  result = []
145
148
 
146
- checker = DomainSyntaxChecker(data)
149
+ checker = self.domain_syntax_checker.set_subject(data)
147
150
 
148
151
  if self.include_given and data not in result:
149
152
  result.append(data)
@@ -58,7 +58,7 @@ from PyFunceble.converter.base import ConverterBase
58
58
 
59
59
  class Url2Netloc(ConverterBase):
60
60
  """
61
- Provides the interface for the conversion/extration of the network location
61
+ Provides the interface for the conversion/extraction of the network location
62
62
  of a given URL.
63
63
  """
64
64
 
@@ -70,7 +70,7 @@ class Url2Netloc(ConverterBase):
70
70
  @ConverterBase.data_to_convert.setter
71
71
  def data_to_convert(self, value: Any) -> None:
72
72
  """
73
- Overrites the default behavior.
73
+ Overrides the default behavior.
74
74
 
75
75
  :raise TypeError:
76
76
  When the given data to convert is not :py:class:`str`
@@ -116,7 +116,7 @@ class Url2Netloc(ConverterBase):
116
116
  Provides the converted data (after conversion)
117
117
  """
118
118
 
119
- # Retrocompatibility.
119
+ # Retro-compatibility.
120
120
  self.parse_url()
121
121
 
122
122
  return self.convert(self.data_to_convert)
@@ -52,7 +52,7 @@ License:
52
52
  """
53
53
  # pylint: enable=line-too-long
54
54
 
55
- from typing import Any
55
+ from typing import Any, Optional
56
56
 
57
57
  from PyFunceble.converter.base import ConverterBase
58
58
 
@@ -67,7 +67,7 @@ class Wildcard2Subject(ConverterBase):
67
67
  @ConverterBase.data_to_convert.setter
68
68
  def data_to_convert(self, value: Any) -> None:
69
69
  """
70
- Overrites the default behavior.
70
+ Overrides the default behavior.
71
71
 
72
72
  :raise TypeError:
73
73
  When the given data to convert is not :py:class:`str`
@@ -86,7 +86,7 @@ class Wildcard2Subject(ConverterBase):
86
86
 
87
87
  return self.convert(self.data_to_convert)
88
88
 
89
- def convert(self, data: Any, *, aggressive: bool = False) -> str:
89
+ def convert(self, data: Any, *, aggressive: bool = False) -> Optional[str]:
90
90
  """
91
91
  Converts the given dataset.
92
92
 
@@ -212,7 +212,7 @@ class CommandHelper:
212
212
  is that :func:`~PyFunceble.helpers.Command.execute` wait for the
213
213
  process to end in order to return its output while this method
214
214
  return each line one by one
215
- - as they are outputed.
215
+ - as they are outputted.
216
216
 
217
217
  :param bool rstrip:
218
218
  Deactivates the rstrip of the output.
@@ -66,7 +66,7 @@ class DictHelper:
66
66
  Simplify some :code:`dict` manipulation.
67
67
 
68
68
  :param dict main: The main :code:`dict` to work with.
69
- :raise TypeError: When :code:`main` is not a dict nor a list (tolarated).
69
+ :raise TypeError: When :code:`main` is not a dict nor a list (tolerated).
70
70
  """
71
71
 
72
72
  _subject: Optional[Union[Any, dict]] = None
@@ -349,7 +349,7 @@ class DictHelper:
349
349
  :param bool default_flow_style: Uses the default flow style.
350
350
  :param int indent: The indentation to apply.
351
351
  :param bool allow_unicode: Allows the decoding of unicode chars.
352
- :param bool sort_keys: Sors the keys.
352
+ :param bool sort_keys: Sorts the keys.
353
353
 
354
354
  :rtype: dict|list
355
355
  """
@@ -371,7 +371,7 @@ class DictHelper:
371
371
  data: Optional[Any] = None,
372
372
  ) -> dict:
373
373
  """
374
- Flatten the current dictionnary.
374
+ Flatten the current dictionary.
375
375
 
376
376
  :param separator:
377
377
  The separator to apply.
@@ -405,7 +405,7 @@ class DictHelper:
405
405
 
406
406
  def unflatten(self, *, separator: str = ".", data: Optional[Any] = None):
407
407
  """
408
- Unflatten a previously flatten dictionnary.
408
+ Unflatten a previously flatten dictionary.
409
409
 
410
410
  :param separator:
411
411
  The separator to split.
@@ -183,7 +183,7 @@ class FileHelper:
183
183
 
184
184
  def read_bytes(self) -> Optional[bytes]:
185
185
  """
186
- Read the given file ath and returns it's bytes contetn.
186
+ Read the given file ath and returns it's bytes content.
187
187
  """
188
188
 
189
189
  data = None
@@ -203,7 +203,7 @@ class FileHelper:
203
203
 
204
204
  def copy(self, destination: str, *, create_parent: bool = False) -> "FileHelper":
205
205
  """
206
- Copy the globaly given file path to the given destination.
206
+ Copy the globally given file path to the given destination.
207
207
 
208
208
  :param str destination: The destination of the copy.
209
209
  :param bool create_parent: Tell us if we have to create the parent directory.
@@ -115,18 +115,21 @@ class ListHelper:
115
115
 
116
116
  return self
117
117
 
118
- def remove_duplicates(self) -> "ListHelper":
118
+ def remove_duplicates(self, *, efficient: bool = True) -> "ListHelper":
119
119
  """
120
120
  Removes the duplicates of the current list.
121
121
  """
122
122
 
123
- result = []
123
+ if efficient:
124
+ self.subject = list(set(self.subject))
125
+ else:
126
+ result = []
124
127
 
125
- for element in self.subject:
126
- if element not in result:
127
- result.append(element)
128
+ for element in self.subject:
129
+ if element not in result:
130
+ result.append(element)
128
131
 
129
- self.subject = result
132
+ self.subject = result
130
133
 
131
134
  return self
132
135
 
@@ -147,7 +150,7 @@ class ListHelper:
147
150
 
148
151
  :param key_method:
149
152
  A function or method to use to format the
150
- readed element before sorting.
153
+ read element before sorting.
151
154
  :type key_method: function|method
152
155
 
153
156
  :param bool reverse: Tell us if we have to reverse the list.
@@ -1,5 +1,5 @@
1
1
  """
2
- The tool to check the availability or syntax of dosubject, IP or URL.
2
+ The tool to check the availability or syntax of domain, IP or URL.
3
3
 
4
4
  ::
5
5
 
@@ -164,7 +164,7 @@ class Merge:
164
164
 
165
165
  def into(self, origin: Any, strict: bool = True) -> Any:
166
166
  """
167
- Process the mergin.
167
+ Process the merging.
168
168
 
169
169
  :param origin: The original data.
170
170
  :param strict:
@@ -63,6 +63,7 @@ class RegexHelper:
63
63
  """
64
64
 
65
65
  _regex: Optional[str] = None
66
+ _compiled: Optional[re.Pattern] = None
66
67
  escape_regex: bool = False
67
68
 
68
69
  def __init__(self, regex: Optional[str] = None, escape_regex: bool = False):
@@ -99,6 +100,8 @@ class RegexHelper:
99
100
  else:
100
101
  self._regex = re.escape(value)
101
102
 
103
+ self._compiled = re.compile(self._regex)
104
+
102
105
  def set_regex(self, value: str) -> "RegexHelper":
103
106
  """
104
107
  Sets the regex to work with.
@@ -120,9 +123,7 @@ class RegexHelper:
120
123
  in the given data.
121
124
  """
122
125
 
123
- pre_result = re.compile(self.regex)
124
-
125
- return [x for x in data if not pre_result.search(str(x))]
126
+ return [x for x in data if not self._compiled.search(str(x))]
126
127
 
127
128
  def get_matching_list(self, data: List[str]) -> List[str]:
128
129
  """
@@ -130,9 +131,7 @@ class RegexHelper:
130
131
  in the given data.
131
132
  """
132
133
 
133
- pre_result = re.compile(self.regex)
134
-
135
- return [x for x in data if pre_result.search(str(x))]
134
+ return [x for x in data if self._compiled.search(str(x))]
136
135
 
137
136
  def match(
138
137
  self,
@@ -157,12 +156,11 @@ class RegexHelper:
157
156
  """
158
157
 
159
158
  result = []
160
- to_match = re.compile(self.regex)
161
159
 
162
160
  if rematch:
163
- pre_result = to_match.findall(data)
161
+ pre_result = self._compiled.findall(data)
164
162
  else:
165
- pre_result = to_match.search(data)
163
+ pre_result = self._compiled.search(data)
166
164
 
167
165
  if return_match and pre_result:
168
166
  if rematch:
@@ -209,7 +207,7 @@ class RegexHelper:
209
207
  self.regex,
210
208
  replacement,
211
209
  data,
212
- occurences,
210
+ count=occurences,
213
211
  flags=re.MULTILINE if multiline else 0,
214
212
  )
215
213
  return data
@@ -222,4 +220,4 @@ class RegexHelper:
222
220
  :rtype: list
223
221
  """
224
222
 
225
- return re.split(self.regex, data)
223
+ return self._compiled.split(data)
@@ -150,25 +150,15 @@ class Nameservers:
150
150
  _ = ipaddress.ip_address(nameserver)
151
151
  result.append(nameserver)
152
152
  except ValueError:
153
- try:
154
- result.extend(
155
- [
156
- x.address
157
- for x in dns.resolver.Resolver().resolve(nameserver, "A")
158
- ]
159
- )
160
- except dns.exception.DNSException:
161
- pass
153
+ resolver = dns.resolver.get_default_resolver()
162
154
 
163
- try:
164
- result.extend(
165
- [
166
- x.address
167
- for x in dns.resolver.Resolver().resolve(nameserver, "AAAA")
168
- ]
169
- )
170
- except dns.exception.DNSException:
171
- pass
155
+ for record_type in ["A", "AAAA"]:
156
+ try:
157
+ result.extend(
158
+ [x.address for x in resolver.resolve(nameserver, record_type)]
159
+ )
160
+ except dns.exception.DNSException:
161
+ pass
172
162
 
173
163
  PyFunceble.facility.Logger.debug(
174
164
  "IP from nameserver (%r):\n%r", nameserver, result
@@ -203,7 +193,7 @@ class Nameservers:
203
193
  self.nameservers = []
204
194
 
205
195
  for nameserver in value:
206
- if self.protocol.lower() == "https":
196
+ if isinstance(self.protocol, str) and self.protocol.lower() == "https":
207
197
  if not nameserver.startswith("https://"):
208
198
  netloc = self.url2netloc.set_data_to_convert(
209
199
  nameserver
@@ -69,7 +69,6 @@ import dns.rdatatype
69
69
 
70
70
  import PyFunceble.facility
71
71
  import PyFunceble.storage
72
- from PyFunceble.helpers.list import ListHelper
73
72
  from PyFunceble.query.dns.nameserver import Nameservers
74
73
  from PyFunceble.query.record.dns import DNSQueryToolRecord
75
74
 
@@ -122,16 +121,16 @@ class DNSQueryTool:
122
121
  ) -> None:
123
122
  self.nameservers = Nameservers()
124
123
 
125
- if nameservers is not None:
126
- self.nameservers.set_nameservers(nameservers)
127
- else: # pragma: no cover ## I'm not playing with system resolver.
128
- self.nameservers.guess_and_set_nameservers()
129
-
130
124
  if preferred_protocol is not None:
131
125
  self.preferred_protocol = preferred_protocol
132
126
  else:
133
127
  self.guess_and_set_preferred_protocol()
134
128
 
129
+ if nameservers is not None:
130
+ self.nameservers.set_nameservers(nameservers)
131
+ else: # pragma: no cover ## I'm not playing with system resolver.
132
+ self.nameservers.guess_and_set_nameservers()
133
+
135
134
  if follow_nameserver_order is not None:
136
135
  self.follow_nameserver_order = follow_nameserver_order
137
136
  else:
@@ -345,6 +344,8 @@ class DNSQueryTool:
345
344
 
346
345
  self.nameservers.set_nameservers(value)
347
346
 
347
+ return self
348
+
348
349
  @property
349
350
  def follow_nameserver_order(self) -> bool:
350
351
  """
@@ -758,29 +759,54 @@ class DNSQueryTool:
758
759
  PyFunceble.facility.Logger.debug("Mixed data:\n%r", dataset)
759
760
  return dataset
760
761
 
761
- @ensure_subject_is_given
762
- @ignore_if_query_message_is_missing
763
- @update_lookup_record_response
764
- def tcp(
765
- self,
766
- ) -> Optional[List[str]]:
762
+ def _query_protocol(self, protocol: str) -> Optional[List[str]]:
767
763
  """
768
- Request the chosen record through the TCP protocol.
764
+ Given a protocol, we query the nameservers with or through it.
765
+
766
+ :param str protocol:
767
+ The protocol to use for the query.
768
+
769
+ It can be one of the following:
770
+ - "TCP"
771
+ - "UDP"
772
+ - "HTTPS"
773
+ - "TLS"
774
+ :return:
775
+ The result of the query, or an empty list if the query failed.
769
776
  """
770
777
 
771
- self.lookup_record.used_protocol = "TCP"
778
+ self.lookup_record.used_protocol = protocol.upper()
772
779
 
773
- result = []
780
+ if self.lookup_record.used_protocol not in self.SUPPORTED_PROTOCOL:
781
+ raise ValueError(
782
+ f"<protocol> ({self.lookup_record.used_protocol!r}) is unknown or "
783
+ f"unsupported (supported: {self.SUPPORTED_PROTOCOL!r})."
784
+ )
785
+
786
+ result = set()
774
787
 
775
788
  for nameserver, port in self._mix_order(
776
789
  self.nameservers.get_nameserver_ports()
777
790
  ).items():
778
791
  PyFunceble.facility.Logger.debug(
779
- "Started to query information of %r from %r", self.subject, nameserver
792
+ "Started to query information of %r from %r (%s)",
793
+ self.subject,
794
+ nameserver,
795
+ self.lookup_record.used_protocol,
780
796
  )
781
797
 
798
+ if self.lookup_record.used_protocol == "HTTPS" and port == 53:
799
+ # Default port for nameserver class is 53. So we ensure we
800
+ # overwrite with our own default.
801
+ port = 443
802
+
803
+ if self.lookup_record.used_protocol == "TLS" and port == 53:
804
+ # Default port for nameserver class is 53. So we ensure we
805
+ # overwrite with our own default.
806
+ port = 853
807
+
782
808
  try:
783
- response = dns.query.tcp(
809
+ response = getattr(dns.query, protocol.lower())(
784
810
  self.query_message,
785
811
  nameserver,
786
812
  port=port,
@@ -790,19 +816,18 @@ class DNSQueryTool:
790
816
  local_result = self._get_result_from_response(response)
791
817
 
792
818
  if local_result:
793
- result.extend(local_result)
819
+ result.update(local_result)
794
820
 
795
821
  self.lookup_record.nameserver = nameserver
796
822
  self.lookup_record.port = port
797
823
 
798
824
  PyFunceble.facility.Logger.debug(
799
- "Successfully queried information of %r from %r.",
825
+ "Successfully queried information of %r from %r. (%s)",
800
826
  self.subject,
801
827
  nameserver,
828
+ self.lookup_record.used_protocol,
802
829
  )
803
830
 
804
- if not self.trust_server: # pragma: no cover: Per case.
805
- break
806
831
  if self.trust_server: # pragma: no cover: Per case.
807
832
  break
808
833
  except (dns.exception.Timeout, socket.error):
@@ -820,87 +845,40 @@ class DNSQueryTool:
820
845
  break
821
846
 
822
847
  PyFunceble.facility.Logger.debug(
823
- "Unsuccessfully queried information of %r from %r. Sleeping %fs.",
848
+ "Unsuccessfully queried information of %r from %r (%s). Sleeping %fs.",
824
849
  self.subject,
825
850
  nameserver,
851
+ self.lookup_record.used_protocol,
826
852
  self.delay,
827
853
  )
828
854
 
829
855
  time.sleep(self.delay)
830
856
 
831
- return ListHelper(result).remove_duplicates().subject
857
+ return list(result)
832
858
 
833
859
  @ensure_subject_is_given
834
860
  @ignore_if_query_message_is_missing
835
861
  @update_lookup_record_response
836
- def udp(
862
+ def tcp(
837
863
  self,
838
864
  ) -> Optional[List[str]]:
839
865
  """
840
- Request the chosen record through the UTP protocol.
866
+ Request the chosen record through the TCP protocol.
841
867
  """
842
868
 
843
- self.lookup_record.used_protocol = "UDP"
869
+ return self._query_protocol("TCP")
844
870
 
845
- result = []
846
-
847
- for nameserver, port in self._mix_order(
848
- self.nameservers.get_nameserver_ports()
849
- ).items():
850
- PyFunceble.facility.Logger.debug(
851
- "Started to query information of %r from %r", self.subject, nameserver
852
- )
853
-
854
- try:
855
- response = dns.query.udp(
856
- self.query_message,
857
- nameserver,
858
- port=port,
859
- timeout=self.query_timeout,
860
- )
861
-
862
- local_result = self._get_result_from_response(response)
863
-
864
- if local_result:
865
- result.extend(local_result)
866
-
867
- self.lookup_record.nameserver = nameserver
868
- self.lookup_record.port = port
869
-
870
- PyFunceble.facility.Logger.debug(
871
- "Successfully queried information of %r from %r.",
872
- self.subject,
873
- nameserver,
874
- )
875
-
876
- if not self.trust_server: # pragma: no cover: Per case.
877
- break
878
- if self.trust_server: # pragma: no cover: Per case.
879
- break
880
- except (dns.exception.Timeout, socket.error):
881
- # Example: Resource temporarily unavailable.
882
- pass
883
- except dns.query.UnexpectedSource:
884
- # Example: got a response from XXX instead of XXX.
885
- pass
886
- except dns.query.BadResponse:
887
- # Example: A DNS query response does not respond to the question
888
- # asked.
889
- pass
890
- except ValueError:
891
- # Example: Input is malformed.
892
- break
893
-
894
- PyFunceble.facility.Logger.debug(
895
- "Unsuccessfully queried information of %r from %r. Sleeping %fs.",
896
- self.subject,
897
- nameserver,
898
- self.delay,
899
- )
900
-
901
- time.sleep(self.delay)
871
+ @ensure_subject_is_given
872
+ @ignore_if_query_message_is_missing
873
+ @update_lookup_record_response
874
+ def udp(
875
+ self,
876
+ ) -> Optional[List[str]]:
877
+ """
878
+ Request the chosen record through the UTP protocol.
879
+ """
902
880
 
903
- return ListHelper(result).remove_duplicates().subject
881
+ return self._query_protocol("UDP")
904
882
 
905
883
  @ensure_subject_is_given
906
884
  @ignore_if_query_message_is_missing
@@ -912,61 +890,7 @@ class DNSQueryTool:
912
890
  Request the chosen record through the https protocol.
913
891
  """
914
892
 
915
- self.lookup_record.used_protocol = "HTTPS"
916
-
917
- result = []
918
-
919
- for nameserver in self._mix_order(self.nameservers.get_nameservers()):
920
- PyFunceble.facility.Logger.debug(
921
- "Started to query information of %r from %r", self.subject, nameserver
922
- )
923
-
924
- try:
925
- response = dns.query.https(
926
- self.query_message, nameserver, timeout=self.query_timeout
927
- )
928
-
929
- local_result = self._get_result_from_response(response)
930
-
931
- if local_result:
932
- result.extend(local_result)
933
-
934
- self.lookup_record.nameserver = nameserver
935
-
936
- PyFunceble.facility.Logger.debug(
937
- "Successfully queried information of %r from %r.",
938
- self.subject,
939
- nameserver,
940
- )
941
-
942
- if not self.trust_server: # pragma: no cover: Per case.
943
- break
944
- if self.trust_server: # pragma: no cover: Per case.
945
- break
946
- except (dns.exception.Timeout, socket.error):
947
- # Example: Resource temporarily unavailable.
948
- pass
949
- except dns.query.UnexpectedSource:
950
- # Example: got a response from XXX instead of XXX.
951
- pass
952
- except dns.query.BadResponse:
953
- # Example: A DNS query response does not respond to the question
954
- # asked.
955
- pass
956
- except ValueError:
957
- # Example: Input is malformed.
958
- break
959
-
960
- PyFunceble.facility.Logger.debug(
961
- "Unsuccessfully queried information of %r from %r. Sleeping %fs.",
962
- self.subject,
963
- nameserver,
964
- self.delay,
965
- )
966
-
967
- time.sleep(self.delay)
968
-
969
- return ListHelper(result).remove_duplicates().subject
893
+ return self._query_protocol("HTTPS")
970
894
 
971
895
  @ensure_subject_is_given
972
896
  @ignore_if_query_message_is_missing
@@ -978,72 +902,7 @@ class DNSQueryTool:
978
902
  Request the chosen record through the TLS protocol.
979
903
  """
980
904
 
981
- self.lookup_record.used_protocol = "TLS"
982
-
983
- result = []
984
-
985
- for nameserver, port in self._mix_order(
986
- self.nameservers.get_nameserver_ports()
987
- ).items():
988
- PyFunceble.facility.Logger.debug(
989
- "Started to query information of %r from %r", self.subject, nameserver
990
- )
991
-
992
- if port == 53:
993
- # Default port for nameserver class is 53. So we ensure we
994
- # overwrite with our own default.
995
- port = 853
996
-
997
- try:
998
- response = dns.query.tls(
999
- self.query_message,
1000
- nameserver,
1001
- port=port,
1002
- timeout=self.query_timeout,
1003
- )
1004
-
1005
- local_result = self._get_result_from_response(response)
1006
-
1007
- if local_result:
1008
- result.extend(local_result)
1009
-
1010
- self.lookup_record.nameserver = nameserver
1011
- self.lookup_record.port = port
1012
-
1013
- PyFunceble.facility.Logger.debug(
1014
- "Successfully queried information of %r from %r.",
1015
- self.subject,
1016
- nameserver,
1017
- )
1018
-
1019
- if not self.trust_server: # pragma: no cover: Per case.
1020
- break
1021
- if self.trust_server: # pragma: no cover: Per case.
1022
- break
1023
- except (dns.exception.Timeout, socket.error):
1024
- # Example: Resource temporarily unavailable.
1025
- pass
1026
- except dns.query.UnexpectedSource:
1027
- # Example: got a response from XXX instead of XXX.
1028
- pass
1029
- except dns.query.BadResponse:
1030
- # Example: A DNS query response does not respond to the question
1031
- # asked.
1032
- pass
1033
- except ValueError:
1034
- # Example: Input is malformed.
1035
- break
1036
-
1037
- PyFunceble.facility.Logger.debug(
1038
- "Unsuccessfully queried information of %r from %r. Sleeping %fs.",
1039
- self.subject,
1040
- nameserver,
1041
- self.delay,
1042
- )
1043
-
1044
- time.sleep(self.delay)
1045
-
1046
- return ListHelper(result).remove_duplicates().subject
905
+ return self._query_protocol("TLS")
1047
906
 
1048
907
  def query(
1049
908
  self,