Skip to content

Commit 27315a7

Browse files
committed
Simplify usage by supporting new default loop
1 parent 7491db0 commit 27315a7

13 files changed

+122
-101
lines changed

README.md

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,9 @@ The following example code demonstrates how this library can be used to send a
7575
plaintext HTTP request to google.com through a remote SSH server:
7676

7777
```php
78-
$loop = React\EventLoop\Factory::create();
78+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
7979

80-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
81-
$connector = new React\Socket\Connector($loop, array(
80+
$connector = new React\Socket\Connector(null, array(
8281
'tcp' => $proxy,
8382
'dns' => false
8483
));
@@ -92,8 +91,6 @@ $connector->connect('tcp://google.com:80')->then(function (React\Socket\Connecti
9291
echo '[DONE]';
9392
});
9493
}, 'printf');
95-
96-
$loop->run();
9794
```
9895

9996
See also the [examples](examples).
@@ -121,17 +118,22 @@ systems, you may simply install it like this:
121118
$ sudo apt install openssh-client
122119
```
123120

124-
Its constructor simply accepts an SSH proxy server URL and a loop to bind to:
121+
Its constructor simply accepts an SSH proxy server URL:
125122

126123
```php
127-
$loop = React\EventLoop\Factory::create();
128-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
124+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
129125
```
130126

131127
The proxy URL may or may not contain a scheme and port definition. The default
132128
port will be `22` for SSH, but you may have to use a custom port depending on
133129
your SSH server setup.
134130

131+
This class takes an optional `LoopInterface|null $loop` parameter that can be used to
132+
pass the event loop instance to use for this object. You can use a `null` value
133+
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
134+
This value SHOULD NOT be given unless you're sure you want to explicitly use a
135+
given event loop instance.
136+
135137
Keep in mind that this class is implemented as a lightweight process wrapper
136138
around the `ssh` client binary and that it will spawn one `ssh` process for each
137139
connection. If you open more connections, it will spawn one `ssh` process for
@@ -160,7 +162,7 @@ higher-level component:
160162

161163
```diff
162164
- $acme = new AcmeApi($connector);
163-
+ $proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
165+
+ $proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
164166
+ $acme = new AcmeApi($proxy);
165167
```
166168

@@ -189,17 +191,22 @@ simply install it like this:
189191
$ sudo apt install openssh-client
190192
```
191193

192-
Its constructor simply accepts an SSH proxy server URL and a loop to bind to:
194+
Its constructor simply accepts an SSH proxy server URL:
193195

194196
```php
195-
$loop = React\EventLoop\Factory::create();
196-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
197+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
197198
```
198199

199200
The proxy URL may or may not contain a scheme and port definition. The default
200201
port will be `22` for SSH, but you may have to use a custom port depending on
201202
your SSH server setup.
202203

204+
This class takes an optional `LoopInterface|null $loop` parameter that can be used to
205+
pass the event loop instance to use for this object. You can use a `null` value
206+
here in order to use the [default loop](https://github.com/reactphp/event-loop#loop).
207+
This value SHOULD NOT be given unless you're sure you want to explicitly use a
208+
given event loop instance.
209+
203210
Keep in mind that this class is implemented as a lightweight process wrapper
204211
around the `ssh` client binary and that it will spawn one `ssh` process for
205212
multiple connections. This process will take some time to create a new SSH
@@ -216,7 +223,7 @@ to use multiple instances of this class to connect to different SSH proxy
216223
servers, you may optionally pass a unique bind address like this:
217224

218225
```php
219-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]?bind=127.1.1.1:1081', $loop);
226+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]?bind=127.1.1.1:1081',);
220227
```
221228

222229
> *Security note for multi-user systems*: This class will spawn the SSH client
@@ -244,7 +251,7 @@ higher-level component:
244251

245252
```diff
246253
- $acme = new AcmeApi($connector);
247-
+ $proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
254+
+ $proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
248255
+ $acme = new AcmeApi($proxy);
249256
```
250257

@@ -260,9 +267,9 @@ a streaming plain TCP/IP connection on the `SshProcessConnector` or `SshSocksCon
260267
and use any higher level protocol like so:
261268

262269
```php
263-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
270+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
264271
// or
265-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
272+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
266273

267274
$proxy->connect('tcp://smtp.googlemail.com:587')->then(function (React\Socket\ConnectionInterface $connection) {
268275
$connection->write("EHLO local\r\n");
@@ -276,11 +283,11 @@ You can either use the `SshProcessConnector` or `SshSocksConnector` directly or
276283
may want to wrap this connector in ReactPHP's [`Connector`](https://github.com/reactphp/socket#connector):
277284

278285
```php
279-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
286+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
280287
// or
281-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
288+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
282289

283-
$connector = new React\Socket\Connector($loop, array(
290+
$connector = new React\Socket\Connector(null, array(
284291
'tcp' => $proxy,
285292
'dns' => false
286293
));
@@ -309,9 +316,9 @@ ReactPHP's [`Connector`](https://github.com/reactphp/socket#connector) or the
309316
low-level [`SecureConnector`](https://github.com/reactphp/socket#secureconnector):
310317

311318
```php
312-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
319+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
313320

314-
$connector = new React\Socket\Connector($loop, array(
321+
$connector = new React\Socket\Connector(null, array(
315322
'tcp' => $proxy,
316323
'dns' => false
317324
));
@@ -341,14 +348,14 @@ In order to send HTTP requests, you first have to add a dependency for
341348
This allows you to send both plain HTTP and TLS-encrypted HTTPS requests like this:
342349

343350
```php
344-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
351+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
345352

346-
$connector = new React\Socket\Connector($loop, array(
353+
$connector = new React\Socket\Connector(null, array(
347354
'tcp' => $proxy,
348355
'dns' => false
349356
));
350357

351-
$browser = new React\Http\Browser($loop, $connector);
358+
$browser = new React\Http\Browser(null, $connector);
352359

353360
$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
354361
var_dump($response->getHeaders(), (string) $response->getBody());
@@ -378,11 +385,10 @@ the above SSH proxy server setup, so we can access a firewalled MySQL database
378385
server through an SSH tunnel. Here's the gist:
379386

380387
```php
381-
$loop = React\EventLoop\Factory::create();
382-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
388+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
383389

384390
$uri = 'test:test@localhost/test';
385-
$factory = new React\MySQL\Factory($loop, $proxy);
391+
$factory = new React\MySQL\Factory(null, $proxy);
386392
$connection = $factory->createLazyConnection($uri);
387393

388394
$connection->query('SELECT * FROM book')->then(
@@ -395,8 +401,6 @@ $connection->query('SELECT * FROM book')->then(
395401
);
396402

397403
$connection->quit();
398-
399-
$loop->run();
400404
```
401405

402406
See also [example #21](examples) for more details.
@@ -427,11 +431,11 @@ It provides the same `connect()` method, but will automatically reject the
427431
underlying connection attempt if it takes too long:
428432

429433
```php
430-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
434+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
431435
// or
432-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
436+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
433437

434-
$connector = new React\Socket\Connector($loop, array(
438+
$connector = new React\Socket\Connector(null, array(
435439
'tcp' => $proxy,
436440
'dns' => false,
437441
'timeout' => 3.0
@@ -473,11 +477,11 @@ Given that remote DNS resolution is assumed to be the preferred mode, all
473477
other examples explicitly disable DNS resolution like this:
474478

475479
```php
476-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
480+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
477481
// or
478-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
482+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
479483

480-
$connector = new React\Socket\Connector($loop, array(
484+
$connector = new React\Socket\Connector(null, array(
481485
'tcp' => $proxy,
482486
'dns' => false
483487
));
@@ -486,12 +490,12 @@ $connector = new React\Socket\Connector($loop, array(
486490
If you want to explicitly use *local DNS resolution*, you can use the following code:
487491

488492
```php
489-
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]', $loop);
493+
$proxy = new Clue\React\SshProxy\SshProcessConnector('[email protected]');
490494
// or
491-
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]', $loop);
495+
$proxy = new Clue\React\SshProxy\SshSocksConnector('[email protected]');
492496

493497
// set up Connector which uses Google's public DNS (8.8.8.8)
494-
$connector = new React\Socket\Connector($loop, array(
498+
$connector = new React\Socket\Connector(null, array(
495499
'tcp' => $proxy,
496500
'dns' => '8.8.8.8'
497501
));
@@ -525,9 +529,9 @@ If your SSH proxy server requires password authentication, you may pass the
525529
username and password as part of the SSH proxy server URL like this:
526530

527531
```php
528-
$proxy = new Clue\React\SshProxy\SshProcessConnector('user:[email protected]', $loop);
532+
$proxy = new Clue\React\SshProxy\SshProcessConnector('user:[email protected]');
529533
// or
530-
$proxy = new Clue\React\SshProxy\SshSocksConnector('user:[email protected]', $loop);
534+
$proxy = new Clue\React\SshProxy\SshSocksConnector('user:[email protected]');
531535
```
532536

533537
For this to work, you will have to have the `sshpass` binary installed. On
@@ -545,8 +549,7 @@ $user = 'he:llo';
545549
$pass = 'p@ss';
546550

547551
$proxy = new Clue\React\SshProxy\SshProcessConnector(
548-
rawurlencode($user) . ':' . rawurlencode($pass) . '@example.com:2222',
549-
$loop
552+
rawurlencode($user) . ':' . rawurlencode($pass) . '@example.com:2222'
550553
);
551554
```
552555

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
"php": ">=5.3",
2222
"clue/socks-react": "^1.0",
2323
"react/child-process": "^0.6",
24-
"react/event-loop": "^1.0 || ^0.5",
24+
"react/event-loop": "^1.2",
2525
"react/promise": "^2.1 || ^1.2.1",
26-
"react/socket": "^1.1",
27-
"react/stream": "^1.0 || ^0.7.2"
26+
"react/socket": "^1.8",
27+
"react/stream": "^1.2"
2828
},
2929
"require-dev": {
3030
"clue/block-react": "^1.3",
3131
"phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.36",
32-
"react/http": "^1.0",
33-
"react/mysql": "^0.5.3"
32+
"react/http": "^1.4",
33+
"react/mysql": "^0.5.5"
3434
}
3535
}

examples/01-https-request.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,18 @@
1313

1414
$url = getenv('SSH_PROXY') !== false ? getenv('SSH_PROXY') : 'ssh://localhost:22';
1515

16-
$loop = React\EventLoop\Factory::create();
17-
$proxy = new Clue\React\SshProxy\SshProcessConnector($url, $loop);
16+
$proxy = new Clue\React\SshProxy\SshProcessConnector($url);
1817

19-
$connector = new React\Socket\Connector($loop, array(
18+
$connector = new React\Socket\Connector(null, array(
2019
'tcp' => $proxy,
2120
'timeout' => 3.0,
2221
'dns' => false
2322
));
2423

25-
$browser = new React\Http\Browser($loop, $connector);
24+
$browser = new React\Http\Browser(null, $connector);
2625

2726
$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
2827
var_dump($response->getHeaders(), (string) $response->getBody());
2928
}, function (Exception $e) {
3029
echo 'Error: ' . $e->getMessage() . PHP_EOL;
3130
});
32-
33-
$loop->run();

examples/02-optional-proxy-https-request.php

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,22 @@
1111

1212
require __DIR__ . '/../vendor/autoload.php';
1313

14-
$loop = React\EventLoop\Factory::create();
15-
1614
// SSH_PROXY environment given? use this as the proxy URL
15+
$connector = null;
1716
if (getenv('SSH_PROXY') !== false) {
18-
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'), $loop);
19-
$connector = new React\Socket\Connector($loop, array(
17+
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'));
18+
19+
$connector = new React\Socket\Connector(null, array(
2020
'tcp' => $proxy,
2121
'timeout' => 3.0,
2222
'dns' => false
2323
));
24-
} else {
25-
$connector = new React\Socket\Connector($loop);
2624
}
2725

28-
$browser = new React\Http\Browser($loop, $connector);
26+
$browser = new React\Http\Browser(null, $connector);
2927

3028
$browser->get('https://example.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
3129
var_dump($response->getHeaders(), (string) $response->getBody());
3230
}, function (Exception $e) {
3331
echo 'Error: ' . $e->getMessage() . PHP_EOL;
3432
});
35-
36-
$loop->run();

examples/11-proxy-raw-http-protocol.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
$url = getenv('SSH_PROXY') !== false ? getenv('SSH_PROXY') : 'ssh://localhost:22';
1818

19-
$loop = React\EventLoop\Factory::create();
19+
$proxy = new Clue\React\SshProxy\SshProcessConnector($url);
2020

21-
$proxy = new Clue\React\SshProxy\SshProcessConnector($url, $loop);
22-
$connector = new React\Socket\Connector($loop, array(
21+
$connector = new React\Socket\Connector(null, array(
2322
'tcp' => $proxy,
2423
'timeout' => 3.0,
2524
'dns' => false
@@ -33,5 +32,3 @@
3332
}, function (Exception $e) {
3433
echo 'Error: ' . $e->getMessage() . PHP_EOL;
3534
});
36-
37-
$loop->run();

examples/12-optional-proxy-raw-http-protocol.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,17 @@
1818

1919
require __DIR__ . '/../vendor/autoload.php';
2020

21-
$loop = React\EventLoop\Factory::create();
22-
2321
// SSH_PROXY environment given? use this as the proxy URL
2422
if (getenv('SSH_PROXY') !== false) {
25-
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'), $loop);
26-
$connector = new React\Socket\Connector($loop, array(
23+
$proxy = new Clue\React\SshProxy\SshProcessConnector(getenv('SSH_PROXY'));
24+
25+
$connector = new React\Socket\Connector(null, array(
2726
'tcp' => $proxy,
2827
'timeout' => 3.0,
2928
'dns' => false
3029
));
3130
} else {
32-
$connector = new React\Socket\Connector($loop);
31+
$connector = new React\Socket\Connector();
3332
}
3433

3534
$connector->connect('tcp://google.com:80')->then(function (React\Socket\ConnectionInterface $connection) {
@@ -40,5 +39,3 @@
4039
}, function (Exception $e) {
4140
echo 'Error: ' . $e->getMessage() . PHP_EOL;
4241
});
43-
44-
$loop->run();

examples/21-proxy-raw-https-protocol.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
$url = getenv('SSH_PROXY') !== false ? getenv('SSH_PROXY') : 'ssh://localhost:22';
1818

19-
$loop = React\EventLoop\Factory::create();
19+
$proxy = new Clue\React\SshProxy\SshSocksConnector($url);
2020

21-
$proxy = new Clue\React\SshProxy\SshSocksConnector($url, $loop);
22-
$connector = new React\Socket\Connector($loop, array(
21+
$connector = new React\Socket\Connector(null, array(
2322
'tcp' => $proxy,
2423
'timeout' => 3.0,
2524
'dns' => false
@@ -33,5 +32,3 @@
3332
}, function (Exception $e) {
3433
echo 'Error: ' . $e->getMessage() . PHP_EOL;
3534
});
36-
37-
$loop->run();

0 commit comments

Comments
 (0)