123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- <?php
- use LeProxy\LeProxy\ConnectorFactory;
- class ConnectorFactoryTest extends PHPUnit_Framework_TestCase
- {
- public function testCoerceProxyUri()
- {
- $uris = array(
- 'host' => 'http://host:8080',
- 'host:1234' => 'http://host:1234',
- 'socks://host' => 'socks4://host:8080',
- 'socks://user:pass@host' => 'socks5://user:pass@host:8080',
- 'user@host' => 'http://user:@host:8080',
- 'socks4a://10.20.30.40:5060' => 'socks4://10.20.30.40:5060',
- './proxy.sock' => 'http+unix://./proxy.sock',
- '/tmp/proxy.sock' => 'http+unix:///tmp/proxy.sock',
- 'user:pass@./proxy.sock' => 'http+unix://user:pass@./proxy.sock',
- 'http+unix://./proxy.sock' => 'http+unix://./proxy.sock',
- 'http+unix:///tmp/proxy.sock' => 'http+unix:///tmp/proxy.sock',
- 'http+unix://user:pass@./proxy.sock' => 'http+unix://user:pass@./proxy.sock',
- 'http+unix://user@./proxy.sock' => 'http+unix://user@./proxy.sock',
- 'socks+unix://./proxy.sock' => 'socks+unix://./proxy.sock',
- 'socks+unix://user:pass@./proxy.sock' => 'socks5+unix://user:pass@./proxy.sock',
- 'socks5+unix://user:pass@./proxy.sock' => 'socks5+unix://user:pass@./proxy.sock',
- );
- foreach ($uris as $in => $out) {
- $this->assertEquals($out, ConnectorFactory::coerceProxyUri($in));
- }
- }
- public function testCoerceProxyUriInvalidThrows()
- {
- $uris = array(
- 'empty' => '',
- 'invalid scheme' => 'tcp://test',
- 'invalid port' => 'host:port',
- 'auth for invalid scheme' => 'socks4://user@host',
- 'excessive path' => 'host/root',
- 'excessive query' => 'host?query',
- 'excessive fragment' => 'host#fragment',
- 'excessive dots' => '.../server.sock',
- 'auth for invalid socks4+unix' => 'socks4+unix://user:pass@./proxy.sock'
- );
- foreach ($uris as $uri) {
- try {
- ConnectorFactory::coerceProxyUri($uri);
- $this->fail($uri);
- } catch (InvalidArgumentException $e) {
- $this->assertTrue(true);
- }
- }
- }
- public function testCoerceListenUri()
- {
- $uris = array(
- '' => '0.0.0.0:8080',
- '127.0.0.1:1234' => '127.0.0.1:1234',
- '127.0.0.1' => '127.0.0.1:8080',
- '127.0.0.1:0' => '127.0.0.1:0',
- ':1234' => '0.0.0.0:1234',
- ':0' => '0.0.0.0:0',
- 'user:pass@0.0.0.0:8080' => 'user:pass@0.0.0.0:8080',
- 'user:pass@127.0.0.1' => 'user:pass@127.0.0.1:8080',
- 'user:pass@:1234' => 'user:pass@0.0.0.0:1234',
- '12:34@:45' => '12:34@0.0.0.0:45',
- 'user:pass@' => 'user:pass@0.0.0.0:8080',
- '[::1]' => '[::1]:8080',
- 'user:pass@[::1]' => 'user:pass@[::1]:8080',
- './proxy.sock' => './proxy.sock',
- '../proxy.sock' => '../proxy.sock',
- '/tmp/proxy.sock' => '/tmp/proxy.sock',
- 'user:pass@./proxy.sock' => 'user:pass@./proxy.sock',
- 'user:pass@/tmp/proxy.sock' => 'user:pass@/tmp/proxy.sock',
- );
- foreach ($uris as $in => $out) {
- $this->assertEquals($out, ConnectorFactory::coerceListenUri($in));
- }
- }
- public function testCoerceListenUriInvalidThrows()
- {
- $uris = array(
- 'invalid port' => '127.0.0.1:port',
- 'hostname' => 'localhost:8080',
- 'wildcard hostname' => '*:8080',
- 'excessive scheme' => 'http://127.0.0.1:8080',
- 'excessive path' => '127.0.0.1:8080/root',
- 'excessive query' => '127.0.0.1:8080?query',
- 'excessive fragment' => '127.0.0.1:8080#fragment',
- 'excessive dots' => '.../proxy.sock',
- 'path looks like hostname' => 'proxy.sock',
- );
- foreach ($uris as $uri) {
- try {
- ConnectorFactory::coerceListenUri($uri);
- $this->fail();
- } catch (InvalidArgumentException $e) {
- $this->assertTrue(true);
- }
- }
- }
- public function testCoerceBlockUri()
- {
- $uris = array(
- 'hostname' => 'hostname',
- '127.0.0.1:1234' => '127.0.0.1:1234',
- '127.0.0.1' => '127.0.0.1',
- '*:1234' => '*:1234',
- ':1234' => '*:1234',
- );
- foreach ($uris as $in => $out) {
- $this->assertEquals($out, ConnectorFactory::coerceBlockUri($in));
- }
- }
- public function testCoerceBlockUriInvalidThrows()
- {
- $uris = array(
- 'invalid port' => '127.0.0.1:port',
- 'excessive scheme' => 'http://127.0.0.1:8080',
- 'excessive path' => '127.0.0.1:8080/root',
- 'excessive query' => '127.0.0.1:8080?query',
- 'excessive fragment' => '127.0.0.1:8080#fragment',
- );
- foreach ($uris as $uri) {
- try {
- ConnectorFactory::coerceBlockUri($uri);
- $this->fail();
- } catch (InvalidArgumentException $e) {
- $this->assertTrue(true);
- }
- }
- }
- public function testIsIpLocal()
- {
- $ips = array(
- '127.0.0.1' => true,
- '127.1.2.3' => true,
- '192.168.1.1' => false,
- '8.8.8.8' => false,
- '::ffff:127.0.0.1' => true,
- '::1' => true,
- '::2' => false
- );
- foreach ($ips as $ip => $bool) {
- $this->assertEquals($bool, ConnectorFactory::isIpLocal($ip));
- }
- }
- public function testEmptyChainReturnsConnector()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $connector = ConnectorFactory::createConnectorChain(array(), $loop);
- $this->assertInstanceOf('React\Socket\ConnectorInterface', $connector);
- $this->assertInstanceOf('React\Socket\Connector', $connector);
- }
- public function testChainWithMixedProxiesReturnsAnyConnector()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $connector = ConnectorFactory::createConnectorChain(array('socks://127.0.0.1:1080', 'http://127.0.0.1:1080'), $loop);
- $this->assertInstanceOf('React\Socket\ConnectorInterface', $connector);
- }
- public function testChainWithMultipleProxiesOnlyStartsOneTimeout()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- $loop->expects($this->once())->method('addTimer');
- $connector = ConnectorFactory::createConnectorChain(array('socks://127.0.0.1:1080', 'http://127.0.0.1:1080'), $loop);
- $connector->connect('google.com:8080');
- }
- /** @expectedException InvalidArgumentException */
- public function testThrowsIfChainContainsInvalidUri()
- {
- $loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
- ConnectorFactory::createConnectorChain(array('///'), $loop);
- }
- public function testEmptyBlockPassesThrough()
- {
- $allow = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $allow->expects($this->once())->method('connect')->with('google.com:80');
- $connector = ConnectorFactory::createBlockingConnector(array(), $allow);
- $this->assertInstanceOf('React\Socket\ConnectorInterface', $connector);
- $connector->connect('google.com:80');
- }
- public function testBlockDomainsBlocksOnlyDomainsAndSubDomains()
- {
- $allow = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $allow->expects($this->once())->method('connect')->with('tls://github.com:443');
- $connector = ConnectorFactory::createBlockingConnector(array('google.com', 'google.de'), $allow);
- $this->assertInstanceOf('React\Socket\ConnectorInterface', $connector);
- $this->assertPromiseRejected($connector->connect('google.com:80'));
- $this->assertPromiseRejected($connector->connect('tcp://google.com:80'));
- $this->assertPromiseRejected($connector->connect('tls://google.com:443'));
- $this->assertPromiseRejected($connector->connect('tcp://www.google.com:80'));
- $this->assertPromiseRejected($connector->connect('tcp://some.sub.domain.google.de:80'));
- $connector->connect('tls://github.com:443');
- }
- public function testBlockWildcardBlocksOnlyMatchingDomains()
- {
- $allow = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $allow->expects($this->once())->method('connect')->with('tcp://google.com:80');
- $connector = ConnectorFactory::createBlockingConnector(array('*.google.com'), $allow);
- $this->assertInstanceOf('React\Socket\ConnectorInterface', $connector);
- $this->assertPromiseRejected($connector->connect('test.google.com:80'));
- $this->assertPromiseRejected($connector->connect('tcp://test.google.com:80'));
- $this->assertPromiseRejected($connector->connect('tls://test.google.com:443'));
- $this->assertPromiseRejected($connector->connect('tcp://some.sub.domain.google.com:80'));
- $connector->connect('tcp://google.com:80');
- }
- public function testBlockHttpPort()
- {
- $allow = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
- $allow->expects($this->once())->method('connect')->with('tls://google.com:443');
- $connector = ConnectorFactory::createBlockingConnector(array('*:80'), $allow);
- $this->assertInstanceOf('React\Socket\ConnectorInterface', $connector);
- $this->assertPromiseRejected($connector->connect('google.com:80'));
- $this->assertPromiseRejected($connector->connect('tcp://google.com:80'));
- $this->assertPromiseRejected($connector->connect('tcp://github.com:80'));
- $connector->connect('tls://google.com:443');
- }
- public function testFilterRootDomains()
- {
- $domains = array('www.google.com', 'google.com', 'deep.example.google.com');
- $this->assertEquals(array('google.com'), ConnectorFactory::filterRootDomains($domains));
- }
- private function assertPromiseRejected($input)
- {
- $this->assertInstanceOf('React\Promise\PromiseInterface', $input);
- $rejected = false;
- $input->then(null, function () use (&$rejected) {
- $rejected= true;
- });
- $this->assertTrue($rejected);
- }
- }
|