Browse Source

flake8

main
nibrag 9 years ago
parent
commit
3c2af6206f
6 changed files with 135 additions and 72 deletions
  1. +28
    -18
      aiosocks/__init__.py
  2. +15
    -11
      aiosocks/connector.py
  3. +4
    -2
      aiosocks/constants.py
  4. +34
    -15
      aiosocks/protocols.py
  5. +9
    -3
      tests/test_connector.py
  6. +45
    -23
      tests/test_protocol.py

+ 28
- 18
aiosocks/__init__.py View File

@@ -1,26 +1,30 @@
import asyncio import asyncio
from .errors import *
from .helpers import *
from .errors import * # noqa
from .helpers import * # noqa
from .protocols import Socks4Protocol, Socks5Protocol from .protocols import Socks4Protocol, Socks5Protocol


__version__ = '0.1.2' __version__ = '0.1.2'


__all__ = ('Socks4Protocol', 'Socks5Protocol', 'Socks4Auth', __all__ = ('Socks4Protocol', 'Socks5Protocol', 'Socks4Auth',
'Socks5Auth', 'Socks4Addr', 'Socks5Addr', 'SocksError', 'Socks5Auth', 'Socks4Addr', 'Socks5Addr', 'SocksError',
'NoAcceptableAuthMethods', 'LoginAuthenticationFailed', 'SocksConnectionError',
'InvalidServerVersion', 'InvalidServerReply', 'create_connection')
'NoAcceptableAuthMethods', 'LoginAuthenticationFailed',
'SocksConnectionError', 'InvalidServerVersion',
'InvalidServerReply', 'create_connection')




async def create_connection(protocol_factory, proxy, proxy_auth, dst, *, remote_resolve=True,
loop=None, ssl=None, family=0, proto=0, flags=0, sock=None,
local_addr=None, server_hostname=None):

@asyncio.coroutine
def create_connection(protocol_factory, proxy, proxy_auth, dst, *,
remote_resolve=True, loop=None, ssl=None, family=0,
proto=0, flags=0, sock=None, local_addr=None,
server_hostname=None):
assert isinstance(proxy, SocksAddr), ( assert isinstance(proxy, SocksAddr), (
'proxy must be Socks4Addr() or Socks5Addr() tuple' 'proxy must be Socks4Addr() or Socks5Addr() tuple'
) )


assert proxy_auth is None or isinstance(proxy_auth, (Socks4Auth, Socks5Auth)), (
'proxy_auth must be None or Socks4Auth() or Socks5Auth() tuple', proxy_auth
assert proxy_auth is None or isinstance(proxy_auth,
(Socks4Auth, Socks5Auth)), (
'proxy_auth must be None or Socks4Auth() '
'or Socks5Auth() tuple', proxy_auth
) )
assert isinstance(dst, (tuple, list)) and len(dst) == 2, ( assert isinstance(dst, (tuple, list)) and len(dst) == 2, (
'invalid dst format, tuple("dst_host", dst_port))' 'invalid dst format, tuple("dst_host", dst_port))'
@@ -28,11 +32,15 @@ async def create_connection(protocol_factory, proxy, proxy_auth, dst, *, remote_


if (isinstance(proxy, Socks4Addr) and not if (isinstance(proxy, Socks4Addr) and not
(proxy_auth is None or isinstance(proxy_auth, Socks4Auth))): (proxy_auth is None or isinstance(proxy_auth, Socks4Auth))):
raise ValueError("proxy is Socks4Addr but proxy_auth is not Socks4Auth")
raise ValueError(
"proxy is Socks4Addr but proxy_auth is not Socks4Auth"
)


if (isinstance(proxy, Socks5Addr) and not if (isinstance(proxy, Socks5Addr) and not
(proxy_auth is None or isinstance(proxy_auth, Socks5Auth))): (proxy_auth is None or isinstance(proxy_auth, Socks5Auth))):
raise ValueError("proxy is Socks5Addr but proxy_auth is not Socks5Auth")
raise ValueError(
"proxy is Socks5Addr but proxy_auth is not Socks5Auth"
)


loop = loop or asyncio.get_event_loop() loop = loop or asyncio.get_event_loop()


@@ -47,16 +55,18 @@ async def create_connection(protocol_factory, proxy, proxy_auth, dst, *, remote_
remote_resolve=remote_resolve, loop=loop) remote_resolve=remote_resolve, loop=loop)


try: try:
transport, protocol = await loop.create_connection(
socks_factory, proxy.host, proxy.port, ssl=ssl, family=family, proto=proto,
flags=flags, sock=sock, local_addr=local_addr, server_hostname=server_hostname)
transport, protocol = yield from loop.create_connection(
socks_factory, proxy.host, proxy.port, ssl=ssl, family=family,
proto=proto, flags=flags, sock=sock, local_addr=local_addr,
server_hostname=server_hostname)
except OSError as exc: except OSError as exc:
raise SocksConnectionError('[Errno %s] Can not connect to proxy %s:%d [%s]' %
(exc.errno, proxy.host, proxy.port, exc.strerror)) from exc
raise SocksConnectionError(
'[Errno %s] Can not connect to proxy %s:%d [%s]' %
(exc.errno, proxy.host, proxy.port, exc.strerror)) from exc


# Wait until communication with proxy server is finished # Wait until communication with proxy server is finished
try: try:
await protocol.negotiate_done()
yield from protocol.negotiate_done()
except SocksError as exc: except SocksError as exc:
raise SocksError('Can not connect to %s:%s [%s]' % raise SocksError('Can not connect to %s:%s [%s]' %
(dst[0], dst[1], exc)) (dst[0], dst[1], exc))


+ 15
- 11
aiosocks/connector.py View File

@@ -10,8 +10,8 @@ __all__ = ('SocksConnector',)




class SocksConnector(aiohttp.TCPConnector): class SocksConnector(aiohttp.TCPConnector):
def __init__(self, proxy, proxy_auth=None, *, remote_resolve=True, **kwargs):
super().__init__(**kwargs)
def __init__(self, proxy, proxy_auth=None, *, remote_resolve=True, **kwgs):
super().__init__(**kwgs)


self._proxy = proxy self._proxy = proxy
self._proxy_auth = proxy_auth self._proxy_auth = proxy_auth
@@ -44,7 +44,8 @@ class SocksConnector(aiohttp.TCPConnector):
# It's aiohttp bug? Hot fix: # It's aiohttp bug? Hot fix:
try: try:
ipaddress.ip_address(self._proxy.host) ipaddress.ip_address(self._proxy.host)
proxy_hosts = await self._loop.getaddrinfo(self._proxy.host, self._proxy.port)
proxy_hosts = await self._loop.getaddrinfo(self._proxy.host,
self._proxy.port)
family, _, proto, _, address = proxy_hosts[0] family, _, proto, _, address = proxy_hosts[0]


proxy_hosts = ({'hostname': self._proxy.host, proxy_hosts = ({'hostname': self._proxy.host,
@@ -52,16 +53,19 @@ class SocksConnector(aiohttp.TCPConnector):
'family': family, 'proto': proto, 'family': family, 'proto': proto,
'flags': socket.AI_NUMERICHOST},) 'flags': socket.AI_NUMERICHOST},)
except ValueError: except ValueError:
proxy_hosts = await self._resolve_host(self._proxy.host, self._proxy.port)
proxy_hosts = await self._resolve_host(self._proxy.host,
self._proxy.port)


for hinfo in proxy_hosts: for hinfo in proxy_hosts:
try: try:
proxy = self._proxy.__class__(host=hinfo['host'], port=hinfo['port'])
proxy = self._proxy.__class__(host=hinfo['host'],
port=hinfo['port'])


transp, proto = await create_connection( transp, proto = await create_connection(
self._factory, proxy, self._proxy_auth, dst, loop=self._loop,
remote_resolve=self._remote_resolve, ssl=None, family=hinfo['family'],
proto=hinfo['proto'], flags=hinfo['flags'], local_addr=self._local_addr)
self._factory, proxy, self._proxy_auth, dst,
loop=self._loop, remote_resolve=self._remote_resolve,
ssl=None, family=hinfo['family'], proto=hinfo['proto'],
flags=hinfo['flags'], local_addr=self._local_addr)


return transp, proto return transp, proto
except (OSError, SocksError, SocksConnectionError) as e: except (OSError, SocksError, SocksConnectionError) as e:
@@ -72,6 +76,6 @@ class SocksConnector(aiohttp.TCPConnector):
if isinstance(exc, SocksError): if isinstance(exc, SocksError):
raise exc raise exc
else: else:
raise aiohttp.ClientOSError(exc.errno,
'Can not connect to %s:%s [%s]' %
(req.host, req.port, exc.strerror)) from exc
raise aiohttp.ClientOSError(
exc.errno, 'Can not connect to %s:%s [%s]' %
(req.host, req.port, exc.strerror)) from exc

+ 4
- 2
aiosocks/constants.py View File

@@ -18,8 +18,10 @@ SOCKS5_ATYP_IPv6 = 0x04


SOCKS4_ERRORS = { SOCKS4_ERRORS = {
0x5B: 'Request rejected or failed', 0x5B: 'Request rejected or failed',
0x5C: 'Request rejected because SOCKS server cannot connect to identd on the client',
0x5D: 'Request rejected because the client program and identd report different user-ids'
0x5C: 'Request rejected because SOCKS server '
'cannot connect to identd on the client',
0x5D: 'Request rejected because the client program '
'and identd report different user-ids'
} }


SOCKS5_ERRORS = { SOCKS5_ERRORS = {


+ 34
- 15
aiosocks/protocols.py View File

@@ -5,13 +5,15 @@ from . import constants as c
from .helpers import ( from .helpers import (
Socks4Addr, Socks5Addr, Socks5Auth, Socks4Auth Socks4Addr, Socks5Addr, Socks5Auth, Socks4Auth
) )
from .errors import *
from .errors import * # noqa




class BaseSocksProtocol(asyncio.StreamReaderProtocol): class BaseSocksProtocol(asyncio.StreamReaderProtocol):
def __init__(self, proxy, proxy_auth, dst, remote_resolve=True, loop=None): def __init__(self, proxy, proxy_auth, dst, remote_resolve=True, loop=None):
if not isinstance(dst, (tuple, list)) or len(dst) != 2: if not isinstance(dst, (tuple, list)) or len(dst) != 2:
raise ValueError('Invalid dst format, tuple("dst_host", dst_port))')
raise ValueError(
'Invalid dst format, tuple("dst_host", dst_port))'
)


self._proxy = proxy self._proxy = proxy
self._auth = proxy_auth self._auth = proxy_auth
@@ -53,9 +55,10 @@ class BaseSocksProtocol(asyncio.StreamReaderProtocol):
return await self._stream_reader.read(n) return await self._stream_reader.read(n)


async def _get_dst_addr(self): async def _get_dst_addr(self):
infos = await self._loop.getaddrinfo(self._dst_host, self._dst_port,
family=socket.AF_UNSPEC, type=socket.SOCK_STREAM,
proto=socket.IPPROTO_TCP, flags=socket.AI_ADDRCONFIG)
infos = await self._loop.getaddrinfo(
self._dst_host, self._dst_port, family=socket.AF_UNSPEC,
type=socket.SOCK_STREAM, proto=socket.IPPROTO_TCP,
flags=socket.AI_ADDRCONFIG)
if not infos: if not infos:
raise OSError('getaddrinfo() returned empty list') raise OSError('getaddrinfo() returned empty list')
return infos[0][0], infos[0][4][0] return infos[0][0], infos[0][4][0]
@@ -94,7 +97,8 @@ class Socks4Protocol(BaseSocksProtocol):
host_bytes = socket.inet_aton(host) host_bytes = socket.inet_aton(host)


# build and send connect command # build and send connect command
req = [c.SOCKS_VER4, cmd, port_bytes, host_bytes, self._auth.login, c.NULL]
req = [c.SOCKS_VER4, cmd, port_bytes,
host_bytes, self._auth.login, c.NULL]
if include_hostname: if include_hostname:
req += [self._dst_host.encode('idna'), c.NULL] req += [self._dst_host.encode('idna'), c.NULL]


@@ -136,7 +140,9 @@ class Socks5Protocol(BaseSocksProtocol):
resp = await self.read_response(3) resp = await self.read_response(3)


if resp[0] != c.SOCKS_VER5: if resp[0] != c.SOCKS_VER5:
raise InvalidServerVersion('SOCKS5 proxy server sent invalid version')
raise InvalidServerVersion(
'SOCKS5 proxy server sent invalid version'
)
if resp[1] != c.SOCKS5_GRANTED: if resp[1] != c.SOCKS5_GRANTED:
error = c.SOCKS5_ERRORS.get(resp[1], 'Unknown error') error = c.SOCKS5_ERRORS.get(resp[1], 'Unknown error')
raise SocksError('[Errno {0:#04x}]: {1}'.format(resp[1], error)) raise SocksError('[Errno {0:#04x}]: {1}'.format(resp[1], error))
@@ -148,7 +154,8 @@ class Socks5Protocol(BaseSocksProtocol):
async def authenticate(self): async def authenticate(self):
# send available auth methods # send available auth methods
if self._auth.login and self._auth.password: if self._auth.login and self._auth.password:
req = [c.SOCKS_VER5, 0x02, c.SOCKS5_AUTH_ANONYMOUS, c.SOCKS5_AUTH_UNAME_PWD]
req = [c.SOCKS_VER5, 0x02,
c.SOCKS5_AUTH_ANONYMOUS, c.SOCKS5_AUTH_UNAME_PWD]
else: else:
req = [c.SOCKS_VER5, 0x01, c.SOCKS5_AUTH_ANONYMOUS] req = [c.SOCKS_VER5, 0x01, c.SOCKS5_AUTH_ANONYMOUS]


@@ -158,7 +165,9 @@ class Socks5Protocol(BaseSocksProtocol):
chosen_auth = await self.read_response(2) chosen_auth = await self.read_response(2)


if chosen_auth[0] != c.SOCKS_VER5: if chosen_auth[0] != c.SOCKS_VER5:
raise InvalidServerVersion('SOCKS5 proxy server sent invalid version')
raise InvalidServerVersion(
'SOCKS5 proxy server sent invalid version'
)


if chosen_auth[1] == c.SOCKS5_AUTH_UNAME_PWD: if chosen_auth[1] == c.SOCKS5_AUTH_UNAME_PWD:
req = [0x01, chr(len(self._auth.login)).encode(), self._auth.login, req = [0x01, chr(len(self._auth.login)).encode(), self._auth.login,
@@ -167,18 +176,27 @@ class Socks5Protocol(BaseSocksProtocol):


auth_status = await self.read_response(2) auth_status = await self.read_response(2)
if auth_status[0] != 0x01: if auth_status[0] != 0x01:
raise InvalidServerReply('SOCKS5 proxy server sent invalid data')
raise InvalidServerReply(
'SOCKS5 proxy server sent invalid data'
)
if auth_status[1] != c.SOCKS5_GRANTED: if auth_status[1] != c.SOCKS5_GRANTED:
raise LoginAuthenticationFailed('SOCKS5 authentication failed')
raise LoginAuthenticationFailed(
"SOCKS5 authentication failed"
)
# offered auth methods rejected # offered auth methods rejected
elif chosen_auth[1] != c.SOCKS5_AUTH_ANONYMOUS: elif chosen_auth[1] != c.SOCKS5_AUTH_ANONYMOUS:
if chosen_auth[1] == c.SOCKS5_AUTH_NO_ACCEPTABLE_METHODS: if chosen_auth[1] == c.SOCKS5_AUTH_NO_ACCEPTABLE_METHODS:
raise NoAcceptableAuthMethods('All offered SOCKS5 authentication methods were rejected')
raise NoAcceptableAuthMethods(
'All offered SOCKS5 authentication methods were rejected'
)
else: else:
raise InvalidServerReply('SOCKS5 proxy server sent invalid data')
raise InvalidServerReply(
'SOCKS5 proxy server sent invalid data'
)


async def write_address(self, host, port): async def write_address(self, host, port):
family_to_byte = {socket.AF_INET: c.SOCKS5_ATYP_IPv4, socket.AF_INET6: c.SOCKS5_ATYP_IPv6}
family_to_byte = {socket.AF_INET: c.SOCKS5_ATYP_IPv4,
socket.AF_INET6: c.SOCKS5_ATYP_IPv6}
port_bytes = struct.pack('>H', port) port_bytes = struct.pack('>H', port)


# if the given destination address is an IP address, we will # if the given destination address is an IP address, we will
@@ -195,7 +213,8 @@ class Socks5Protocol(BaseSocksProtocol):
# it's not an IP number, so it's probably a DNS name. # it's not an IP number, so it's probably a DNS name.
if self._remote_resolve: if self._remote_resolve:
host_bytes = host.encode('idna') host_bytes = host.encode('idna')
req = [c.SOCKS5_ATYP_DOMAIN, chr(len(host_bytes)).encode(), host_bytes, port_bytes]
req = [c.SOCKS5_ATYP_DOMAIN, chr(len(host_bytes)).encode(),
host_bytes, port_bytes]
else: else:
family, host_bytes = await self._get_dst_addr() family, host_bytes = await self._get_dst_addr()
host_bytes = socket.inet_pton(family, host_bytes) host_bytes = socket.inet_pton(family, host_bytes)


+ 9
- 3
tests/test_connector.py View File

@@ -41,7 +41,9 @@ class TestSocksConnector(unittest.TestCase):


self.assertTrue(loop_mock.getaddrinfo.is_called) self.assertTrue(loop_mock.getaddrinfo.is_called)
self.assertIs(conn._transport, tr) self.assertIs(conn._transport, tr)
self.assertTrue(isinstance(conn._protocol, aiohttp.parsers.StreamProtocol))
self.assertTrue(
isinstance(conn._protocol, aiohttp.parsers.StreamProtocol)
)


conn.close() conn.close()


@@ -63,7 +65,9 @@ class TestSocksConnector(unittest.TestCase):
self.assertTrue(connector._resolve_host.is_called) self.assertTrue(connector._resolve_host.is_called)
self.assertEqual(connector._resolve_host.call_count, 1) self.assertEqual(connector._resolve_host.call_count, 1)
self.assertIs(conn._transport, tr) self.assertIs(conn._transport, tr)
self.assertTrue(isinstance(conn._protocol, aiohttp.parsers.StreamProtocol))
self.assertTrue(
isinstance(conn._protocol, aiohttp.parsers.StreamProtocol)
)


conn.close() conn.close()


@@ -85,7 +89,9 @@ class TestSocksConnector(unittest.TestCase):
self.assertTrue(connector._resolve_host.is_called) self.assertTrue(connector._resolve_host.is_called)
self.assertEqual(connector._resolve_host.call_count, 2) self.assertEqual(connector._resolve_host.call_count, 2)
self.assertIs(conn._transport, tr) self.assertIs(conn._transport, tr)
self.assertTrue(isinstance(conn._protocol, aiohttp.parsers.StreamProtocol))
self.assertTrue(
isinstance(conn._protocol, aiohttp.parsers.StreamProtocol)
)


conn.close() conn.close()




+ 45
- 23
tests/test_protocol.py View File

@@ -67,7 +67,8 @@ class TestBaseSocksProtocol(unittest.TestCase):
BaseSocksProtocol(None, None, ('python.org',), loop=self.loop) BaseSocksProtocol(None, None, ('python.org',), loop=self.loop)


def test_write_request(self): def test_write_request(self):
proto = BaseSocksProtocol(None, None, ('python.org', 80), loop=self.loop)
proto = BaseSocksProtocol(None, None, ('python.org', 80),
loop=self.loop)
proto._transport = mock.Mock() proto._transport = mock.Mock()


proto.write_request([b'\x00', b'\x01\x02', 0x03]) proto.write_request([b'\x00', b'\x01\x02', 0x03])
@@ -97,10 +98,12 @@ class TestSocks4Protocol(unittest.TestCase):
aiosocks.Socks4Protocol(None, auth, dst, loop=self.loop) aiosocks.Socks4Protocol(None, auth, dst, loop=self.loop)


with self.assertRaises(ValueError): with self.assertRaises(ValueError):
aiosocks.Socks4Protocol(aiosocks.Socks5Addr('host'), auth, dst, loop=self.loop)
aiosocks.Socks4Protocol(aiosocks.Socks5Addr('host'), auth, dst,
loop=self.loop)


with self.assertRaises(ValueError): with self.assertRaises(ValueError):
aiosocks.Socks4Protocol(addr, aiosocks.Socks5Auth('l', 'p'), dst, loop=self.loop)
aiosocks.Socks4Protocol(addr, aiosocks.Socks5Auth('l', 'p'), dst,
loop=self.loop)


aiosocks.Socks4Protocol(addr, None, dst, loop=self.loop) aiosocks.Socks4Protocol(addr, None, dst, loop=self.loop)
aiosocks.Socks4Protocol(addr, auth, dst, loop=self.loop) aiosocks.Socks4Protocol(addr, auth, dst, loop=self.loop)
@@ -119,7 +122,8 @@ class TestSocks4Protocol(unittest.TestCase):
) )


# dst = domain, remote resolve = false # dst = domain, remote resolve = false
proto = make_socks4(self.loop, dst=('python.org', 80), rr=False, r=resp)
proto = make_socks4(self.loop, dst=('python.org', 80),
rr=False, r=resp)


req = proto.socks_request(c.SOCKS_CMD_CONNECT) req = proto.socks_request(c.SOCKS_CMD_CONNECT)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)
@@ -138,7 +142,8 @@ class TestSocks4Protocol(unittest.TestCase):
) )


# dst = ip, remote resolve = false # dst = ip, remote resolve = false
proto = make_socks4(self.loop, dst=('127.0.0.1', 8800), rr=False, r=resp)
proto = make_socks4(self.loop, dst=('127.0.0.1', 8800),
rr=False, r=resp)
req = proto.socks_request(c.SOCKS_CMD_CONNECT) req = proto.socks_request(c.SOCKS_CMD_CONNECT)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


@@ -147,8 +152,8 @@ class TestSocks4Protocol(unittest.TestCase):
) )


# dst = domain, without user # dst = domain, without user
proto = make_socks4(
self.loop, auth=aiosocks.Socks4Auth(''), dst=('python.org', 80), r=resp)
proto = make_socks4(self.loop, auth=aiosocks.Socks4Auth(''),
dst=('python.org', 80), r=resp)
req = proto.socks_request(c.SOCKS_CMD_CONNECT) req = proto.socks_request(c.SOCKS_CMD_CONNECT)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


@@ -157,8 +162,8 @@ class TestSocks4Protocol(unittest.TestCase):
) )


# dst = ip, without user # dst = ip, without user
proto = make_socks4(
self.loop, auth=aiosocks.Socks4Auth(''), dst=('127.0.0.1', 8800), r=resp)
proto = make_socks4(self.loop, auth=aiosocks.Socks4Auth(''),
dst=('127.0.0.1', 8800), r=resp)
req = proto.socks_request(c.SOCKS_CMD_CONNECT) req = proto.socks_request(c.SOCKS_CMD_CONNECT)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


@@ -226,10 +231,12 @@ class TestSocks5Protocol(unittest.TestCase):
aiosocks.Socks5Protocol(None, auth, dst, loop=self.loop) aiosocks.Socks5Protocol(None, auth, dst, loop=self.loop)


with self.assertRaises(ValueError): with self.assertRaises(ValueError):
aiosocks.Socks5Protocol(aiosocks.Socks4Addr('host'), auth, dst, loop=self.loop)
aiosocks.Socks5Protocol(aiosocks.Socks4Addr('host'),
auth, dst, loop=self.loop)


with self.assertRaises(ValueError): with self.assertRaises(ValueError):
aiosocks.Socks5Protocol(addr, aiosocks.Socks4Auth('l'), dst, loop=self.loop)
aiosocks.Socks5Protocol(addr, aiosocks.Socks4Auth('l'),
dst, loop=self.loop)


aiosocks.Socks5Protocol(addr, None, dst, loop=self.loop) aiosocks.Socks5Protocol(addr, None, dst, loop=self.loop)
aiosocks.Socks5Protocol(addr, auth, dst, loop=self.loop) aiosocks.Socks5Protocol(addr, auth, dst, loop=self.loop)
@@ -264,8 +271,10 @@ class TestSocks5Protocol(unittest.TestCase):
proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x01\x00',)) proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x01\x00',))
req = proto.authenticate() req = proto.authenticate()
self.loop.run_until_complete(req) self.loop.run_until_complete(req)
proto._transport.write.assert_has_calls(
[mock.call(b'\x05\x02\x00\x02'), mock.call(b'\x01\x04user\x03pwd')])
proto._transport.write.assert_has_calls([
mock.call(b'\x05\x02\x00\x02'),
mock.call(b'\x01\x04user\x03pwd')
])


# invalid reply # invalid reply
proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x00\x00',)) proto = make_socks5(self.loop, r=(b'\x05\x02', b'\x00\x00',))
@@ -289,7 +298,8 @@ class TestSocks5Protocol(unittest.TestCase):


# ipv6 # ipv6
proto = make_socks5(self.loop) proto = make_socks5(self.loop)
req = proto.write_address('2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d', 80)
req = proto.write_address(
'2001:0db8:11a3:09d7:1f34:8a2e:07a0:765d', 80)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


proto._transport.write.assert_called_with( proto._transport.write.assert_called_with(
@@ -311,22 +321,29 @@ class TestSocks5Protocol(unittest.TestCase):


def test_read_address(self): def test_read_address(self):
# ipv4 # ipv4
proto = make_socks5(self.loop, r=[b'\x01', b'\x7f\x00\x00\x01', b'\x00P'])
proto = make_socks5(
self.loop, r=[b'\x01', b'\x7f\x00\x00\x01', b'\x00P'])
req = asyncio.ensure_future(proto.read_address(), loop=self.loop) req = asyncio.ensure_future(proto.read_address(), loop=self.loop)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


self.assertEqual(req.result(), ('127.0.0.1', 80)) self.assertEqual(req.result(), ('127.0.0.1', 80))


# ipv6 # ipv6
proto = make_socks5(
self.loop, r=[b'\x04', b' \x01\r\xb8\x11\xa3\t\xd7\x1f4\x8a.\x07\xa0v]', b'\x00P'])
resp = [
b'\x04',
b' \x01\r\xb8\x11\xa3\t\xd7\x1f4\x8a.\x07\xa0v]',
b'\x00P'
]
proto = make_socks5(self.loop, r=resp)
req = asyncio.ensure_future(proto.read_address(), loop=self.loop) req = asyncio.ensure_future(proto.read_address(), loop=self.loop)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


self.assertEqual(req.result(), ('2001:db8:11a3:9d7:1f34:8a2e:7a0:765d', 80))
self.assertEqual(
req.result(), ('2001:db8:11a3:9d7:1f34:8a2e:7a0:765d', 80))


# domain # domain
proto = make_socks5(self.loop, r=[b'\x03', b'\n', b'python.org', b'\x00P'])
proto = make_socks5(
self.loop, r=[b'\x03', b'\n', b'python.org', b'\x00P'])
req = asyncio.ensure_future(proto.read_address(), loop=self.loop) req = asyncio.ensure_future(proto.read_address(), loop=self.loop)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


@@ -345,7 +362,8 @@ class TestSocks5Protocol(unittest.TestCase):
with self.assertRaises(aiosocks.SocksError) as ct: with self.assertRaises(aiosocks.SocksError) as ct:
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


self.assertTrue('Connection not allowed by ruleset' in str(ct.exception))
self.assertTrue(
'Connection not allowed by ruleset' in str(ct.exception))


# socks unknown error # socks unknown error
proto = make_socks5(self.loop, r=[b'\x05\x00', b'\x05\xFF\x00']) proto = make_socks5(self.loop, r=[b'\x05\x00', b'\x05\xFF\x00'])
@@ -356,9 +374,13 @@ class TestSocks5Protocol(unittest.TestCase):
self.assertTrue('Unknown error' in str(ct.exception)) self.assertTrue('Unknown error' in str(ct.exception))


# cmd granted # cmd granted
proto = make_socks5(
self.loop, r=[b'\x05\x00', b'\x05\x00\x00', b'\x01', b'\x7f\x00\x00\x01', b'\x00P'])
req = asyncio.ensure_future(proto.socks_request(c.SOCKS_CMD_CONNECT), loop=self.loop)
resp = [b'\x05\x00',
b'\x05\x00\x00',
b'\x01', b'\x7f\x00\x00\x01',
b'\x00P']
proto = make_socks5(self.loop, r=resp)
req = asyncio.ensure_future(proto.socks_request(c.SOCKS_CMD_CONNECT),
loop=self.loop)
self.loop.run_until_complete(req) self.loop.run_until_complete(req)


self.assertEqual(req.result(), (('python.org', 80), ('127.0.0.1', 80))) self.assertEqual(req.result(), (('python.org', 80), ('127.0.0.1', 80)))


Loading…
Cancel
Save