Package qpid :: Package messaging :: Module transports
[frames] | no frames]

Source Code for Module qpid.messaging.transports

  1  # 
  2  # Licensed to the Apache Software Foundation (ASF) under one 
  3  # or more contributor license agreements.  See the NOTICE file 
  4  # distributed with this work for additional information 
  5  # regarding copyright ownership.  The ASF licenses this file 
  6  # to you under the Apache License, Version 2.0 (the 
  7  # "License"); you may not use this file except in compliance 
  8  # with the License.  You may obtain a copy of the License at 
  9  # 
 10  #   http://www.apache.org/licenses/LICENSE-2.0 
 11  # 
 12  # Unless required by applicable law or agreed to in writing, 
 13  # software distributed under the License is distributed on an 
 14  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 15  # KIND, either express or implied.  See the License for the 
 16  # specific language governing permissions and limitations 
 17  # under the License. 
 18  # 
 19   
 20  import socket 
 21  from qpid.util import connect 
 22   
 23  TRANSPORTS = {} 
 24   
25 -class SocketTransport:
26
27 - def __init__(self, conn, host, port):
28 self.socket = connect(host, port) 29 if conn.tcp_nodelay: 30 self.socket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
31
32 - def fileno(self):
33 return self.socket.fileno()
34
35 -class tcp(SocketTransport):
36
37 - def reading(self, reading):
38 return reading
39
40 - def writing(self, writing):
41 return writing
42
43 - def send(self, bytes):
44 return self.socket.send(bytes)
45
46 - def recv(self, n):
47 return self.socket.recv(n)
48
49 - def close(self):
50 self.socket.close()
51 52 TRANSPORTS["tcp"] = tcp 53 54 try: 55 from ssl import wrap_socket, SSLError, SSL_ERROR_WANT_READ, \ 56 SSL_ERROR_WANT_WRITE 57 except ImportError: 58 59 ## try the older python SSL api: 60 from socket import ssl 61
62 - class old_ssl(SocketTransport):
63 - def __init__(self, conn, host, port):
64 SocketTransport.__init__(self, conn, host, port) 65 # Bug (QPID-4337): this is the "old" version of python SSL. 66 # The private key is required. If a certificate is given, but no 67 # keyfile, assume the key is contained in the certificate 68 ssl_keyfile = conn.ssl_keyfile 69 ssl_certfile = conn.ssl_certfile 70 if ssl_certfile and not ssl_keyfile: 71 ssl_keyfile = ssl_certfile 72 self.ssl = ssl(self.socket, keyfile=ssl_keyfile, certfile=ssl_certfile) 73 self.socket.setblocking(1)
74
75 - def reading(self, reading):
76 return reading
77
78 - def writing(self, writing):
79 return writing
80
81 - def recv(self, n):
82 return self.ssl.read(n)
83
84 - def send(self, s):
85 return self.ssl.write(s)
86
87 - def close(self):
88 self.socket.close()
89 90 TRANSPORTS["ssl"] = old_ssl 91 TRANSPORTS["tcp+tls"] = old_ssl 92 93 else:
94 - class tls(SocketTransport):
95
96 - def __init__(self, conn, host, port):
97 SocketTransport.__init__(self, conn, host, port) 98 self.tls = wrap_socket(self.socket, keyfile=conn.ssl_keyfile, certfile=conn.ssl_certfile, ca_certs=conn.ssl_trustfile) 99 self.socket.setblocking(0) 100 self.state = None
101
102 - def reading(self, reading):
103 if self.state is None: 104 return reading 105 else: 106 return self.state == SSL_ERROR_WANT_READ
107
108 - def writing(self, writing):
109 if self.state is None: 110 return writing 111 else: 112 return self.state == SSL_ERROR_WANT_WRITE
113
114 - def send(self, bytes):
115 self._clear_state() 116 try: 117 return self.tls.write(bytes) 118 except SSLError, e: 119 if self._update_state(e.args[0]): 120 return 0 121 else: 122 raise
123
124 - def recv(self, n):
125 self._clear_state() 126 try: 127 return self.tls.read(n) 128 except SSLError, e: 129 if self._update_state(e.args[0]): 130 return None 131 else: 132 raise
133
134 - def _clear_state(self):
135 self.state = None
136
137 - def _update_state(self, code):
138 if code in (SSL_ERROR_WANT_READ, SSL_ERROR_WANT_WRITE): 139 self.state = code 140 return True 141 else: 142 return False
143
144 - def close(self):
145 self.socket.setblocking(1) 146 # this closes the underlying socket 147 self.tls.close()
148 149 TRANSPORTS["ssl"] = tls 150 TRANSPORTS["tcp+tls"] = tls 151