diff --git a/README.md b/README.md index 6c809c2b..65892b47 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,8 @@ If the remote address can not be determined or is unknown at this time (such as after the connection has been closed), it MAY return a `NULL` value instead. Otherwise, it will return the full address (URI) as a string value, such -as `tcp://127.0.0.1:8080`, `tcp://[::1]:80` or `tls://127.0.0.1:443`. +as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`, +`unix://example.sock` or `unix:///path/to/example.sock`. Note that individual URI components are application specific and depend on the underlying transport protocol. @@ -176,7 +177,8 @@ If the local address can not be determined or is unknown at this time (such as after the connection has been closed), it MAY return a `NULL` value instead. Otherwise, it will return the full address (URI) as a string value, such -as `tcp://127.0.0.1:8080`, `tcp://[::1]:80` or `tls://127.0.0.1:443`. +as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`, +`unix://example.sock` or `unix:///path/to/example.sock`. Note that individual URI components are application specific and depend on the underlying transport protocol. @@ -831,6 +833,12 @@ $connector->connect('unix:///tmp/demo.sock')->then(function (ConnectionInterface }); ``` +> The [`getRemoteAddress()`](#getremoteaddress) method will return the target + Unix domain socket (UDS) path as given to the `connect()` method, including + the `unix://` scheme, for example `unix:///tmp/demo.sock`. + The [`getLocalAddress()`](#getlocaladdress) method will most likely return a + `null` value as this value is not applicable to UDS connections here. + Under the hood, the `Connector` is implemented as a *higher-level facade* for the lower-level connectors implemented in this package. This means it also shares all of their features and implementation details. @@ -1209,6 +1217,12 @@ Connecting to Unix domain sockets is an atomic operation, i.e. its promise will settle (either resolve or reject) immediately. As such, calling `cancel()` on the resulting promise has no effect. +> The [`getRemoteAddress()`](#getremoteaddress) method will return the target + Unix domain socket (UDS) path as given to the `connect()` method, prepended + with the `unix://` scheme, for example `unix:///tmp/demo.sock`. + The [`getLocalAddress()`](#getlocaladdress) method will most likely return a + `null` value as this value is not applicable to UDS connections here. + ## Install The recommended way to install this library is [through Composer](http://getcomposer.org). diff --git a/src/Connection.php b/src/Connection.php index 528cb76d..abdf361d 100644 --- a/src/Connection.php +++ b/src/Connection.php @@ -19,6 +19,13 @@ */ class Connection extends EventEmitter implements ConnectionInterface { + /** + * Internal flag whether this is a Unix domain socket (UDS) connection + * + * @internal + */ + public $unix = false; + /** * Internal flag whether encryption has been enabled on this connection * @@ -138,6 +145,22 @@ private function parseAddress($address) return null; } + if ($this->unix) { + // remove trailing colon from address for HHVM < 3.19: https://3v4l.org/5C1lo + // note that techncially ":" is a valid address, so keep this in place otherwise + if (substr($address, -1) === ':' && defined('HHVM_VERSION_ID') && HHVM_VERSION_ID < 31900) { + $address = (string)substr($address, 0, -1); + } + + // work around unknown addresses should return null value: https://3v4l.org/5C1lo + // PHP uses "\0" string and HHVM uses empty string (colon removed above) + if ($address === "\x00" || $address === '') { + return null; + } + + return 'unix://' . $address; + } + // check if this is an IPv6 address which includes multiple colons but no square brackets $pos = strrpos($address, ':'); if ($pos !== false && strpos($address, ':') < $pos && substr($address, 0, 1) !== '[') { diff --git a/src/ConnectionInterface.php b/src/ConnectionInterface.php index 45848bca..64613b58 100644 --- a/src/ConnectionInterface.php +++ b/src/ConnectionInterface.php @@ -66,7 +66,8 @@ interface ConnectionInterface extends DuplexStreamInterface * after the connection has been closed), it MAY return a `NULL` value instead. * * Otherwise, it will return the full address (URI) as a string value, such - * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80` or `tls://127.0.0.1:443`. + * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`, + * `unix://example.sock` or `unix:///path/to/example.sock`. * Note that individual URI components are application specific and depend * on the underlying transport protocol. * @@ -95,7 +96,8 @@ public function getRemoteAddress(); * after the connection has been closed), it MAY return a `NULL` value instead. * * Otherwise, it will return the full address (URI) as a string value, such - * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80` or `tls://127.0.0.1:443`. + * as `tcp://127.0.0.1:8080`, `tcp://[::1]:80`, `tls://127.0.0.1:443`, + * `unix://example.sock` or `unix:///path/to/example.sock`. * Note that individual URI components are application specific and depend * on the underlying transport protocol. * diff --git a/src/UnixConnector.php b/src/UnixConnector.php index bb00f8dd..719db8e9 100644 --- a/src/UnixConnector.php +++ b/src/UnixConnector.php @@ -36,6 +36,9 @@ public function connect($path) return Promise\reject(new RuntimeException('Unable to connect to unix domain socket "' . $path . '": ' . $errstr, $errno)); } - return Promise\resolve(new Connection($resource, $this->loop)); + $connection = new Connection($resource, $this->loop); + $connection->unix = true; + + return Promise\resolve($connection); } } diff --git a/tests/UnixConnectorTest.php b/tests/UnixConnectorTest.php index deb826d7..1c86f616 100644 --- a/tests/UnixConnectorTest.php +++ b/tests/UnixConnectorTest.php @@ -3,6 +3,8 @@ namespace React\Tests\Socket; use React\Socket\UnixConnector; +use Clue\React\Block; +use React\Socket\ConnectionInterface; class UnixConnectorTest extends TestCase { @@ -45,8 +47,19 @@ public function testValid() $promise = $this->connector->connect($path); $promise->then($this->expectCallableOnce()); + // remember remote and local address of this connection and close again + $remote = $local = false; + $promise->then(function(ConnectionInterface $conn) use (&$remote, &$local) { + $remote = $conn->getRemoteAddress(); + $local = $conn->getLocalAddress(); + $conn->close(); + }); + // clean up server fclose($server); unlink($path); + + $this->assertNull($local); + $this->assertEquals('unix://' . $path, $remote); } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy