Skip to content

Commit 0f2a4ec

Browse files
committed
Fix connection cleanup when connecting to same IP multiple times
1 parent 128a9d1 commit 0f2a4ec

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

src/HappyEyeBallsConnectionBuilder.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,20 @@ public function check($resolve, $reject)
145145
{
146146
$ip = \array_shift($this->connectQueue);
147147

148+
// start connection attempt and remember array position to later unset again
149+
$this->connectionPromises[] = $this->attemptConnection($ip);
150+
\end($this->connectionPromises);
151+
$index = \key($this->connectionPromises);
152+
148153
$that = $this;
149-
$that->connectionPromises[$ip] = $this->attemptConnection($ip);
150-
$that->connectionPromises[$ip]->then(function ($connection) use ($that, $ip, $resolve) {
151-
unset($that->connectionPromises[$ip]);
154+
$that->connectionPromises[$index]->then(function ($connection) use ($that, $index, $resolve) {
155+
unset($that->connectionPromises[$index]);
152156

153157
$that->cleanUp();
154158

155159
$resolve($connection);
156-
}, function (\Exception $e) use ($that, $ip, $resolve, $reject) {
157-
unset($that->connectionPromises[$ip]);
160+
}, function (\Exception $e) use ($that, $index, $resolve, $reject) {
161+
unset($that->connectionPromises[$index]);
158162

159163
$that->failureCount++;
160164

tests/HappyEyeBallsConnectionBuilderTest.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,4 +592,33 @@ public function testCheckCallsRejectFunctionImmediateWithoutLeavingDanglingPromi
592592

593593
$this->assertEquals(array(), $promises);
594594
}
595+
596+
public function testCleanUpCancelsAllPendingConnectionAttempts()
597+
{
598+
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
599+
600+
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
601+
$connector->expects($this->exactly(2))->method('connect')->with('tcp://[::1]:80/path?test=yes&hostname=reactphp.org#start')->willReturnOnConsecutiveCalls(
602+
new Promise(function () { }, $this->expectCallableOnce()),
603+
new Promise(function () { }, $this->expectCallableOnce())
604+
);
605+
606+
$resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock();
607+
$resolver->expects($this->never())->method('resolveAll');
608+
609+
$uri = 'tcp://reactphp.org:80/path?test=yes#start';
610+
$host = 'reactphp.org';
611+
$parts = parse_url($uri);
612+
613+
$builder = new HappyEyeBallsConnectionBuilder($loop, $connector, $resolver, $uri, $host, $parts);
614+
615+
$ref = new \ReflectionProperty($builder, 'connectQueue');
616+
$ref->setAccessible(true);
617+
$ref->setValue($builder, array('::1', '::1'));
618+
619+
$builder->check($this->expectCallableNever(), function () { });
620+
$builder->check($this->expectCallableNever(), function () { });
621+
622+
$builder->cleanUp();
623+
}
595624
}

0 commit comments

Comments
 (0)