Skip to content

Commit

Permalink
Merge pull request #28 from clue-labs/socket
Browse files Browse the repository at this point in the history
Simplify usage by supporting new Socket API without nullable loop
  • Loading branch information
clue authored Aug 5, 2021
2 parents b2d791f + 1e51a37 commit e0bbe0c
Show file tree
Hide file tree
Showing 11 changed files with 44 additions and 52 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ plaintext HTTP request to google.com through a remote SSH server:
```php
$proxy = new Clue\React\SshProxy\SshProcessConnector('user@example.com');

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => false
));
Expand Down Expand Up @@ -287,7 +287,7 @@ $proxy = new Clue\React\SshProxy\SshProcessConnector('user@example.com');
// or
$proxy = new Clue\React\SshProxy\SshSocksConnector('user@example.com');

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => false
));
Expand Down Expand Up @@ -318,7 +318,7 @@ low-level [`SecureConnector`](https://github.com/reactphp/socket#secureconnector
```php
$proxy = new Clue\React\SshProxy\SshSocksConnector('user@example.com');

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => false
));
Expand Down Expand Up @@ -350,12 +350,12 @@ This allows you to send both plain HTTP and TLS-encrypted HTTPS requests like th
```php
$proxy = new Clue\React\SshProxy\SshSocksConnector('user@example.com');

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => false
));

$browser = new React\Http\Browser(null, $connector);
$browser = new React\Http\Browser($connector);

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
var_dump($response->getHeaders(), (string) $response->getBody());
Expand Down Expand Up @@ -435,7 +435,7 @@ $proxy = new Clue\React\SshProxy\SshProcessConnector('user@example.com');
// or
$proxy = new Clue\React\SshProxy\SshSocksConnector('user@example.com');

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => false,
'timeout' => 3.0
Expand Down Expand Up @@ -481,7 +481,7 @@ $proxy = new Clue\React\SshProxy\SshProcessConnector('user@example.com');
// or
$proxy = new Clue\React\SshProxy\SshSocksConnector('user@example.com');

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => false
));
Expand All @@ -495,7 +495,7 @@ $proxy = new Clue\React\SshProxy\SshProcessConnector('user@example.com');
$proxy = new Clue\React\SshProxy\SshSocksConnector('user@example.com');

// set up Connector which uses Google's public DNS (8.8.8.8)
$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'dns' => '8.8.8.8'
));
Expand Down
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
"react/child-process": "^0.6",
"react/event-loop": "^1.2",
"react/promise": "^2.1 || ^1.2.1",
"react/socket": "^1.8",
"react/socket": "^1.9",
"react/stream": "^1.2"
},
"require-dev": {
"clue/block-react": "^1.3",
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36",
"react/http": "^1.4",
"react/http": "^1.5",
"react/mysql": "^0.5.5"
}
}
4 changes: 2 additions & 2 deletions examples/01-https-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@

$proxy = new Clue\React\SshProxy\SshProcessConnector($url);

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'timeout' => 3.0,
'dns' => false
));

$browser = new React\Http\Browser(null, $connector);
$browser = new React\Http\Browser($connector);

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
var_dump($response->getHeaders(), (string) $response->getBody());
Expand Down
4 changes: 2 additions & 2 deletions examples/02-optional-proxy-https-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@
if (getenv('SSH_PROXY') !== false) {
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'));

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'timeout' => 3.0,
'dns' => false
));
}

$browser = new React\Http\Browser(null, $connector);
$browser = new React\Http\Browser($connector);

$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
var_dump($response->getHeaders(), (string) $response->getBody());
Expand Down
2 changes: 1 addition & 1 deletion examples/11-proxy-raw-http-protocol.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

$proxy = new Clue\React\SshProxy\SshProcessConnector($url);

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'timeout' => 3.0,
'dns' => false
Expand Down
2 changes: 1 addition & 1 deletion examples/12-optional-proxy-raw-http-protocol.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
if (getenv('SSH_PROXY') !== false) {
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'));

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'timeout' => 3.0,
'dns' => false
Expand Down
2 changes: 1 addition & 1 deletion examples/21-proxy-raw-https-protocol.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

$proxy = new Clue\React\SshProxy\SshSocksConnector($url);

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'timeout' => 3.0,
'dns' => false
Expand Down
2 changes: 1 addition & 1 deletion examples/22-optional-proxy-raw-https-protocol.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
if (getenv('SSH_PROXY') !== false) {
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'));

$connector = new React\Socket\Connector(null, array(
$connector = new React\Socket\Connector(array(
'tcp' => $proxy,
'timeout' => 3.0,
'dns' => false
Expand Down
16 changes: 7 additions & 9 deletions tests/FunctionalSshProcessConnectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

namespace Clue\Tests\React\SshProxy;

use React\EventLoop\Factory;
use Clue\React\SshProxy\SshProcessConnector;
use React\EventLoop\Loop;

class FunctionalSshProcessConnectorTest extends TestCase
{
const TIMEOUT = 10.0;

private $loop;
private $connector;

/**
Expand All @@ -22,25 +21,24 @@ public function setUpConnector()
$this->markTestSkipped('No SSH_PROXY env set');
}

$this->loop = Factory::create();
$this->connector = new SshProcessConnector($url, $this->loop);
$this->connector = new SshProcessConnector($url);
}

public function testConnectInvalidProxyUriWillReturnRejectedPromise()
{
$this->connector = new SshProcessConnector(getenv('SSH_PROXY') . '.invalid', $this->loop);
$this->connector = new SshProcessConnector(getenv('SSH_PROXY') . '.invalid');
$promise = $this->connector->connect('example.com:80');

$this->setExpectedException('RuntimeException', 'Connection to example.com:80 failed because SSH client died');
\Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
\Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);
}

public function testConnectInvalidTargetWillReturnRejectedPromise()
{
$promise = $this->connector->connect('example.invalid:80');

$this->setExpectedException('RuntimeException', 'Connection to example.invalid:80 rejected:');
\Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
\Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);
}

public function testCancelConnectWillReturnRejectedPromise()
Expand All @@ -49,14 +47,14 @@ public function testCancelConnectWillReturnRejectedPromise()
$promise->cancel();

$this->setExpectedException('RuntimeException', 'Connection to example.com:80 cancelled while waiting for SSH client');
\Clue\React\Block\await($promise, $this->loop, 0);
\Clue\React\Block\await($promise, Loop::get(), 0);
}

public function testConnectValidTargetWillReturnPromiseWhichResolvesToConnection()
{
$promise = $this->connector->connect('example.com:80');

$connection = \Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
$connection = \Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);

$this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
$this->assertTrue($connection->isReadable());
Expand Down
22 changes: 10 additions & 12 deletions tests/FunctionalSshSocksConnectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@

namespace Clue\Tests\React\SshProxy;

use React\EventLoop\Factory;
use Clue\React\SshProxy\SshSocksConnector;
use React\EventLoop\Loop;

class FunctionalSshSocksConnectorTest extends TestCase
{
const TIMEOUT = 10.0;

private $loop;
private $connector;

/**
Expand All @@ -22,8 +21,7 @@ public function setUpConnector()
$this->markTestSkipped('No SSH_PROXY env set');
}

$this->loop = Factory::create();
$this->connector = new SshSocksConnector($url, $this->loop);
$this->connector = new SshSocksConnector($url);
}

/**
Expand All @@ -32,25 +30,25 @@ public function setUpConnector()
public function tearDownSSHClientProcess()
{
// run loop in order to shut down SSH client process again
\Clue\React\Block\sleep(0.001, $this->loop);
\Clue\React\Block\sleep(0.001, Loop::get());
}

public function testConnectInvalidProxyUriWillReturnRejectedPromise()
{
$this->connector = new SshSocksConnector(getenv('SSH_PROXY') . '.invalid', $this->loop);
$this->connector = new SshSocksConnector(getenv('SSH_PROXY') . '.invalid');

$promise = $this->connector->connect('example.com:80');

$this->setExpectedException('RuntimeException', 'Connection to example.com:80 failed because SSH client process died');
\Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
\Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);
}

public function testConnectInvalidTargetWillReturnRejectedPromise()
{
$promise = $this->connector->connect('example.invalid:80');

$this->setExpectedException('RuntimeException', 'Connection to tcp://example.invalid:80 failed because connection to proxy was lost');
\Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
\Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);
}

public function testCancelConnectWillReturnRejectedPromise()
Expand All @@ -59,14 +57,14 @@ public function testCancelConnectWillReturnRejectedPromise()
$promise->cancel();

$this->setExpectedException('RuntimeException', 'Connection to example.com:80 cancelled while waiting for SSH client');
\Clue\React\Block\await($promise, $this->loop, 0);
\Clue\React\Block\await($promise, Loop::get(), 0);
}

public function testConnectValidTargetWillReturnPromiseWhichResolvesToConnection()
{
$promise = $this->connector->connect('example.com:80');

$connection = \Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
$connection = \Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);

$this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
$this->assertTrue($connection->isReadable());
Expand All @@ -76,10 +74,10 @@ public function testConnectValidTargetWillReturnPromiseWhichResolvesToConnection

public function testConnectValidTargetWillReturnPromiseWhichResolvesToConnectionForCustomBindAddress()
{
$this->connector = new SshSocksConnector(getenv('SSH_PROXY') . '?bind=127.0.0.1:1081', $this->loop);
$this->connector = new SshSocksConnector(getenv('SSH_PROXY') . '?bind=127.0.0.1:1081', Loop::get());
$promise = $this->connector->connect('example.com:80');

$connection = \Clue\React\Block\await($promise, $this->loop, self::TIMEOUT);
$connection = \Clue\React\Block\await($promise, Loop::get(), self::TIMEOUT);

$this->assertInstanceOf('React\Socket\ConnectionInterface', $connection);
$this->assertTrue($connection->isReadable());
Expand Down
22 changes: 9 additions & 13 deletions tests/IntegrationSshProcessConnectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
namespace Clue\Tests\React\SshProxy;

use Clue\React\SshProxy\SshProcessConnector;
use React\EventLoop\Factory;
use React\EventLoop\Loop;
use React\Socket\ConnectionInterface;

class IntegrationSshProcessConnectorTest extends TestCase
{
public function testConnectWillResolveWithConnectionInterfaceWhenProcessOutputsChannelOpenConfirmMessage()
{
$loop = Factory::create();
$connector = new SshProcessConnector('host', $loop);
$connector = new SshProcessConnector('host');

$ref = new \ReflectionProperty($connector, 'cmd');
$ref->setAccessible(true);
Expand All @@ -20,13 +19,12 @@ public function testConnectWillResolveWithConnectionInterfaceWhenProcessOutputsC
$promise = $connector->connect('example.com:80');
$promise->then($this->expectCallableOnceWith($this->isInstanceOf('React\Socket\ConnectionInterface')));

$loop->run();
Loop::run();
}

public function testConnectWillRejectWithExceptionWhenProcessOutputsChannelOpenFailedMessage()
{
$loop = Factory::create();
$connector = new SshProcessConnector('host', $loop);
$connector = new SshProcessConnector('host');

$ref = new \ReflectionProperty($connector, 'cmd');
$ref->setAccessible(true);
Expand All @@ -35,13 +33,12 @@ public function testConnectWillRejectWithExceptionWhenProcessOutputsChannelOpenF
$promise = $connector->connect('example.com:80');
$promise->then(null, $this->expectCallableOnceWith($this->isInstanceOf('RuntimeException')));

$loop->run();
Loop::run();
}

public function testConnectWillRejectWithExceptionWhenProcessOutputsEndsWithoutChannelMessage()
{
$loop = Factory::create();
$connector = new SshProcessConnector('host', $loop);
$connector = new SshProcessConnector('host');

$ref = new \ReflectionProperty($connector, 'cmd');
$ref->setAccessible(true);
Expand All @@ -50,13 +47,12 @@ public function testConnectWillRejectWithExceptionWhenProcessOutputsEndsWithoutC
$promise = $connector->connect('example.com:80');
$promise->then(null, $this->expectCallableOnceWith($this->isInstanceOf('RuntimeException')));

$loop->run();
Loop::run();
}

public function testConnectWillResolveWithConnectionThatWillEmitImmediateDataFromProcessStdoutAfterChannelOpenConfirmMessage()
{
$loop = Factory::create();
$connector = new SshProcessConnector('host', $loop);
$connector = new SshProcessConnector('host');

$ref = new \ReflectionProperty($connector, 'cmd');
$ref->setAccessible(true);
Expand All @@ -69,6 +65,6 @@ public function testConnectWillResolveWithConnectionThatWillEmitImmediateDataFro
$connection->on('data', $data);
});

$loop->run();
Loop::run();
}
}

0 comments on commit e0bbe0c

Please sign in to comment.