summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorBill Janssen <janssen@parc.com>2008-09-08 16:37:24 (GMT)
committerBill Janssen <janssen@parc.com>2008-09-08 16:37:24 (GMT)
commit61c001a93942e5afc23d607f84f0ff04d01fc4b4 (patch)
treee87d226a16337b9e2010aae0013500e1e591284a /Lib
parent996b9f38db931b322b0cd252857e1fb2ad92b4ee (diff)
downloadcpython-61c001a93942e5afc23d607f84f0ff04d01fc4b4.zip
cpython-61c001a93942e5afc23d607f84f0ff04d01fc4b4.tar.gz
cpython-61c001a93942e5afc23d607f84f0ff04d01fc4b4.tar.bz2
incorporate fixes from issue 3162; SSL doc patch
Diffstat (limited to 'Lib')
-rw-r--r--Lib/ssl.py44
-rw-r--r--Lib/test/test_ssl.py121
2 files changed, 160 insertions, 5 deletions
diff --git a/Lib/ssl.py b/Lib/ssl.py
index c9ee71a..8a799bc 100644
--- a/Lib/ssl.py
+++ b/Lib/ssl.py
@@ -91,10 +91,12 @@ class SSLSocket (socket):
suppress_ragged_eofs=True):
socket.__init__(self, _sock=sock._sock)
# the initializer for socket trashes the methods (tsk, tsk), so...
- self.send = lambda x, flags=0: SSLSocket.send(self, x, flags)
- self.recv = lambda x, flags=0: SSLSocket.recv(self, x, flags)
+ self.send = lambda data, flags=0: SSLSocket.send(self, data, flags)
self.sendto = lambda data, addr, flags=0: SSLSocket.sendto(self, data, addr, flags)
- self.recvfrom = lambda addr, buflen, flags: SSLSocket.recvfrom(self, addr, buflen, flags)
+ self.recv = lambda buflen=1024, flags=0: SSLSocket.recv(self, buflen, flags)
+ self.recvfrom = lambda addr, buflen=1024, flags=0: SSLSocket.recvfrom(self, addr, buflen, flags)
+ self.recv_into = lambda buffer, nbytes=None, flags=0: SSLSocket.recv_into(self, buffer, nbytes, flags)
+ self.recvfrom_into = lambda buffer, nbytes=None, flags=0: SSLSocket.recvfrom_into(self, buffer, nbytes, flags)
if certfile and not keyfile:
keyfile = certfile
@@ -221,6 +223,30 @@ class SSLSocket (socket):
else:
return socket.recv(self, buflen, flags)
+ def recv_into (self, buffer, nbytes=None, flags=0):
+ if buffer and (nbytes is None):
+ nbytes = len(buffer)
+ elif nbytes is None:
+ nbytes = 1024
+ if self._sslobj:
+ if flags != 0:
+ raise ValueError(
+ "non-zero flags not allowed in calls to recv_into() on %s" %
+ self.__class__)
+ while True:
+ try:
+ tmp_buffer = self.read(nbytes)
+ v = len(tmp_buffer)
+ buffer[:v] = tmp_buffer
+ return v
+ except SSLError as x:
+ if x.args[0] == SSL_ERROR_WANT_READ:
+ continue
+ else:
+ raise x
+ else:
+ return socket.recv_into(self, buffer, nbytes, flags)
+
def recvfrom (self, addr, buflen=1024, flags=0):
if self._sslobj:
raise ValueError("recvfrom not allowed on instances of %s" %
@@ -228,6 +254,13 @@ class SSLSocket (socket):
else:
return socket.recvfrom(self, addr, buflen, flags)
+ def recvfrom_into (self, buffer, nbytes=None, flags=0):
+ if self._sslobj:
+ raise ValueError("recvfrom_into not allowed on instances of %s" %
+ self.__class__)
+ else:
+ return socket.recvfrom_into(self, buffer, nbytes, flags)
+
def pending (self):
if self._sslobj:
return self._sslobj.pending()
@@ -295,8 +328,9 @@ class SSLSocket (socket):
def makefile(self, mode='r', bufsize=-1):
- """Ouch. Need to make and return a file-like object that
- works with the SSL connection."""
+ """Make and return a file-like object that
+ works with the SSL connection. Just use the code
+ from the socket module."""
self._makefile_refs += 1
return _fileobject(self, mode, bufsize)
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index 05a9b57..98681f4 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -1030,6 +1030,127 @@ else:
server.join()
+ def testAllRecvAndSendMethods(self):
+
+ if test_support.verbose:
+ sys.stdout.write("\n")
+
+ server = ThreadedEchoServer(CERTFILE,
+ certreqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1,
+ cacerts=CERTFILE,
+ chatty=True,
+ connectionchatty=False)
+ flag = threading.Event()
+ server.start(flag)
+ # wait for it to start
+ flag.wait()
+ # try to connect
+ try:
+ s = ssl.wrap_socket(socket.socket(),
+ server_side=False,
+ certfile=CERTFILE,
+ ca_certs=CERTFILE,
+ cert_reqs=ssl.CERT_NONE,
+ ssl_version=ssl.PROTOCOL_TLSv1)
+ s.connect((HOST, server.port))
+ except ssl.SSLError as x:
+ raise support.TestFailed("Unexpected SSL error: " + str(x))
+ except Exception as x:
+ raise support.TestFailed("Unexpected exception: " + str(x))
+ else:
+ # helper methods for standardising recv* method signatures
+ def _recv_into():
+ b = bytearray("\0"*100)
+ count = s.recv_into(b)
+ return b[:count]
+
+ def _recvfrom_into():
+ b = bytearray("\0"*100)
+ count, addr = s.recvfrom_into(b)
+ return b[:count]
+
+ # (name, method, whether to expect success, *args)
+ send_methods = [
+ ('send', s.send, True, []),
+ ('sendto', s.sendto, False, ["some.address"]),
+ ('sendall', s.sendall, True, []),
+ ]
+ recv_methods = [
+ ('recv', s.recv, True, []),
+ ('recvfrom', s.recvfrom, False, ["some.address"]),
+ ('recv_into', _recv_into, True, []),
+ ('recvfrom_into', _recvfrom_into, False, []),
+ ]
+ data_prefix = u"PREFIX_"
+
+ for meth_name, send_meth, expect_success, args in send_methods:
+ indata = data_prefix + meth_name
+ try:
+ send_meth(indata.encode('ASCII', 'strict'), *args)
+ outdata = s.read()
+ outdata = outdata.decode('ASCII', 'strict')
+ if outdata != indata.lower():
+ raise support.TestFailed(
+ "While sending with <<%s>> bad data "
+ "<<%r>> (%d) received; "
+ "expected <<%r>> (%d)\n" % (
+ meth_name, outdata[:20], len(outdata),
+ indata[:20], len(indata)
+ )
+ )
+ except ValueError as e:
+ if expect_success:
+ raise support.TestFailed(
+ "Failed to send with method <<%s>>; "
+ "expected to succeed.\n" % (meth_name,)
+ )
+ if not str(e).startswith(meth_name):
+ raise support.TestFailed(
+ "Method <<%s>> failed with unexpected "
+ "exception message: %s\n" % (
+ meth_name, e
+ )
+ )
+
+ for meth_name, recv_meth, expect_success, args in recv_methods:
+ indata = data_prefix + meth_name
+ try:
+ s.send(indata.encode('ASCII', 'strict'))
+ outdata = recv_meth(*args)
+ outdata = outdata.decode('ASCII', 'strict')
+ if outdata != indata.lower():
+ raise support.TestFailed(
+ "While receiving with <<%s>> bad data "
+ "<<%r>> (%d) received; "
+ "expected <<%r>> (%d)\n" % (
+ meth_name, outdata[:20], len(outdata),
+ indata[:20], len(indata)
+ )
+ )
+ except ValueError as e:
+ if expect_success:
+ raise support.TestFailed(
+ "Failed to receive with method <<%s>>; "
+ "expected to succeed.\n" % (meth_name,)
+ )
+ if not str(e).startswith(meth_name):
+ raise support.TestFailed(
+ "Method <<%s>> failed with unexpected "
+ "exception message: %s\n" % (
+ meth_name, e
+ )
+ )
+ # consume data
+ s.read()
+
+ s.write("over\n".encode("ASCII", "strict"))
+ s.close()
+ finally:
+ server.stop()
+ server.join()
+
+
def test_main(verbose=False):
if skip_expected:
raise test_support.TestSkipped("No SSL support")