Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge SocketClient component into this component #87

Merged
merged 197 commits into from
Apr 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
197 commits
Select commit Hold shift + click to select a range
64034cf
Move ConnectionManager* to new SocketClient component
igorw Jan 15, 2013
730f933
Handle connection failure in ConnectionManager (thanks @nrk)
igorw Jan 15, 2013
fc4d27d
Fix ConnectionException namespace
igorw Jan 15, 2013
bc9991c
Move error handling to inner promise
clue Jan 15, 2013
83b7210
Do not pretend a timeout is supported
clue Jan 15, 2013
b3b764a
Split to provide a SecureConnectionManager decorator
clue Jan 15, 2013
30d52b4
Import initial sketch of README and composer.json
clue Jan 15, 2013
4dfcdbd
Remove useless setter for the time being
clue Jan 15, 2013
e4fa842
Fix whitespace
clue Jan 15, 2013
c56cb75
Remove leftovers of timeout handling
clue Jan 15, 2013
faaac4b
Improve error handling
clue Jan 18, 2013
fa6c341
Move error handling to separate chained promise
clue Jan 18, 2013
ee75185
Update composer.json for v0.3
igorw Jan 20, 2013
2e259da
Trailing newline for composer.json
igorw Jan 20, 2013
d0200b5
Wrap README
igorw Jan 20, 2013
010795e
Remove UDP and LICENSE sections from README
igorw Jan 20, 2013
f1d85f1
Make composer.json consistent with the other ones
igorw Jan 20, 2013
37ba732
Simplify README
igorw Jan 20, 2013
ea1ed9e
Add newline to ConnectionManager
igorw Jan 20, 2013
ff0122e
Wrap StreamEncryption comment
igorw Jan 20, 2013
abfe843
Add missing import of Promise\\When to ConnectionManager
igorw Jan 20, 2013
bdd080a
Tighten visibility of SocketClient properties
igorw Jan 20, 2013
16bf0dd
Make promise constraint consistent by using tilde
igorw Jan 20, 2013
0117b87
Use When instead of FulfilledPromise and RejectedPromise
igorw Jan 21, 2013
73dec56
Make the transport method of the socket variable.
robinvdvleuten Jan 28, 2013
9f75e72
Rename ConnectionManager to Connector
igorw Jan 28, 2013
3cdd19e
Rename Connector::getConnection to createTcp
igorw Jan 28, 2013
873a077
Merged the changes of igorw to the SocketClient
robinvdvleuten Jan 29, 2013
12b54c4
[socket-client] Remove leading backslash for use statement
igorw Jan 31, 2013
cbbbebb
Merge remote-tracking branch 'robinvdvleuten/socket-client' into sock…
igorw Feb 7, 2013
c7488bf
Fix socket-client composer.json
igorw Apr 14, 2013
cc7ca13
[SocketClient] Remove ConnectorInterface::createUdp
igorw Apr 14, 2013
a6e852b
[SocketClient] Rename Connector::createTcp to Connector::create
igorw Apr 14, 2013
06d0c73
CS
cboden Apr 14, 2013
0bbbbac
Clean up annoying 5.3 $that = $this
igorw Apr 14, 2013
23c9417
Remove $that craziness from SecureConnector
igorw Apr 14, 2013
87935a0
Support connecting to IPv6 addresses
clue Apr 20, 2013
3bcf823
Merge branch 'refs/heads/master' into 0.4
cboden Jul 8, 2013
d18db34
Update to React/Promise 2.0
jsor Dec 10, 2013
bfecaa8
Fixed broken link for stream_socket_client documentation and updated …
elliot Dec 18, 2013
6ec8c3a
Update child repos to PSR-4 for git subs-plit
cboden Feb 1, 2014
5ee205c
Move tests to each component
clue May 7, 2014
d347675
Make components' tests run on their own and from main repo.
clue May 7, 2014
52ff3bf
Update repo to work as a standalone component
cboden May 25, 2014
970cf18
Adjusted parent test bootstrap loader path
cboden May 25, 2014
49620d1
Merge branch 'refs/heads/standalone'
cboden May 25, 2014
a813a91
Added license file from react
cboden Jun 1, 2014
cd0ddfb
Add CHANGELOG
clue Jun 6, 2014
00b6532
Add bumped versions to changelog
clue Jun 9, 2014
7c1c701
Explicitly depend on react/stream
clue Jun 9, 2014
0d941c5
Merge pull request #3 from clue/changelog
cboden Jun 11, 2014
afad9e9
Merge branch 'refs/heads/deps'
cboden Jun 15, 2014
20a9d24
Show test coverage directly after running test
Jun 17, 2014
cc9087c
Merge pull request #8 from psychoticmeow/f-require-phpunit
cboden Jun 21, 2014
a91bb2f
Ensure SNI details are always set on socket creation
DaveRandom Jul 31, 2014
a1f4e7c
Merge pull request #11 from DaveRandom/patch/SNI-fix
cboden Aug 14, 2014
6a813e0
Only toggle the stream crypto handshake once
cboden Aug 23, 2014
72eea35
SecureStream to address SSL buffering problem
cboden Aug 23, 2014
ac87c2d
Fixed wrong emit when piping data through Secure
cboden Aug 23, 2014
44ab73c
Unwrap SecureStream, better decorating API
cboden Aug 23, 2014
aa071b8
Only do file_get_contents on PHP versions needed
cboden Aug 31, 2014
08ff406
Fix version check to 5.5
cboden Sep 2, 2014
d744011
Merge remote-tracking branch 'origin/crypto-once'
igorw Sep 21, 2014
a30ef4d
Merge remote-tracking branch 'origin/ssl-fix'
igorw Sep 21, 2014
6ebaa4e
Update CHANGELOG
igorw Sep 21, 2014
5b4ccbb
Changelog for release
cboden Oct 16, 2014
80eeb47
Adding Code Climate badge to readme
e3betht Dec 18, 2014
e81abac
Added peer_name to ssl context options
WyriHaximus Feb 2, 2015
6f92680
"Fix" minor BC break
cboden Feb 3, 2015
b302dfc
Always Stream if SSL
cboden Feb 3, 2015
3cc2bfd
Merge pull request #23 from WyriHaximus/master
cboden Mar 11, 2015
14116e4
Undo API change in docs
cboden Mar 11, 2015
e3122b1
Merge branch 'ssl-refix'
cboden Mar 20, 2015
dfaf7c3
Merge branch 'bc-fix'
cboden Mar 20, 2015
d46c0b5
Merge branch 'cc-badge'
cboden Mar 20, 2015
25686f5
v0.4.3 changelog
cboden Mar 20, 2015
0406b34
Integration test that performs a HTTP request against google.com
igorw Sep 21, 2014
7cc7043
just check for beginning of HTTP line, since google is strange
igorw Sep 21, 2014
1375dac
Merge branch 'integration-test'
cboden Mar 20, 2015
7f713ac
Explicitly set supported TLS version for PHP5.6+
WyriHaximus Apr 2, 2015
cf29c6c
Using defined instead of a version check as suggested by @cboden
WyriHaximus Apr 12, 2015
5f41caa
Merge branch 'tls-support'
cboden Apr 12, 2015
a12dc4e
Test against PHP7
WyriHaximus Apr 15, 2015
6d765b0
65137 was fixed in PHP 5.6.8, so this code now fails on that version
alexmace May 7, 2015
720ffc6
Merge pull request #32 from WyriHaximus/patch-1
cboden May 13, 2015
b06c154
Merge branch '5.6.8-fix'
cboden May 13, 2015
98b6095
spaces > tabs
cboden May 13, 2015
fa736cf
Adding $loop->run(); to the documentation
Jun 2, 2015
3cc3f86
Merge pull request #36 from ThijsFeryn/looprun
clue Jun 2, 2015
2536462
Add support for Unix domain sockets (UDS)
clue Jul 15, 2015
78d8d3d
Move SSL/TLS context options to SecureConnector
clue Sep 6, 2015
3985ea1
Merge pull request #41 from clue-labs/unix
cboden Sep 22, 2015
3ca814d
Prepare v0.4.4 release
clue Sep 23, 2015
5e3c4c6
Merge pull request #43 from clue-labs/secure-context
cboden Sep 24, 2015
1a4b1c6
Split Connector into TcpConnector and DnsConnector
clue Jul 15, 2015
9fe3407
Reject hostnames for TcpConnector and improve test coverage
clue Sep 22, 2015
b468654
Add legacy Connector as BC layer
clue Sep 23, 2015
0516389
Mark internals as such in order to avoid a future BC break
clue Nov 18, 2015
0f07289
Improve exception error message
clue Nov 20, 2015
0460210
Merge pull request #46 from clue-labs/resolving
clue Nov 21, 2015
7b4cfdc
Test creating invalid socket address and improve test coverage
clue Sep 22, 2015
a9499e7
Close stream resource if connection fails
clue Oct 13, 2015
818fe1c
First class support for PHP7 and HHVM
clue Nov 22, 2015
77ab97a
Merge pull request #47 from clue-labs/invalid-address
cboden Feb 23, 2016
a14adf5
Merge pull request #48 from clue-labs/close
cboden Feb 23, 2016
1cc368e
Merge pull request #54 from clue-labs/php
cboden Feb 23, 2016
7052fe2
Add socket and SSL/TLS context options to connectors
clue Nov 20, 2015
e3d41bc
Work around HHVM not being able to set context options as an array
clue Feb 23, 2016
35524f6
PHP 5.6+ uses new SSL/TLS context options
clue Dec 14, 2015
f58d22f
Merge branch 'context'
cboden Mar 8, 2016
38dbd8f
Merge branch 'new-context'
cboden Mar 8, 2016
1279cb3
Compatiblity with legacy versions
clue Oct 13, 2015
f905ec2
Merge branch 'compat'
cboden Mar 8, 2016
36126a0
Simplify tests by blocking
clue Nov 22, 2015
a825a7c
Add SSL client example
clue Aug 31, 2014
8022ba5
Move example client into a test case
clue Sep 6, 2014
bab3fd1
Test SecureConnector by installing stunnel on Travis
clue Sep 7, 2014
2f49704
Disable peer verification for SecureConnector tests
clue Sep 9, 2014
a072b05
Rely on environment variables to run TLS integration test
clue Mar 8, 2016
e5bf902
Break up into smaller, independent test cases
clue Mar 9, 2016
80a7d04
Install stud from source in Travis' containers (replace stunnel)
clue Mar 12, 2016
72535fc
More reliable tests by awaiting events instead of sleeping
clue Mar 12, 2016
f15683a
Add tests to exhibit SSL/TLS buffering issues
clue Mar 12, 2016
7c79c33
Merge branch 'tests'
cboden Mar 14, 2016
4ed32f2
Prepare v0.5.0 release
clue Mar 19, 2016
67662fe
Support Promise cancellation for TcpConnector
clue Sep 6, 2015
6962034
Add TimeoutConnector decorator
clue Jul 15, 2015
3242509
Support Promise cancellation for TimeoutConnector
clue Nov 15, 2016
d6254e6
Support Promise cancellation for DnsConnector
clue Oct 13, 2015
c47dbbb
Documentation for atomic operation of UnixConnector
clue Oct 17, 2016
edc3e46
Support Promise cancellation for SecureConnector
clue Oct 18, 2016
64b7e2e
Skip TLS tests on outdated HHVM (Travis)
clue Nov 15, 2016
3bcd121
Merge pull request #71 from clue-labs/cancellation
clue Nov 19, 2016
bd03a1c
Merge pull request #51 from clue-labs/timeout
clue Nov 19, 2016
3cb406a
Prepare v0.5.1 release
clue Nov 20, 2016
4d31e9d
Replace SecureStream with unlimited read buffer from react/stream v0.4.5
clue Nov 15, 2016
12a7eaf
Add timeouts for all integration tests
clue Nov 15, 2016
43993f3
Documentation for using SecureConnector WRT default context
clue Dec 6, 2016
0251f7e
Add examples
clue Dec 3, 2016
16ef9c8
Add TimeoutConnector to examples
clue Dec 4, 2016
223e0a3
Merge pull request #72 from clue-labs/wrap
clue Dec 19, 2016
b43838b
Merge pull request #75 from clue-labs/examples
clue Dec 19, 2016
fecbf59
Rename create() to connect()
clue Nov 23, 2015
89ae4f6
Use string URIs instead of host and port
clue Nov 25, 2015
5414f98
Preserve all components from URI when passing through
clue Nov 29, 2016
6c5560b
Prepare v0.5.2 release
clue Dec 19, 2016
867a137
Skip IPv6 tests if not supported by the system
clue Dec 23, 2016
624ef62
Merge pull request #76 from clue-labs/ipv6
clue Dec 23, 2016
cf56ed9
Documentation for ConnectorInterface
clue Dec 21, 2016
aafd20d
Documentation for how all connectors implement ConnectorInterface
clue Dec 23, 2016
4ddda7b
Merge pull request #77 from clue-labs/docs
clue Dec 24, 2016
5570838
Prepare v0.5.3 release
clue Dec 24, 2016
035b373
Merge branch 'master' into uri
clue Jan 5, 2017
c73098b
Simplify test suite by relying on React's secure TLS server
clue Jan 8, 2017
a322101
Merge pull request #78 from clue-labs/tests
clue Jan 9, 2017
1bf5685
Merge pull request #74 from clue-labs/uri
clue Jan 9, 2017
cb51eab
Update README.md
clue Jan 9, 2017
bdc03ce
Require cancellation support
clue Dec 2, 2016
832f6b5
Merge pull request #79 from clue-labs/require-cancellation
clue Jan 12, 2017
5996b69
add phpunit 4.8 to require-dev, force travisci to use local phpunit
Jan 14, 2017
d775015
Merge pull request #80 from shaunbramley/dev-phpunit-4.8
clue Jan 15, 2017
75e9885
Update Socket component to v0.5
clue Feb 14, 2017
ea36cab
Merge pull request #81 from clue-labs/socket
clue Feb 15, 2017
87c77d0
Connections now resolve with a ConnectionInterface
clue Feb 16, 2017
3473047
Merge pull request #82 from clue-labs/connection
clue Feb 16, 2017
c9b7f22
Remove superfluous and undocumented ConnectionException
clue Feb 16, 2017
f841296
Mark all connector classes as final
clue Feb 16, 2017
0e63d30
Merge pull request #84 from clue-labs/exception
clue Feb 16, 2017
733266b
Merge pull request #85 from clue-labs/final
clue Feb 16, 2017
8e3cd4f
Prepare v0.6.0 release
clue Feb 17, 2017
8d6921f
Fix examples to use updated API
clue Mar 8, 2017
1fce343
Forward compatibility with Stream v0.5 and upcoming v0.6
clue Mar 8, 2017
7dc5721
Merge pull request #89 from clue-labs/stream
WyriHaximus Mar 9, 2017
dcac545
Merge pull request #88 from clue-labs/examples
WyriHaximus Mar 9, 2017
a141bb1
Prepare v0.6.1 release
clue Mar 10, 2017
cdbdfe9
HTTP/HTTPS examples accept target host
clue Mar 10, 2017
7c91c7a
Pass through original host to underlying TcpConnector for TLS setup
clue Mar 10, 2017
f797b6a
Work around HHVM being unable to parse URIs with query but no path
clue Mar 11, 2017
773417f
Merge pull request #90 from clue-labs/sni
clue Mar 14, 2017
2589d0f
Documentation for supported PHP versions
clue Mar 17, 2017
856ba6d
Merge pull request #91 from clue-labs/php
clue Mar 17, 2017
e9efc9e
Prepare v0.6.2 release
clue Mar 17, 2017
4c6bc51
Connector class now supports plaintext TCP and secure TLS connections
clue Mar 11, 2017
90d5d1e
Connector is now main class, everything else is advanced usage
clue Mar 10, 2017
07ec684
Simplify DNS setup by using underlying connector hash map
clue Mar 25, 2017
46c7635
Support disabling certain URI schemes
clue Mar 27, 2017
6c88baf
Allow setting TCP and TLS context options
clue Mar 25, 2017
91198c9
Support explicitly passing connectors
clue Mar 25, 2017
03504a1
Add timeout handling
clue Mar 27, 2017
1a0b360
Merge pull request #93 from clue-labs/connector
clue Mar 29, 2017
697fdd9
Update examples to use Stream v0.6 API
clue Mar 29, 2017
88f55f8
Merge pull request #94 from clue-labs/cleanup
clue Mar 30, 2017
8ad621e
Prepare v0.7.0 release
clue Apr 2, 2017
57bfe77
Prepare merging by updating namespace to Socket
clue Apr 2, 2017
f0e9c19
Merge branch 'socket-client-prepared' into merge-socket-client
clue Apr 4, 2017
7bcdfde
Re-structure to ease getting started with merged component
clue Mar 30, 2017
1529ce8
Work around legacy HHVM < 3.8 (does not support TLS connections)
clue Apr 4, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
680 changes: 609 additions & 71 deletions README.md

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
{
"name": "react/socket",
"description": "Async, streaming plaintext TCP/IP and secure TLS socket server for React PHP",
"keywords": ["socket"],
"description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP",
"keywords": ["async", "socket", "stream", "connection", "ReactPHP"],
"license": "MIT",
"require": {
"php": ">=5.3.0",
"evenement/evenement": "~2.0|~1.0",
"react/dns": "0.4.*|0.3.*",
"react/event-loop": "0.4.*|0.3.*",
"react/stream": "^0.6 || ^0.5 || ^0.4.5",
"react/promise": "^2.0 || ^1.1"
"react/promise": "^2.1 || ^1.2",
"react/promise-timer": "~1.0"
},
"require-dev": {
"react/socket-client": "^0.6",
"clue/block-react": "^1.1",
"phpunit/phpunit": "~4.8"
"phpunit/phpunit": "~4.8",
"react/stream": "^0.6"
},
"autoload": {
"psr-4": {
Expand Down
25 changes: 25 additions & 0 deletions examples/11-http.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

use React\EventLoop\Factory;
use React\Socket\Connector;
use React\Socket\ConnectionInterface;

$target = isset($argv[1]) ? $argv[1] : 'www.google.com:80';

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

$loop = Factory::create();
$connector = new Connector($loop);

$connector->connect($target)->then(function (ConnectionInterface $connection) use ($target) {
$connection->on('data', function ($data) {
echo $data;
});
$connection->on('close', function () {
echo '[CLOSED]' . PHP_EOL;
});

$connection->write("GET / HTTP/1.0\r\nHost: $target\r\n\r\n");
}, 'printf');

$loop->run();
25 changes: 25 additions & 0 deletions examples/12-https.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

use React\EventLoop\Factory;
use React\Socket\Connector;
use React\Socket\ConnectionInterface;

$target = isset($argv[1]) ? $argv[1] : 'www.google.com:443';

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

$loop = Factory::create();
$connector = new Connector($loop);

$connector->connect('tls://' . $target)->then(function (ConnectionInterface $connection) use ($target) {
$connection->on('data', function ($data) {
echo $data;
});
$connection->on('close', function () {
echo '[CLOSED]' . PHP_EOL;
});

$connection->write("GET / HTTP/1.0\r\nHost: $target\r\n\r\n");
}, 'printf');

$loop->run();
50 changes: 50 additions & 0 deletions examples/13-netcat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

use React\EventLoop\Factory;
use React\Socket\Connector;
use React\Socket\ConnectionInterface;
use React\Stream\ReadableResourceStream;
use React\Stream\WritableResourceStream;

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

if (!isset($argv[1])) {
fwrite(STDERR, 'Usage error: required argument <host:port>' . PHP_EOL);
exit(1);
}

$loop = Factory::create();
$connector = new Connector($loop);

$stdin = new ReadableResourceStream(STDIN, $loop);
$stdin->pause();
$stdout = new WritableResourceStream(STDOUT, $loop);
$stderr = new WritableResourceStream(STDERR, $loop);

$stderr->write('Connecting' . PHP_EOL);

$connector->connect($argv[1])->then(function (ConnectionInterface $connection) use ($stdin, $stdout, $stderr) {
// pipe everything from STDIN into connection
$stdin->resume();
$stdin->pipe($connection);

// pipe everything from connection to STDOUT
$connection->pipe($stdout);

// report errors to STDERR
$connection->on('error', function ($error) use ($stderr) {
$stderr->write('Stream ERROR: ' . $error . PHP_EOL);
});

// report closing and stop reading from input
$connection->on('close', function () use ($stderr, $stdin) {
$stderr->write('[CLOSED]' . PHP_EOL);
$stdin->close();
});

$stderr->write('Connected' . PHP_EOL);
}, function ($error) use ($stderr) {
$stderr->write('Connection ERROR: ' . $error . PHP_EOL);
});

$loop->run();
47 changes: 47 additions & 0 deletions examples/14-web.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

use React\EventLoop\Factory;
use React\Socket\ConnectionInterface;
use React\Socket\Connector;
use React\Stream\WritableResourceStream;

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

$uri = isset($argv[1]) ? $argv[1] : 'www.google.com';

if (strpos($uri, '://') === false) {
$uri = 'http://' . $uri;
}
$parts = parse_url($uri);

if (!$parts || !isset($parts['scheme'], $parts['host'])) {
fwrite(STDERR, 'Usage error: required argument <host:port>' . PHP_EOL);
exit(1);
}

$loop = Factory::create();
$connector = new Connector($loop);

if (!isset($parts['port'])) {
$parts['port'] = $parts['scheme'] === 'https' ? 443 : 80;
}

$host = $parts['host'];
if (($parts['scheme'] === 'http' && $parts['port'] !== 80) || ($parts['scheme'] === 'https' && $parts['port'] !== 443)) {
$host .= ':' . $parts['port'];
}
$target = ($parts['scheme'] === 'https' ? 'tls' : 'tcp') . '://' . $parts['host'] . ':' . $parts['port'];
$resource = isset($parts['path']) ? $parts['path'] : '/';
if (isset($parts['query'])) {
$resource .= '?' . $parts['query'];
}

$stdout = new WritableResourceStream(STDOUT, $loop);

$connector->connect($target)->then(function (ConnectionInterface $connection) use ($resource, $host, $stdout) {
$connection->pipe($stdout);

$connection->write("GET $resource HTTP/1.0\r\nHost: $host\r\n\r\n");
}, 'printf');

$loop->run();
38 changes: 22 additions & 16 deletions src/ConnectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@
use React\Stream\DuplexStreamInterface;

/**
* Any incoming connection is represented by this interface.
* Any incoming and outgoing connection is represented by this interface,
* such as a normal TCP/IP connection.
*
* An incoming connection is a duplex stream (both readable and writable) that
* implements React's DuplexStreamInterface.
* An incoming or outgoing connection is a duplex stream (both readable and
* writable) that implements React's
* [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).
* It contains additional properties for the local and remote address (client IP)
* where this connection has been established from.
* where this connection has been established to/from.
*
* Note that this interface is only to be used to represent the server-side end
* of an incoming connection.
* It MUST NOT be used to represent an outgoing connection in a client-side
* context.
* If you want to establish an outgoing connection,
* use React's SocketClient component instead.
* Most commonly, instances implementing this `ConnectionInterface` are emitted
* by all classes implementing the [`ServerInterface`](#serverinterface) and
* used by all classes implementing the [`ConnectorInterface`](#connectorinterface).
*
* Because the `ConnectionInterface` implements the underlying
* `DuplexStreamInterface` you can use any of its events and methods as usual:
* [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface)
* you can use any of its events and methods as usual:
*
* ```php
* $connection->on('data', function ($chunk) {
Expand Down Expand Up @@ -49,15 +49,17 @@
* [`DuplexStreamInterface`](https://github.com/reactphp/stream#duplexstreaminterface).
*
* @see DuplexStreamInterface
* @see ServerInterface
* @see ConnectorInterface
*/
interface ConnectionInterface extends DuplexStreamInterface
{
/**
* Returns the remote address (client IP and port) where this connection has been established from
* Returns the remote address (client IP and port) where this connection has been established with
*
* ```php
* $address = $connection->getRemoteAddress();
* echo 'Connection from ' . $address . PHP_EOL;
* echo 'Connection with ' . $address . PHP_EOL;
* ```
*
* If the remote address can not be determined or is unknown at this time (such as
Expand All @@ -70,19 +72,19 @@ interface ConnectionInterface extends DuplexStreamInterface
* ```php
* $address = $connection->getRemoteAddress();
* $ip = trim(parse_url('tcp://' . $address, PHP_URL_HOST), '[]');
* echo 'Connection from ' . $ip . PHP_EOL;
* echo 'Connection with ' . $ip . PHP_EOL;
* ```
*
* @return ?string remote address (client IP and port) or null if unknown
*/
public function getRemoteAddress();

/**
* Returns the full local address (client IP and port) where this connection has been established to
* Returns the full local address (client IP and port) where this connection has been established with
*
* ```php
* $address = $connection->getLocalAddress();
* echo 'Connection to ' . $address . PHP_EOL;
* echo 'Connection with ' . $address . PHP_EOL;
* ```
*
* If the local address can not be determined or is unknown at this time (such as
Expand All @@ -97,6 +99,10 @@ public function getRemoteAddress();
* the address `0.0.0.0`), you can use this method to find out which interface
* actually accepted this connection (such as a public or local interface).
*
* If your system has multiple interfaces (e.g. a WAN and a LAN interface),
* you can use this method to find out which interface was actually
* used for this connection.
*
* @return ?string local address (client IP and port) or null if unknown
* @see self::getRemoteAddress()
*/
Expand Down
127 changes: 127 additions & 0 deletions src/Connector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?php

namespace React\Socket;

use React\EventLoop\LoopInterface;
use React\Dns\Resolver\Resolver;
use React\Dns\Resolver\Factory;
use React\Promise;
use RuntimeException;

/**
* The `Connector` class is the main class in this package that implements the
* `ConnectorInterface` and allows you to create streaming connections.
*
* You can use this connector to create any kind of streaming connections, such
* as plaintext TCP/IP, secure TLS or local Unix connection streams.
*
* Under the hood, the `Connector` is implemented as a *higher-level facade*
* or the lower-level connectors implemented in this package. This means it
* also shares all of their features and implementation details.
* If you want to typehint in your higher-level protocol implementation, you SHOULD
* use the generic [`ConnectorInterface`](#connectorinterface) instead.
*
* @see ConnectorInterface for the base interface
*/
final class Connector implements ConnectorInterface
{
private $connectors = array();

public function __construct(LoopInterface $loop, array $options = array())
{
// apply default options if not explicitly given
$options += array(
'tcp' => true,
'tls' => true,
'unix' => true,

'dns' => true,
'timeout' => true,
);

if ($options['timeout'] === true) {
$options['timeout'] = (float)ini_get("default_socket_timeout");
}

if ($options['tcp'] instanceof ConnectorInterface) {
$tcp = $options['tcp'];
} else {
$tcp = new TcpConnector(
$loop,
is_array($options['tcp']) ? $options['tcp'] : array()
);
}

if ($options['dns'] !== false) {
if ($options['dns'] instanceof Resolver) {
$resolver = $options['dns'];
} else {
$factory = new Factory();
$resolver = $factory->create(
$options['dns'] === true ? '8.8.8.8' : $options['dns'],
$loop
);
}

$tcp = new DnsConnector($tcp, $resolver);
}

if ($options['tcp'] !== false) {
$options['tcp'] = $tcp;

if ($options['timeout'] !== false) {
$options['tcp'] = new TimeoutConnector(
$options['tcp'],
$options['timeout'],
$loop
);
}

$this->connectors['tcp'] = $options['tcp'];
}

if ($options['tls'] !== false) {
if (!$options['tls'] instanceof ConnectorInterface) {
$options['tls'] = new SecureConnector(
$tcp,
$loop,
is_array($options['tls']) ? $options['tls'] : array()
);
}

if ($options['timeout'] !== false) {
$options['tls'] = new TimeoutConnector(
$options['tls'],
$options['timeout'],
$loop
);
}

$this->connectors['tls'] = $options['tls'];
}

if ($options['unix'] !== false) {
if (!$options['unix'] instanceof ConnectorInterface) {
$options['unix'] = new UnixConnector($loop);
}
$this->connectors['unix'] = $options['unix'];
}
}

public function connect($uri)
{
$scheme = 'tcp';
if (strpos($uri, '://') !== false) {
$scheme = (string)substr($uri, 0, strpos($uri, '://'));
}

if (!isset($this->connectors[$scheme])) {
return Promise\reject(new RuntimeException(
'No connector available for URI scheme "' . $scheme . '"'
));
}

return $this->connectors[$scheme]->connect($uri);
}
}

Loading