Skip to content

Commit 934cb3e

Browse files
committed
Merge branch 'master' into uri
2 parents 99bbf2e + 04bfd60 commit 934cb3e

15 files changed

Lines changed: 265 additions & 116 deletions

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,4 @@ install:
1414
- COMPOSER_ROOT_VERSION=`git describe --abbrev=0` composer install --no-interaction
1515

1616
script:
17-
- phpunit --coverage-text
17+
- ./vendor/bin/phpunit --coverage-text

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## 0.4.6 (2017-01-26)
4+
5+
* Feature: Support socket context options passed to `Server`
6+
(#64 by @clue)
7+
8+
* Fix: Properly return `null` for unknown addresses
9+
(#63 by @clue)
10+
11+
* Improve documentation for `ServerInterface` and lock test suite requirements
12+
(#60 by @clue, #57 by @shaunbramley)
13+
314
## 0.4.5 (2017-01-08)
415

516
* Feature: Add `SecureServer` for secure TLS connections

README.md

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ The socket component provides a more usable interface for a socket-layer
88
server based on the [`EventLoop`](https://github.com/reactphp/event-loop)
99
and [`Stream`](https://github.com/reactphp/stream) components.
1010

11+
> The master branch contains the code for the upcoming 0.5 release.
12+
For the code of the current stable 0.4.x release, checkout the
13+
[0.4 branch](https://github.com/reactphp/socket-client/tree/0.4).
14+
1115
**Table of Contents**
1216

1317
* [Quickstart example](#quickstart-example)
@@ -16,7 +20,7 @@ and [`Stream`](https://github.com/reactphp/stream) components.
1620
* [connection event](#connection-event)
1721
* [error event](#error-event)
1822
* [getPort()](#getport)
19-
* [shutdown()](#shutdown)
23+
* [close()](#close)
2024
* [Server](#server)
2125
* [SecureServer](#secureserver)
2226
* [ConnectionInterface](#connectioninterface)
@@ -124,16 +128,16 @@ echo 'Server listening on port ' . $port . PHP_EOL;
124128
It will return the port number or `NULL` if it is unknown (not applicable to
125129
this server socket or already closed).
126130

127-
#### shutdown()
131+
#### close()
128132

129-
The `shutdown(): void` method can be used to
133+
The `close(): void` method can be used to
130134
shut down this listening socket.
131135

132136
This will stop listening for new incoming connections on this socket.
133137

134138
```php
135139
echo 'Shutting down server socket' . PHP_EOL;
136-
$server->shutdown();
140+
$server->close();
137141
```
138142

139143
Calling this method more than once on the same instance is a NO-OP.
@@ -156,6 +160,22 @@ provided to the constructor:
156160
$server = new Server('192.168.0.1:8080', $loop);
157161
```
158162

163+
Optionally, you can specify [socket context options](http://php.net/manual/en/context.socket.php)
164+
for the underlying stream socket resource like this:
165+
166+
```php
167+
$server = new Server('[::1]:8080', $loop, array(
168+
'backlog' => 200,
169+
'so_reuseport' => true,
170+
'ipv6_v6only' => true
171+
));
172+
```
173+
174+
> Note that available [socket context options](http://php.net/manual/en/context.socket.php),
175+
their defaults and effects of changing these may vary depending on your system
176+
and/or PHP version.
177+
Passing unknown context options has no effect.
178+
159179
Whenever a client connects, it will emit a `connection` event with a connection
160180
instance implementing [`ConnectionInterface`](#connectioninterface):
161181

@@ -271,17 +291,27 @@ For more details, see the
271291

272292
#### getRemoteAddress()
273293

274-
The `getRemoteAddress(): ?string` method returns the remote address
275-
(client IP) where this connection has been established from.
294+
The `getRemoteAddress(): ?string` method returns the full remote address
295+
(client IP and port) where this connection has been established from.
276296

277297
```php
278-
$ip = $connection->getRemoteAddress();
298+
$address = $connection->getRemoteAddress();
299+
echo 'Connection from ' . $address . PHP_EOL;
279300
```
280301

281-
It will return the remote address as a string value.
282302
If the remote address can not be determined or is unknown at this time (such as
283303
after the connection has been closed), it MAY return a `NULL` value instead.
284304

305+
Otherwise, it will return the full remote address as a string value.
306+
If this is a TCP/IP based connection and you only want the remote IP, you may
307+
use something like this:
308+
309+
```php
310+
$address = $connection->getRemoteAddress();
311+
$ip = trim(parse_url('tcp://' . $address, PHP_URL_HOST), '[]');
312+
echo 'Connection from ' . $ip . PHP_EOL;
313+
```
314+
285315
## Install
286316

287317
The recommended way to install this library is [through Composer](http://getcomposer.org).
@@ -290,7 +320,7 @@ The recommended way to install this library is [through Composer](http://getcomp
290320
This will install the latest supported version:
291321

292322
```bash
293-
$ composer require react/socket:^0.4.5
323+
$ composer require react/socket:^0.4.6
294324
```
295325

296326
More details about version upgrades can be found in the [CHANGELOG](CHANGELOG.md).
@@ -306,10 +336,10 @@ manually specify the root package version like this:
306336
$ COMPOSER_ROOT_VERSION=`git describe --abbrev=0` composer install
307337
```
308338

309-
To run the test suite, you need PHPUnit. Go to the project root and run:
339+
To run the test suite, go to the project root and run:
310340

311341
```bash
312-
$ phpunit
342+
$ php vendor/bin/phpunit
313343
```
314344

315345
## License

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
},
1313
"require-dev": {
1414
"react/socket-client": "^0.5.1",
15-
"clue/block-react": "^1.1"
15+
"clue/block-react": "^1.1",
16+
"phpunit/phpunit": "~4.8"
1617
},
1718
"autoload": {
1819
"psr-4": {

src/Connection.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,22 @@ public function handleClose()
2828

2929
public function getRemoteAddress()
3030
{
31-
return $this->parseAddress(stream_socket_get_name($this->stream, true));
31+
return $this->parseAddress(@stream_socket_get_name($this->stream, true));
3232
}
3333

3434
private function parseAddress($address)
3535
{
36-
return trim(substr($address, 0, strrpos($address, ':')), '[]');
36+
if ($address === false) {
37+
return null;
38+
}
39+
40+
// check if this is an IPv6 address which includes multiple colons but no square brackets
41+
$pos = strrpos($address, ':');
42+
if ($pos !== false && strpos($address, ':') < $pos && substr($address, 0, 1) !== '[') {
43+
$port = substr($address, $pos + 1);
44+
$address = '[' . substr($address, 0, $pos) . ']:' . $port;
45+
}
46+
47+
return $address;
3748
}
3849
}

src/ConnectionInterface.php

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,27 @@
2727
interface ConnectionInterface extends DuplexStreamInterface
2828
{
2929
/**
30-
* Returns the remote address (client IP) where this connection has been established from
30+
* Returns the remote address (client IP and port) where this connection has been established from
3131
*
32-
* @return string|null remote address (client IP) or null if unknown
32+
* ```php
33+
* $address = $connection->getRemoteAddress();
34+
* echo 'Connection from ' . $address . PHP_EOL;
35+
* ```
36+
*
37+
* If the remote address can not be determined or is unknown at this time (such as
38+
* after the connection has been closed), it MAY return a `NULL` value instead.
39+
*
40+
* Otherwise, it will return the full remote address as a string value.
41+
* If this is a TCP/IP based connection and you only want the remote IP, you may
42+
* use something like this:
43+
*
44+
* ```php
45+
* $address = $connection->getRemoteAddress();
46+
* $ip = trim(parse_url('tcp://' . $address, PHP_URL_HOST), '[]');
47+
* echo 'Connection from ' . $ip . PHP_EOL;
48+
* ```
49+
*
50+
* @return string|null remote address (client IP and port) or null if unknown
3351
*/
3452
public function getRemoteAddress();
3553
}

src/SecureServer.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ public function getPort()
7373
return $this->tcp->getPort();
7474
}
7575

76-
public function shutdown()
76+
public function close()
7777
{
78-
return $this->tcp->shutdown();
78+
return $this->tcp->close();
7979
}
8080

8181
/** @internal */

src/Server.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,29 @@ class Server extends EventEmitter implements ServerInterface
5959
* $server = new Server('192.168.0.1:8080', $loop);
6060
* ```
6161
*
62+
* Optionally, you can specify [socket context options](http://php.net/manual/en/context.socket.php)
63+
* for the underlying stream socket resource like this:
64+
*
65+
* ```php
66+
* $server = new Server('[::1]:8080', $loop, array(
67+
* 'backlog' => 200,
68+
* 'so_reuseport' => true,
69+
* 'ipv6_v6only' => true
70+
* ));
71+
* ```
72+
*
73+
* Note that available [socket context options](http://php.net/manual/en/context.socket.php),
74+
* their defaults and effects of changing these may vary depending on your system
75+
* and/or PHP version.
76+
* Passing unknown context options has no effect.
77+
*
6278
* @param string $uri
6379
* @param LoopInterface $loop
80+
* @param array $context
6481
* @throws InvalidArgumentException if the listening address is invalid
6582
* @throws ConnectionException if listening on this address fails (already in use etc.)
6683
*/
67-
public function __construct($uri, LoopInterface $loop)
84+
public function __construct($uri, LoopInterface $loop, array $context = array())
6885
{
6986
$this->loop = $loop;
7087

@@ -98,7 +115,7 @@ public function __construct($uri, LoopInterface $loop)
98115
$errno,
99116
$errstr,
100117
STREAM_SERVER_BIND | STREAM_SERVER_LISTEN,
101-
stream_context_create()
118+
stream_context_create(array('socket' => $context))
102119
);
103120
if (false === $this->master) {
104121
$message = "Could not bind to $uri: $errstr";
@@ -139,7 +156,7 @@ public function getPort()
139156
return (int) substr(strrchr($name, ':'), 1);
140157
}
141158

142-
public function shutdown()
159+
public function close()
143160
{
144161
if (!is_resource($this->master)) {
145162
return;

src/ServerInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,5 @@ public function getPort();
6464
*
6565
* @return void
6666
*/
67-
public function shutdown();
67+
public function close();
6868
}

tests/ConnectionTest.php

Lines changed: 0 additions & 73 deletions
This file was deleted.

0 commit comments

Comments
 (0)