|
9 | 9 | import threading
|
10 | 10 | import weakref
|
11 | 11 |
|
| 12 | +from OpenSSL import SSL |
12 | 13 | from uvloop import _testbase as tb
|
13 | 14 |
|
14 | 15 |
|
@@ -1856,6 +1857,127 @@ async def run_main():
|
1856 | 1857 |
|
1857 | 1858 | self.loop.run_until_complete(run_main())
|
1858 | 1859 |
|
| 1860 | + def test_renegotiation(self): |
| 1861 | + if self.implementation == 'asyncio': |
| 1862 | + raise unittest.SkipTest('asyncio does not support renegotiation') |
| 1863 | + |
| 1864 | + CNT = 0 |
| 1865 | + TOTAL_CNT = 25 |
| 1866 | + |
| 1867 | + A_DATA = b'A' * 1024 * 1024 |
| 1868 | + B_DATA = b'B' * 1024 * 1024 |
| 1869 | + |
| 1870 | + sslctx = self._create_server_ssl_context(self.ONLYCERT, self.ONLYKEY) |
| 1871 | + sslctx = SSL.Context(SSL.SSLv23_METHOD) |
| 1872 | + if hasattr(SSL, 'OP_NO_SSLV2'): |
| 1873 | + sslctx.set_options(SSL.OP_NO_SSLV2) |
| 1874 | + sslctx.use_privatekey_file(self.ONLYKEY) |
| 1875 | + sslctx.use_certificate_chain_file(self.ONLYCERT) |
| 1876 | + client_sslctx = self._create_client_ssl_context() |
| 1877 | + |
| 1878 | + def server(sock): |
| 1879 | + conn = SSL.Connection(sslctx, sock) |
| 1880 | + conn.set_accept_state() |
| 1881 | + |
| 1882 | + data = b'' |
| 1883 | + while len(data) < len(A_DATA): |
| 1884 | + try: |
| 1885 | + chunk = conn.recv(len(A_DATA) - len(data)) |
| 1886 | + if not chunk: |
| 1887 | + break |
| 1888 | + data += chunk |
| 1889 | + except SSL.WantReadError: |
| 1890 | + pass |
| 1891 | + self.assertEqual(data, A_DATA) |
| 1892 | + conn.renegotiate() |
| 1893 | + if conn.renegotiate_pending(): |
| 1894 | + conn.send(b'OK') |
| 1895 | + else: |
| 1896 | + conn.send(b'ER') |
| 1897 | + |
| 1898 | + data = b'' |
| 1899 | + while len(data) < len(B_DATA): |
| 1900 | + try: |
| 1901 | + chunk = conn.recv(len(B_DATA) - len(data)) |
| 1902 | + if not chunk: |
| 1903 | + break |
| 1904 | + data += chunk |
| 1905 | + except SSL.WantReadError: |
| 1906 | + pass |
| 1907 | + self.assertEqual(data, B_DATA) |
| 1908 | + if conn.renegotiate_pending(): |
| 1909 | + conn.send(b'ERRO') |
| 1910 | + else: |
| 1911 | + conn.send(b'SPAM') |
| 1912 | + |
| 1913 | + conn.shutdown() |
| 1914 | + |
| 1915 | + async def client(addr): |
| 1916 | + extras = {} |
| 1917 | + if self.implementation != 'asyncio' or self.PY37: |
| 1918 | + extras = dict(ssl_handshake_timeout=10.0) |
| 1919 | + |
| 1920 | + reader, writer = await asyncio.open_connection( |
| 1921 | + *addr, |
| 1922 | + ssl=client_sslctx, |
| 1923 | + server_hostname='', |
| 1924 | + loop=self.loop, |
| 1925 | + **extras) |
| 1926 | + |
| 1927 | + writer.write(A_DATA) |
| 1928 | + self.assertEqual(await reader.readexactly(2), b'OK') |
| 1929 | + |
| 1930 | + writer.write(B_DATA) |
| 1931 | + self.assertEqual(await reader.readexactly(4), b'SPAM') |
| 1932 | + |
| 1933 | + nonlocal CNT |
| 1934 | + CNT += 1 |
| 1935 | + |
| 1936 | + writer.close() |
| 1937 | + |
| 1938 | + async def client_sock(addr): |
| 1939 | + sock = socket.socket() |
| 1940 | + sock.connect(addr) |
| 1941 | + reader, writer = await asyncio.open_connection( |
| 1942 | + sock=sock, |
| 1943 | + ssl=client_sslctx, |
| 1944 | + server_hostname='', |
| 1945 | + loop=self.loop) |
| 1946 | + |
| 1947 | + writer.write(A_DATA) |
| 1948 | + self.assertEqual(await reader.readexactly(2), b'OK') |
| 1949 | + |
| 1950 | + writer.write(B_DATA) |
| 1951 | + self.assertEqual(await reader.readexactly(4), b'SPAM') |
| 1952 | + |
| 1953 | + nonlocal CNT |
| 1954 | + CNT += 1 |
| 1955 | + |
| 1956 | + writer.close() |
| 1957 | + sock.close() |
| 1958 | + |
| 1959 | + def run(coro): |
| 1960 | + nonlocal CNT |
| 1961 | + CNT = 0 |
| 1962 | + |
| 1963 | + with self.tcp_server(server, |
| 1964 | + max_clients=TOTAL_CNT, |
| 1965 | + backlog=TOTAL_CNT) as srv: |
| 1966 | + tasks = [] |
| 1967 | + for _ in range(TOTAL_CNT): |
| 1968 | + tasks.append(coro(srv.addr)) |
| 1969 | + |
| 1970 | + self.loop.run_until_complete( |
| 1971 | + asyncio.gather(*tasks, loop=self.loop)) |
| 1972 | + |
| 1973 | + self.assertEqual(CNT, TOTAL_CNT) |
| 1974 | + |
| 1975 | + with self._silence_eof_received_warning(): |
| 1976 | + run(client) |
| 1977 | + |
| 1978 | + with self._silence_eof_received_warning(): |
| 1979 | + run(client_sock) |
| 1980 | + |
1859 | 1981 |
|
1860 | 1982 | class Test_UV_TCPSSL(_TestSSL, tb.UVTestCase):
|
1861 | 1983 | pass
|
|
0 commit comments