Skip to content

Commit 2a299b9

Browse files
committed
Merge pull request #16 from clue/react04
Support React v0.4 (while preserving BC)
2 parents 36e5dd6 + c973eb8 commit 2a299b9

4 files changed

Lines changed: 52 additions & 55 deletions

File tree

composer.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@
1515
},
1616
"require": {
1717
"php": ">=5.3",
18-
"react/event-loop": "0.3.*",
19-
"react/socket-client": "0.3.*",
20-
"react/socket": "0.3.*",
21-
"react/dns": "0.3.*",
22-
"react/stream": "0.3.*",
23-
"react/promise": "~1.0",
24-
"evenement/evenement": "~1.0"
18+
"react/event-loop": "0.3.*|0.4.*",
19+
"react/socket-client": "0.3.*|0.4.*",
20+
"react/socket": "0.3.*|0.4.*",
21+
"react/dns": "0.3.*|0.4.*",
22+
"react/stream": "0.3.*|0.4.*",
23+
"react/promise": "~1.0|~2.0",
24+
"evenement/evenement": "~1.0|~2.0"
2525
}
2626
}

composer.lock

Lines changed: 5 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Client.php

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Clue\React\Socks;
44

5-
use React\Promise\When;
65
use React\Promise\Deferred;
76
use React\Dns\Resolver\Factory as DnsFactory;
87
use React\Dns\Resolver\Resolver;
@@ -133,7 +132,9 @@ public function createConnector()
133132
public function getConnection($host, $port)
134133
{
135134
if (strlen($host) > 255 || $port > 65535 || $port < 0) {
136-
return When::reject(new InvalidArgumentException('Invalid target specified'));
135+
$deferred = new Deferred();
136+
$deferred->reject(new InvalidArgumentException('Invalid target specified'));
137+
return $deferred->promise();
137138
}
138139
$deferred = new Deferred();
139140

@@ -155,40 +156,43 @@ public function getConnection($host, $port)
155156

156157
$loop = $this->loop;
157158
$that = $this;
158-
When::all(
159-
array(
160-
$this->connector->create($this->socksHost, $this->socksPort)->then(
161-
null,
162-
function ($error) {
163-
throw new Exception('Unable to connect to socks server', 0, $error);
164-
}
165-
),
166-
$this->resolve($host)->then(
167-
null,
159+
160+
// simultaneously start TCP connection and DNS resolution
161+
$connecting = $this->connector->create($this->socksHost, $this->socksPort);
162+
$resolving = $this->resolve($host);
163+
164+
$deferred->resolve($connecting->then(
165+
function (Stream $stream) use ($that, $resolving, $loop, $timerTimeout, $protocolVersion, $auth, $timestampTimeout, $port) {
166+
// connection established, wait for DNS resolver
167+
return $resolving->then(
168+
function ($host) use ($stream, $port, $timestampTimeout, $that, $loop, $timerTimeout, $protocolVersion, $auth) {
169+
// DNS resolver completed => cancel timeout
170+
$loop->cancelTimer($timerTimeout);
171+
172+
$timeout = max($timestampTimeout - microtime(true), 0.1);
173+
return $that->handleConnectedSocks($stream, $host, $port, $timeout, $protocolVersion, $auth);
174+
},
168175
function ($error) {
169176
throw new Exception('Unable to resolve remote hostname', 0, $error);
170177
}
171-
)
172-
),
173-
function ($fulfilled) use ($deferred, $port, $timestampTimeout, $that, $loop, $timerTimeout, $protocolVersion, $auth) {
174-
$loop->cancelTimer($timerTimeout);
175-
176-
$timeout = max($timestampTimeout - microtime(true), 0.1);
177-
$deferred->resolve($that->handleConnectedSocks($fulfilled[0], $fulfilled[1], $port, $timeout, $protocolVersion, $auth));
178+
);
178179
},
179-
function ($error) use ($deferred, $loop, $timerTimeout) {
180+
function ($error) use ($loop, $timerTimeout) {
180181
$loop->cancelTimer($timerTimeout);
181-
$deferred->reject(new Exception('Unable to connect to socks server', 0, $error));
182+
throw new Exception('Unable to connect to socks server', 0, $error);
182183
}
183-
);
184+
));
185+
184186
return $deferred->promise();
185187
}
186188

187189
private function resolve($host)
188190
{
189191
// return if it's already an IP or we want to resolve remotely (socks 4 only supports resolving locally)
190192
if (false !== filter_var($host, FILTER_VALIDATE_IP) || ($this->protocolVersion !== '4' && !$this->resolveLocal)) {
191-
return When::resolve($host);
193+
$deferred = new Deferred();
194+
$deferred->resolve($host);
195+
return $deferred->promise();
192196
}
193197

194198
return $this->resolver->resolve($host);
@@ -197,10 +201,9 @@ private function resolve($host)
197201
public function handleConnectedSocks(Stream $stream, $host, $port, $timeout, $protocolVersion, $auth=null)
198202
{
199203
$deferred = new Deferred();
200-
$resolver = $deferred->resolver();
201204

202-
$timerTimeout = $this->loop->addTimer($timeout, function () use ($resolver) {
203-
$resolver->reject(new Exception('Timeout while establishing socks session'));
205+
$timerTimeout = $this->loop->addTimer($timeout, function () use ($deferred) {
206+
$deferred->reject(new Exception('Timeout while establishing socks session'));
204207
});
205208

206209
$reader = new StreamReader($stream);
@@ -211,14 +214,14 @@ public function handleConnectedSocks(Stream $stream, $host, $port, $timeout, $pr
211214
} else {
212215
$promise = $this->handleSocks4($stream, $host, $port, $reader);
213216
}
214-
$promise->then(function () use ($resolver, $stream) {
215-
$resolver->resolve($stream);
216-
}, function($error) use ($resolver) {
217-
$resolver->reject(new Exception('Unable to communicate...', 0, $error));
217+
$promise->then(function () use ($deferred, $stream) {
218+
$deferred->resolve($stream);
219+
}, function($error) use ($deferred) {
220+
$deferred->reject(new Exception('Unable to communicate...', 0, $error));
218221
});
219222

220223
$loop = $this->loop;
221-
$deferred->then(
224+
$deferred->promise()->then(
222225
function (Stream $stream) use ($timerTimeout, $loop, $reader) {
223226
$loop->cancelTimer($timerTimeout);
224227
$stream->removeAllListeners('end');
@@ -237,8 +240,8 @@ function ($error) use ($stream, $timerTimeout, $loop, $reader) {
237240
}
238241
);
239242

240-
$stream->on('end', function (Stream $stream) use ($resolver) {
241-
$resolver->reject(new Exception('Premature end while establishing socks session'));
243+
$stream->on('end', function (Stream $stream) use ($deferred) {
244+
$deferred->reject(new Exception('Premature end while establishing socks session'));
242245
});
243246

244247
return $deferred->promise();

src/Server.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Evenement\EventEmitter;
66
use React\Socket\ServerInterface;
7-
use React\Promise\When;
87
use React\Promise\PromiseInterface;
98
use React\Stream\Stream;
109
use React\Dns\Resolver\Factory as DnsFactory;
@@ -15,6 +14,7 @@
1514
use \UnexpectedValueException;
1615
use \InvalidArgumentException;
1716
use \Exception;
17+
use React\Promise\Deferred;
1818

1919
class Server extends EventEmitter
2020
{
@@ -73,7 +73,9 @@ public function setAuth($auth)
7373
if ($ret instanceof PromiseInterface) {
7474
return $ret;
7575
}
76-
return $ret ? When::resolve() : When::reject();
76+
$deferred = new Deferred();
77+
$ret ? $deferred->resolve() : $deferred->reject();
78+
return $deferred->promise();
7779
};
7880
}
7981

0 commit comments

Comments
 (0)