OLD | NEW |
| (Empty) |
1 # -*- test-case-name: twisted.test.test_compat -*- | |
2 # | |
3 # Copyright (c) 2001-2007 Twisted Matrix Laboratories. | |
4 # See LICENSE for details. | |
5 | |
6 | |
7 """ | |
8 Compatibility module to provide backwards compatibility for useful Python | |
9 features. | |
10 | |
11 This is mainly for use of internal Twisted code. We encourage you to use | |
12 the latest version of Python directly from your code, if possible. | |
13 """ | |
14 | |
15 import sys, string, socket, struct | |
16 | |
17 def inet_pton(af, addr): | |
18 if af == socket.AF_INET: | |
19 return socket.inet_aton(addr) | |
20 elif af == getattr(socket, 'AF_INET6', 'AF_INET6'): | |
21 if [x for x in addr if x not in string.hexdigits + ':.']: | |
22 raise ValueError("Illegal characters: %r" % (''.join(x),)) | |
23 | |
24 parts = addr.split(':') | |
25 elided = parts.count('') | |
26 ipv4Component = '.' in parts[-1] | |
27 | |
28 if len(parts) > (8 - ipv4Component) or elided > 3: | |
29 raise ValueError("Syntactically invalid address") | |
30 | |
31 if elided == 3: | |
32 return '\x00' * 16 | |
33 | |
34 if elided: | |
35 zeros = ['0'] * (8 - len(parts) - ipv4Component + elided) | |
36 | |
37 if addr.startswith('::'): | |
38 parts[:2] = zeros | |
39 elif addr.endswith('::'): | |
40 parts[-2:] = zeros | |
41 else: | |
42 idx = parts.index('') | |
43 parts[idx:idx+1] = zeros | |
44 | |
45 if len(parts) != 8 - ipv4Component: | |
46 raise ValueError("Syntactically invalid address") | |
47 else: | |
48 if len(parts) != (8 - ipv4Component): | |
49 raise ValueError("Syntactically invalid address") | |
50 | |
51 if ipv4Component: | |
52 if parts[-1].count('.') != 3: | |
53 raise ValueError("Syntactically invalid address") | |
54 rawipv4 = socket.inet_aton(parts[-1]) | |
55 unpackedipv4 = struct.unpack('!HH', rawipv4) | |
56 parts[-1:] = [hex(x)[2:] for x in unpackedipv4] | |
57 | |
58 parts = [int(x, 16) for x in parts] | |
59 return struct.pack('!8H', *parts) | |
60 else: | |
61 raise socket.error(97, 'Address family not supported by protocol') | |
62 | |
63 def inet_ntop(af, addr): | |
64 if af == socket.AF_INET: | |
65 return socket.inet_ntoa(addr) | |
66 elif af == socket.AF_INET6: | |
67 if len(addr) != 16: | |
68 raise ValueError("address length incorrect") | |
69 parts = struct.unpack('!8H', addr) | |
70 curBase = bestBase = None | |
71 for i in range(8): | |
72 if not parts[i]: | |
73 if curBase is None: | |
74 curBase = i | |
75 curLen = 0 | |
76 curLen += 1 | |
77 else: | |
78 if curBase is not None: | |
79 if bestBase is None or curLen > bestLen: | |
80 bestBase = curBase | |
81 bestLen = curLen | |
82 curBase = None | |
83 if curBase is not None and (bestBase is None or curLen > bestLen): | |
84 bestBase = curBase | |
85 bestLen = curLen | |
86 parts = [hex(x)[2:] for x in parts] | |
87 if bestBase is not None: | |
88 parts[bestBase:bestBase + bestLen] = [''] | |
89 if parts[0] == '': | |
90 parts.insert(0, '') | |
91 if parts[-1] == '': | |
92 parts.insert(len(parts) - 1, '') | |
93 return ':'.join(parts) | |
94 else: | |
95 raise socket.error(97, 'Address family not supported by protocol') | |
96 | |
97 try: | |
98 socket.inet_pton(socket.AF_INET6, "::") | |
99 except (AttributeError, NameError, socket.error): | |
100 socket.inet_pton = inet_pton | |
101 socket.inet_ntop = inet_ntop | |
102 socket.AF_INET6 = 'AF_INET6' | |
103 | |
104 adict = dict | |
105 | |
106 # OpenSSL/__init__.py imports OpenSSL.tsafe. OpenSSL/tsafe.py imports | |
107 # threading. threading imports thread. All to make this stupid threadsafe | |
108 # version of its Connection class. We don't even care about threadsafe | |
109 # Connections. In the interest of not screwing over some crazy person | |
110 # calling into OpenSSL from another thread and trying to use Twisted's SSL | |
111 # support, we don't totally destroy OpenSSL.tsafe, but we will replace it | |
112 # with our own version which imports threading as late as possible. | |
113 | |
114 class tsafe(object): | |
115 class Connection: | |
116 """ | |
117 OpenSSL.tsafe.Connection, defined in such a way as to not blow. | |
118 """ | |
119 __module__ = 'OpenSSL.tsafe' | |
120 | |
121 def __init__(self, *args): | |
122 from OpenSSL import SSL as _ssl | |
123 self._ssl_conn = apply(_ssl.Connection, args) | |
124 from threading import _RLock | |
125 self._lock = _RLock() | |
126 | |
127 for f in ('get_context', 'pending', 'send', 'write', 'recv', | |
128 'read', 'renegotiate', 'bind', 'listen', 'connect', | |
129 'accept', 'setblocking', 'fileno', 'shutdown', | |
130 'close', 'get_cipher_list', 'getpeername', | |
131 'getsockname', 'getsockopt', 'setsockopt', | |
132 'makefile', 'get_app_data', 'set_app_data', | |
133 'state_string', 'sock_shutdown', | |
134 'get_peer_certificate', 'want_read', 'want_write', | |
135 'set_connect_state', 'set_accept_state', | |
136 'connect_ex', 'sendall'): | |
137 | |
138 exec """def %s(self, *args): | |
139 self._lock.acquire() | |
140 try: | |
141 return apply(self._ssl_conn.%s, args) | |
142 finally: | |
143 self._lock.release()\n""" % (f, f) | |
144 sys.modules['OpenSSL.tsafe'] = tsafe | |
145 | |
146 import operator | |
147 try: | |
148 operator.attrgetter | |
149 except AttributeError: | |
150 class attrgetter(object): | |
151 def __init__(self, name): | |
152 self.name = name | |
153 def __call__(self, obj): | |
154 return getattr(obj, self.name) | |
155 operator.attrgetter = attrgetter | |
156 | |
157 | |
158 try: | |
159 set = set | |
160 except NameError: | |
161 from sets import Set as set | |
162 | |
163 | |
164 try: | |
165 frozenset = frozenset | |
166 except NameError: | |
167 from sets import ImmutableSet as frozenset | |
168 | |
OLD | NEW |