Index: twisted/names/test/test_client.py =================================================================== --- twisted/names/test/test_client.py (revision 23403) +++ twisted/names/test/test_client.py (working copy) @@ -305,3 +305,12 @@ d = client.lookupAllRecords(self.hostname) d.addCallback(self.checkResult, dns.ALL_RECORDS) return d + + def test_lookupNamingAuthorityPointer(self): + """ + See L{test_lookupAddress} + """ + d = client.lookupNamingAuthorityPointer(self.hostname) + d.addCallback(self.checkResult, dns.NAPTR) + return d + Index: twisted/names/test/test_dns.py =================================================================== --- twisted/names/test/test_dns.py (revision 23403) +++ twisted/names/test/test_dns.py (working copy) @@ -102,8 +102,36 @@ hk2 = hash(k2) self.assertEquals(hk1, hk2, "%s != %s (for %s)" % (hk1,hk2,k)) + def testCharstr(self): + for n in self.names: + # encode the name + f = StringIO() + dns.Charstr(n).encode(f) + # decode the name + f.seek(0, 0) + result = dns.Charstr() + result.decode(f) + self.assertEquals(result.string, n) + def testNAPTR(self): + naptrs = [(100, 10, "u", "sip+E2U","!^.*$!sip:information@domain.tld!",""), + (100, 50, "s", "http+I2L+I2C+I2R" ,"" ,"_http._tcp.gatech.edu")] + for (order,preference,flags,service,regexp,replacement) in naptrs: + rin = dns.Record_NAPTR(order,preference,flags,service,regexp,replacement) + e = StringIO() + rin.encode(e) + e.seek(0,0) + rout = dns.Record_NAPTR() + rout.decode(e) + self.assertEquals(rin.order, rout.order) + self.assertEquals(rin.preference, rout.preference) + self.assertEquals(rin.flags, rout.flags) + self.assertEquals(rin.service, rout.service) + self.assertEquals(rin.regexp, rout.regexp) + self.assertEquals(rin.replacement, rout.replacement) + self.assertEquals(rin.ttl, rout.ttl) + class MessageTestCase(unittest.TestCase): def testEmptyMessage(self): """ @@ -265,8 +293,9 @@ d = self.proto.query(('127.0.0.1', 21345), [dns.Query('foo')]) return self.assertFailure(d, CannotListenError) +if __name__ == '__main__': + unittest.main() - class TestTCPController(TestController): """ Pretend to be a DNS query processor for a DNSProtocol. Index: twisted/names/dns.py =================================================================== --- twisted/names/dns.py (revision 23403) +++ twisted/names/dns.py (working copy) @@ -208,22 +208,11 @@ """ Encode this Character string into the appropriate byte format. - @type strio: file @param strio: The byte representation of this Charstr + @type strio: file + @param strio: The byte representation of this Charstr will be written to this file. - - @type compDict: dict @param compDict: dictionary of Charstrs that have - already been encoded and whose addresses may be backreferenced by - this Charstr (for the purpose of reducing the message size). """ string = self.string - if compDict is not None: - if string in compDict: - strio.write( - struct.pack("!H", 0xc000 | compDict[string])) - return - else: - compDict[string] = strio.tell() + Message.headerSize - ind = len(string) strio.write(chr(ind)) strio.write(string) @@ -240,11 +229,10 @@ @raise EOFError: Raised when there are not enough bytes available from C{strio}. """ + self.string = '' - off = 0 l = ord(readPrecisely(strio, 1)) - if l != 0: - self.string = readPrecisely(strio, l) + self.string = readPrecisely(strio, l) def __eq__(self, other): @@ -1020,6 +1008,52 @@ class Record_NAPTR(tputil.FancyEqMixin, tputil.FancyStrMixin): + """ + The location of the server(s) for a specific protocol and domain. + + This is an experimental record type. + + @type order: C{int} + @ivar order: An integer specifying the order in which the NAPTR records + MUST be processed to ensure the correct ordering of rules. + Low numbers are processed before high numbers + + @type preference: C{int} + @ivar preference: An integer that specifies the order in which NAPTR + records with equal "order" values SHOULD be processed, low + numbers being processed before high numbers. + + @type flag: L{Charstr} + @ivar flag: A containing flags to control aspects of the + rewriting and interpretation of the fields in the record. Flags + are single characters from the set [A-Z0-9]. The case of the + alphabetic characters is not significant. + + At this time only four flags, "S", "A", "U", and "P", are defined. + + @type service: L{Charstr} + @ivar service: Specifies the service(s) available down this rewrite path. + It may also specify the particular protocol that is used to talk with a + service. A protocol MUST be specified if the flags field states + that the NAPTR is terminal. + + @type regexp: L{Charstr} + @ivar regexp: A STRING containing a substitution expression that is applied to + the original string held by the client in order to construct the + next domain name to lookup. + + @type replacement: L{Name} + @ivar replacement: The next NAME to query for NAPTR, SRV, or address records + depending on the value of the flags field. This MUST be a fully + qualified domain-name. + + @type ttl: C{int} + @ivar ttl: The maximum number of seconds which this record should be + cached. + + @see: U{http://www.faqs.org/rfcs/rfc2915.html} + """ + implements(IEncodable, IRecord) TYPE = NAPTR