| 1 | Index: twisted/names/test/test_client.py |
|---|
| 2 | =================================================================== |
|---|
| 3 | --- twisted/names/test/test_client.py (revision 23403) |
|---|
| 4 | +++ twisted/names/test/test_client.py (working copy) |
|---|
| 5 | @@ -305,3 +305,12 @@ |
|---|
| 6 | d = client.lookupAllRecords(self.hostname) |
|---|
| 7 | d.addCallback(self.checkResult, dns.ALL_RECORDS) |
|---|
| 8 | return d |
|---|
| 9 | + |
|---|
| 10 | + def test_lookupNamingAuthorityPointer(self): |
|---|
| 11 | + """ |
|---|
| 12 | + See L{test_lookupAddress} |
|---|
| 13 | + """ |
|---|
| 14 | + d = client.lookupNamingAuthorityPointer(self.hostname) |
|---|
| 15 | + d.addCallback(self.checkResult, dns.NAPTR) |
|---|
| 16 | + return d |
|---|
| 17 | + |
|---|
| 18 | Index: twisted/names/test/test_dns.py |
|---|
| 19 | =================================================================== |
|---|
| 20 | --- twisted/names/test/test_dns.py (revision 23403) |
|---|
| 21 | +++ twisted/names/test/test_dns.py (working copy) |
|---|
| 22 | @@ -102,8 +102,36 @@ |
|---|
| 23 | hk2 = hash(k2) |
|---|
| 24 | self.assertEquals(hk1, hk2, "%s != %s (for %s)" % (hk1,hk2,k)) |
|---|
| 25 | |
|---|
| 26 | + def testCharstr(self): |
|---|
| 27 | + for n in self.names: |
|---|
| 28 | + # encode the name |
|---|
| 29 | + f = StringIO() |
|---|
| 30 | + dns.Charstr(n).encode(f) |
|---|
| 31 | |
|---|
| 32 | + # decode the name |
|---|
| 33 | + f.seek(0, 0) |
|---|
| 34 | + result = dns.Charstr() |
|---|
| 35 | + result.decode(f) |
|---|
| 36 | + self.assertEquals(result.string, n) |
|---|
| 37 | |
|---|
| 38 | + def testNAPTR(self): |
|---|
| 39 | + naptrs = [(100, 10, "u", "sip+E2U","!^.*$!sip:information@domain.tld!",""), |
|---|
| 40 | + (100, 50, "s", "http+I2L+I2C+I2R" ,"" ,"_http._tcp.gatech.edu")] |
|---|
| 41 | + for (order,preference,flags,service,regexp,replacement) in naptrs: |
|---|
| 42 | + rin = dns.Record_NAPTR(order,preference,flags,service,regexp,replacement) |
|---|
| 43 | + e = StringIO() |
|---|
| 44 | + rin.encode(e) |
|---|
| 45 | + e.seek(0,0) |
|---|
| 46 | + rout = dns.Record_NAPTR() |
|---|
| 47 | + rout.decode(e) |
|---|
| 48 | + self.assertEquals(rin.order, rout.order) |
|---|
| 49 | + self.assertEquals(rin.preference, rout.preference) |
|---|
| 50 | + self.assertEquals(rin.flags, rout.flags) |
|---|
| 51 | + self.assertEquals(rin.service, rout.service) |
|---|
| 52 | + self.assertEquals(rin.regexp, rout.regexp) |
|---|
| 53 | + self.assertEquals(rin.replacement, rout.replacement) |
|---|
| 54 | + self.assertEquals(rin.ttl, rout.ttl) |
|---|
| 55 | + |
|---|
| 56 | class MessageTestCase(unittest.TestCase): |
|---|
| 57 | def testEmptyMessage(self): |
|---|
| 58 | """ |
|---|
| 59 | @@ -265,8 +293,9 @@ |
|---|
| 60 | d = self.proto.query(('127.0.0.1', 21345), [dns.Query('foo')]) |
|---|
| 61 | return self.assertFailure(d, CannotListenError) |
|---|
| 62 | |
|---|
| 63 | +if __name__ == '__main__': |
|---|
| 64 | + unittest.main() |
|---|
| 65 | |
|---|
| 66 | - |
|---|
| 67 | class TestTCPController(TestController): |
|---|
| 68 | """ |
|---|
| 69 | Pretend to be a DNS query processor for a DNSProtocol. |
|---|
| 70 | Index: twisted/names/dns.py |
|---|
| 71 | =================================================================== |
|---|
| 72 | --- twisted/names/dns.py (revision 23403) |
|---|
| 73 | +++ twisted/names/dns.py (working copy) |
|---|
| 74 | @@ -208,22 +208,11 @@ |
|---|
| 75 | """ |
|---|
| 76 | Encode this Character string into the appropriate byte format. |
|---|
| 77 | |
|---|
| 78 | - @type strio: file @param strio: The byte representation of this Charstr |
|---|
| 79 | + @type strio: file |
|---|
| 80 | + @param strio: The byte representation of this Charstr |
|---|
| 81 | will be written to this file. |
|---|
| 82 | - |
|---|
| 83 | - @type compDict: dict @param compDict: dictionary of Charstrs that have |
|---|
| 84 | - already been encoded and whose addresses may be backreferenced by |
|---|
| 85 | - this Charstr (for the purpose of reducing the message size). |
|---|
| 86 | """ |
|---|
| 87 | string = self.string |
|---|
| 88 | - if compDict is not None: |
|---|
| 89 | - if string in compDict: |
|---|
| 90 | - strio.write( |
|---|
| 91 | - struct.pack("!H", 0xc000 | compDict[string])) |
|---|
| 92 | - return |
|---|
| 93 | - else: |
|---|
| 94 | - compDict[string] = strio.tell() + Message.headerSize |
|---|
| 95 | - |
|---|
| 96 | ind = len(string) |
|---|
| 97 | strio.write(chr(ind)) |
|---|
| 98 | strio.write(string) |
|---|
| 99 | @@ -240,11 +229,10 @@ |
|---|
| 100 | @raise EOFError: Raised when there are not enough bytes available from |
|---|
| 101 | C{strio}. |
|---|
| 102 | """ |
|---|
| 103 | + |
|---|
| 104 | self.string = '' |
|---|
| 105 | - off = 0 |
|---|
| 106 | l = ord(readPrecisely(strio, 1)) |
|---|
| 107 | - if l != 0: |
|---|
| 108 | - self.string = readPrecisely(strio, l) |
|---|
| 109 | + self.string = readPrecisely(strio, l) |
|---|
| 110 | |
|---|
| 111 | |
|---|
| 112 | def __eq__(self, other): |
|---|
| 113 | @@ -1020,6 +1008,52 @@ |
|---|
| 114 | |
|---|
| 115 | |
|---|
| 116 | class Record_NAPTR(tputil.FancyEqMixin, tputil.FancyStrMixin): |
|---|
| 117 | + """ |
|---|
| 118 | + The location of the server(s) for a specific protocol and domain. |
|---|
| 119 | + |
|---|
| 120 | + This is an experimental record type. |
|---|
| 121 | + |
|---|
| 122 | + @type order: C{int} |
|---|
| 123 | + @ivar order: An integer specifying the order in which the NAPTR records |
|---|
| 124 | + MUST be processed to ensure the correct ordering of rules. |
|---|
| 125 | + Low numbers are processed before high numbers |
|---|
| 126 | + |
|---|
| 127 | + @type preference: C{int} |
|---|
| 128 | + @ivar preference: An integer that specifies the order in which NAPTR |
|---|
| 129 | + records with equal "order" values SHOULD be processed, low |
|---|
| 130 | + numbers being processed before high numbers. |
|---|
| 131 | + |
|---|
| 132 | + @type flag: L{Charstr} |
|---|
| 133 | + @ivar flag: A <character-string> containing flags to control aspects of the |
|---|
| 134 | + rewriting and interpretation of the fields in the record. Flags |
|---|
| 135 | + are single characters from the set [A-Z0-9]. The case of the |
|---|
| 136 | + alphabetic characters is not significant. |
|---|
| 137 | + |
|---|
| 138 | + At this time only four flags, "S", "A", "U", and "P", are defined. |
|---|
| 139 | + |
|---|
| 140 | + @type service: L{Charstr} |
|---|
| 141 | + @ivar service: Specifies the service(s) available down this rewrite path. |
|---|
| 142 | + It may also specify the particular protocol that is used to talk with a |
|---|
| 143 | + service. A protocol MUST be specified if the flags field states |
|---|
| 144 | + that the NAPTR is terminal. |
|---|
| 145 | + |
|---|
| 146 | + @type regexp: L{Charstr} |
|---|
| 147 | + @ivar regexp: A STRING containing a substitution expression that is applied to |
|---|
| 148 | + the original string held by the client in order to construct the |
|---|
| 149 | + next domain name to lookup. |
|---|
| 150 | + |
|---|
| 151 | + @type replacement: L{Name} |
|---|
| 152 | + @ivar replacement: The next NAME to query for NAPTR, SRV, or address records |
|---|
| 153 | + depending on the value of the flags field. This MUST be a fully |
|---|
| 154 | + qualified domain-name. |
|---|
| 155 | + |
|---|
| 156 | + @type ttl: C{int} |
|---|
| 157 | + @ivar ttl: The maximum number of seconds which this record should be |
|---|
| 158 | + cached. |
|---|
| 159 | + |
|---|
| 160 | + @see: U{http://www.faqs.org/rfcs/rfc2915.html} |
|---|
| 161 | + """ |
|---|
| 162 | + |
|---|
| 163 | implements(IEncodable, IRecord) |
|---|
| 164 | TYPE = NAPTR |
|---|
| 165 | |
|---|