Skip to content

Commit b133361

Browse files
committed
Add connect_accepted_socket.
1 parent e7ff857 commit b133361

File tree

11 files changed

+188
-27
lines changed

11 files changed

+188
-27
lines changed

tests/test_tcp.py

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,47 @@
33
import socket
44
import unittest.mock
55
import uvloop
6+
import ssl
67
import sys
8+
import threading
79

810
from uvloop import _testbase as tb
911

1012

13+
class MyBaseProto(asyncio.Protocol):
14+
connected = None
15+
done = None
16+
17+
def __init__(self, loop=None):
18+
self.transport = None
19+
self.state = 'INITIAL'
20+
self.nbytes = 0
21+
if loop is not None:
22+
self.connected = asyncio.Future(loop=loop)
23+
self.done = asyncio.Future(loop=loop)
24+
25+
def connection_made(self, transport):
26+
self.transport = transport
27+
assert self.state == 'INITIAL', self.state
28+
self.state = 'CONNECTED'
29+
if self.connected:
30+
self.connected.set_result(None)
31+
32+
def data_received(self, data):
33+
assert self.state == 'CONNECTED', self.state
34+
self.nbytes += len(data)
35+
36+
def eof_received(self):
37+
assert self.state == 'CONNECTED', self.state
38+
self.state = 'EOF'
39+
40+
def connection_lost(self, exc):
41+
assert self.state in ('CONNECTED', 'EOF'), self.state
42+
self.state = 'CLOSED'
43+
if self.done:
44+
self.done.set_result(None)
45+
46+
1147
class _TestTCP:
1248
def test_create_server_1(self):
1349
if self.is_asyncio_loop() and sys.version_info[:3] == (3, 5, 2):
@@ -699,6 +735,62 @@ async def runner():
699735
srv.close()
700736
self.loop.run_until_complete(srv.wait_closed())
701737

738+
def test_connect_accepted_socket(self, server_ssl=None, client_ssl=None):
739+
loop = self.loop
740+
741+
class MyProto(MyBaseProto):
742+
743+
def connection_lost(self, exc):
744+
super().connection_lost(exc)
745+
loop.call_soon(loop.stop)
746+
747+
def data_received(self, data):
748+
super().data_received(data)
749+
self.transport.write(expected_response)
750+
751+
lsock = socket.socket()
752+
lsock.bind(('127.0.0.1', 0))
753+
lsock.listen(1)
754+
addr = lsock.getsockname()
755+
756+
message = b'test data'
757+
response = None
758+
expected_response = b'roger'
759+
760+
def client():
761+
nonlocal response
762+
try:
763+
csock = socket.socket()
764+
if client_ssl is not None:
765+
csock = client_ssl.wrap_socket(csock)
766+
csock.connect(addr)
767+
csock.sendall(message)
768+
response = csock.recv(99)
769+
csock.close()
770+
except Exception as exc:
771+
print(
772+
"Failure in client thread in test_connect_accepted_socket",
773+
exc)
774+
775+
thread = threading.Thread(target=client, daemon=True)
776+
thread.start()
777+
778+
conn, _ = lsock.accept()
779+
proto = MyProto(loop=loop)
780+
proto.loop = loop
781+
loop.create_task(
782+
loop.connect_accepted_socket(
783+
(lambda: proto), conn, ssl=server_ssl))
784+
loop.run_forever()
785+
conn.close()
786+
lsock.close()
787+
788+
thread.join(1)
789+
self.assertFalse(thread.is_alive())
790+
self.assertEqual(proto.state, 'CLOSED')
791+
self.assertEqual(proto.nbytes, len(message))
792+
self.assertEqual(response, expected_response)
793+
702794

703795
class Test_AIO_TCP(_TestTCP, tb.AIOTestCase):
704796
pass
@@ -864,7 +956,22 @@ def run(coro):
864956

865957

866958
class Test_UV_TCPSSL(_TestSSL, tb.UVTestCase):
867-
pass
959+
960+
def test_ssl_connect_accepted_socket(self):
961+
server_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
962+
server_context.load_cert_chain(self.ONLYCERT, self.ONLYKEY)
963+
if hasattr(server_context, 'check_hostname'):
964+
server_context.check_hostname = False
965+
server_context.verify_mode = ssl.CERT_NONE
966+
967+
client_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
968+
if hasattr(server_context, 'check_hostname'):
969+
client_context.check_hostname = False
970+
client_context.verify_mode = ssl.CERT_NONE
971+
972+
Test_UV_TCP.test_connect_accepted_socket(
973+
self, server_context, client_context)
974+
868975

869976

870977
class Test_AIO_TCPSSL(_TestSSL, tb.AIOTestCase):

uvloop/handles/handle.pxd

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ cdef class UVSocketHandle(UVHandle):
3939
cdef _new_socket(self)
4040
cdef inline _get_socket(self)
4141
cdef inline _attach_fileobj(self, object file)
42+
43+
cdef _open(self, int sockfd)

uvloop/handles/handle.pyx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,9 @@ cdef class UVSocketHandle(UVHandle):
274274
finally:
275275
UVHandle._close(self)
276276

277+
cdef _open(self, int sockfd):
278+
raise NotImplementedError
279+
277280

278281
cdef inline bint __ensure_handle_data(uv.uv_handle_t* handle,
279282
const char* handle_ctx):

uvloop/handles/pipe.pxd

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
cdef class UnixServer(UVStreamServer):
22

33
cdef bind(self, str path)
4-
cdef open(self, int sockfd)
54

65
@staticmethod
76
cdef UnixServer new(Loop loop, object protocol_factory, Server server,
@@ -14,7 +13,6 @@ cdef class UnixTransport(UVStream):
1413
cdef UnixTransport new(Loop loop, object protocol, Server server,
1514
object waiter)
1615

17-
cdef open(self, int sockfd)
1816
cdef connect(self, char* addr)
1917

2018

@@ -24,13 +22,9 @@ cdef class ReadUnixTransport(UVStream):
2422
cdef ReadUnixTransport new(Loop loop, object protocol, Server server,
2523
object waiter)
2624

27-
cdef open(self, int sockfd)
28-
2925

3026
cdef class WriteUnixTransport(UVStream):
3127

3228
@staticmethod
3329
cdef WriteUnixTransport new(Loop loop, object protocol, Server server,
3430
object waiter)
35-
36-
cdef open(self, int sockfd)

uvloop/handles/pipe.pyx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ cdef class UnixServer(UVStreamServer):
5050
cdef _new_socket(self):
5151
return __pipe_get_socket(<UVSocketHandle>self)
5252

53-
cdef open(self, int sockfd):
53+
cdef _open(self, int sockfd):
5454
self._ensure_alive()
5555
__pipe_open(<UVStream>self, sockfd)
5656
self._mark_as_open()
@@ -89,7 +89,7 @@ cdef class UnixTransport(UVStream):
8989
cdef _new_socket(self):
9090
return __pipe_get_socket(<UVSocketHandle>self)
9191

92-
cdef open(self, int sockfd):
92+
cdef _open(self, int sockfd):
9393
__pipe_open(<UVStream>self, sockfd)
9494

9595
cdef connect(self, char* addr):
@@ -113,7 +113,7 @@ cdef class ReadUnixTransport(UVStream):
113113
cdef _new_socket(self):
114114
return __pipe_get_socket(<UVSocketHandle>self)
115115

116-
cdef open(self, int sockfd):
116+
cdef _open(self, int sockfd):
117117
__pipe_open(<UVStream>self, sockfd)
118118

119119
def get_write_buffer_limits(self):
@@ -163,7 +163,7 @@ cdef class WriteUnixTransport(UVStream):
163163
cdef _new_socket(self):
164164
return __pipe_get_socket(<UVSocketHandle>self)
165165

166-
cdef open(self, int sockfd):
166+
cdef _open(self, int sockfd):
167167
__pipe_open(<UVStream>self, sockfd)
168168

169169
def pause_reading(self):

uvloop/handles/process.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ cdef class UVProcessTransport(UVProcess):
401401
self._stdin = WriteUnixTransport.new(
402402
self._loop, self.stdin_proto, None, waiter)
403403
self._init_futs.append(waiter)
404-
self._stdin.open(w)
404+
self._stdin._open(w)
405405
self._stdin._init_protocol()
406406
elif _stdin == subprocess_DEVNULL:
407407
io[0] = self._file_devnull()
@@ -430,7 +430,7 @@ cdef class UVProcessTransport(UVProcess):
430430
self._stdout = ReadUnixTransport.new(
431431
self._loop, self.stdout_proto, None, waiter)
432432
self._init_futs.append(waiter)
433-
self._stdout.open(r)
433+
self._stdout._open(r)
434434
self._stdout._init_protocol()
435435
elif _stdout == subprocess_DEVNULL:
436436
io[1] = self._file_devnull()
@@ -453,7 +453,7 @@ cdef class UVProcessTransport(UVProcess):
453453
self._stderr = ReadUnixTransport.new(
454454
self._loop, self.stderr_proto, None, waiter)
455455
self._init_futs.append(waiter)
456-
self._stderr.open(r)
456+
self._stderr._open(r)
457457
self._stderr._init_protocol()
458458
elif _stderr == subprocess_STDOUT:
459459
if io[1] is None:

uvloop/handles/tcp.pxd

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
cdef class TCPServer(UVStreamServer):
2-
cdef open(self, int sockfd)
32
cdef bind(self, system.sockaddr* addr, unsigned int flags=*)
43

54
@staticmethod
@@ -15,7 +14,6 @@ cdef class TCPTransport(UVStream):
1514
system.sockaddr_storage __sockname
1615

1716
cdef bind(self, system.sockaddr* addr, unsigned int flags=*)
18-
cdef open(self, int sockfd)
1917
cdef connect(self, system.sockaddr* addr)
2018

2119
@staticmethod

uvloop/handles/tcp.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ cdef class TCPServer(UVStreamServer):
6969
cdef _new_socket(self):
7070
return __tcp_get_socket(<UVSocketHandle>self)
7171

72-
cdef open(self, int sockfd):
72+
cdef _open(self, int sockfd):
7373
self._ensure_alive()
7474
try:
7575
__tcp_open(<UVStream>self, sockfd)
@@ -158,7 +158,7 @@ cdef class TCPTransport(UVStream):
158158
self._ensure_alive()
159159
__tcp_bind(<UVStream>self, addr, flags)
160160

161-
cdef open(self, int sockfd):
161+
cdef _open(self, int sockfd):
162162
self._ensure_alive()
163163
__tcp_open(<UVStream>self, sockfd)
164164

uvloop/handles/udp.pxd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ cdef class UDPTransport(UVBaseTransport):
1313
size_t addr_len)
1414

1515
cdef _bind(self, system.sockaddr* addr, bint reuse_addr)
16-
cdef _open(self, int family, int sockfd)
16+
cdef open(self, int family, int sockfd)
1717
cdef _set_broadcast(self, bint on)
1818

1919
cdef inline __receiving_started(self)

uvloop/handles/udp.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ cdef class UDPTransport(UVBaseTransport):
8686
memcpy(&self._address, addr, addr_len)
8787
self._address_set = 1
8888

89-
cdef _open(self, int family, int sockfd):
89+
cdef open(self, int family, int sockfd):
9090
if family in (uv.AF_INET, uv.AF_INET6):
9191
self._family = family
9292
else:

0 commit comments

Comments
 (0)