dns.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import struct
  2. import dns
  3. import dns.rdtypes.txtbase
  4. @dns.immutable.immutable
  5. class LongQuotedTXT(dns.rdtypes.txtbase.TXTBase):
  6. """
  7. A TXT record like RFC 1035, but
  8. - allows arbitrarily long tokens, and
  9. - all tokens must be quoted.
  10. """
  11. def __init__(self, rdclass, rdtype, strings):
  12. # Same as in parent class, but with max_length=None. Note that we are calling __init__ from the grandparent.
  13. super(dns.rdtypes.txtbase.TXTBase, self).__init__(rdclass, rdtype)
  14. self.strings = self._as_tuple(strings,
  15. lambda x: self._as_bytes(x, True, max_length=None))
  16. @classmethod
  17. def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True):
  18. strings = []
  19. for token in tok.get_remaining():
  20. token = token.unescape_to_bytes()
  21. # The 'if' below is always true in the current code, but we
  22. # are leaving this check in in case things change some day.
  23. if not token.is_quoted_string():
  24. raise dns.exception.SyntaxError("Content must be quoted.")
  25. strings.append(token.value)
  26. if len(strings) == 0:
  27. raise dns.exception.UnexpectedEnd
  28. return cls(rdclass, rdtype, strings)
  29. def _to_wire(self, file, compress=None, origin=None, canonicalize=False):
  30. for long_s in self.strings:
  31. for s in [long_s[i:i+255] for i in range(0, max(len(long_s), 1), 255)]:
  32. l = len(s)
  33. assert l < 256
  34. file.write(struct.pack('!B', l))
  35. file.write(s)