-
-
Notifications
You must be signed in to change notification settings - Fork 157
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
Hookup happy eyeballs #216
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,12 +4,17 @@ | |
|
||
use Clue\React\Block; | ||
use React\EventLoop\Factory; | ||
use React\Socket\ConnectionInterface; | ||
use React\Socket\Connector; | ||
use React\Socket\ConnectorInterface; | ||
use React\Socket\TcpServer; | ||
|
||
class FunctionalConnectorTest extends TestCase | ||
{ | ||
const TIMEOUT = 1.0; | ||
const TIMEOUT = 30.0; | ||
|
||
private $ipv4; | ||
private $ipv6; | ||
|
||
/** @test */ | ||
public function connectionToTcpServerShouldSucceedWithLocalhost() | ||
|
@@ -29,4 +34,174 @@ public function connectionToTcpServerShouldSucceedWithLocalhost() | |
$connection->close(); | ||
$server->close(); | ||
} | ||
|
||
/** | ||
* @test | ||
* @group internet | ||
*/ | ||
public function connectionToRemoteTCP4n6ServerShouldResultInOurIP() | ||
{ | ||
$loop = Factory::create(); | ||
|
||
$connector = new Connector($loop, array('happy_eyeballs' => true)); | ||
|
||
$ip = Block\await($this->request('dual.tlund.se', $connector), $loop, self::TIMEOUT); | ||
|
||
$this->assertSame($ip, filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6), $ip); | ||
} | ||
|
||
/** | ||
* @test | ||
* @group internet | ||
*/ | ||
public function connectionToRemoteTCP4ServerShouldResultInOurIP() | ||
{ | ||
if ($this->ipv4() === false) { | ||
// IPv4 not supported on this system | ||
$this->assertFalse($this->ipv4()); | ||
return; | ||
} | ||
|
||
$loop = Factory::create(); | ||
|
||
$connector = new Connector($loop, array('happy_eyeballs' => true)); | ||
|
||
$ip = Block\await($this->request('ipv4.tlund.se', $connector), $loop, self::TIMEOUT); | ||
|
||
$this->assertSame($ip, filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4), $ip); | ||
$this->assertFalse(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6), $ip); | ||
} | ||
|
||
/** | ||
* @test | ||
* @group internet | ||
*/ | ||
public function connectionToRemoteTCP6ServerShouldResultInOurIP() | ||
{ | ||
if ($this->ipv6() === false) { | ||
// IPv6 not supported on this system | ||
$this->assertFalse($this->ipv6()); | ||
return; | ||
} | ||
|
||
$loop = Factory::create(); | ||
|
||
$connector = new Connector($loop, array('happy_eyeballs' => true)); | ||
|
||
$ip = Block\await($this->request('ipv6.tlund.se', $connector), $loop, self::TIMEOUT); | ||
|
||
$this->assertFalse(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4), $ip); | ||
$this->assertSame($ip, filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6), $ip); | ||
} | ||
|
||
/** | ||
* @test | ||
* @group internet | ||
* | ||
* @expectedException \RuntimeException | ||
* @expectedExceptionMessageRegExp /Connection to ipv6.tlund.se:80 failed/ | ||
*/ | ||
public function tryingToConnectToAnIPv6OnlyHostWithOutHappyEyeBallsShouldResultInFailure() | ||
{ | ||
$loop = Factory::create(); | ||
|
||
$connector = new Connector($loop, array('happy_eyeballs' => false)); | ||
|
||
Block\await($this->request('ipv6.tlund.se', $connector), $loop, self::TIMEOUT); | ||
} | ||
|
||
/** | ||
* @test | ||
* @group internet | ||
* | ||
* @expectedException \RuntimeException | ||
* @expectedExceptionMessageRegExp /Connection to tcp:\/\/193.15.228.195:80 failed:/ | ||
*/ | ||
public function connectingDirectlyToAnIPv4AddressShouldFailWhenIPv4IsntAvailable() | ||
{ | ||
if ($this->ipv4() === true) { | ||
// IPv4 supported on this system | ||
throw new \RuntimeException('Connection to tcp://193.15.228.195:80 failed:'); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The check makes sense, but I don't link how this marks the whole test result as yellow in a properly configured system (this would match most common systems). This might be preference, but how about using |
||
|
||
$loop = Factory::create(); | ||
|
||
$connector = new Connector($loop); | ||
|
||
$host = current(dns_get_record('ipv4.tlund.se', DNS_A)); | ||
$host = $host['ip']; | ||
Block\await($this->request($host, $connector), $loop, self::TIMEOUT); | ||
} | ||
|
||
/** | ||
* @test | ||
* @group internet | ||
* | ||
* @expectedException \RuntimeException | ||
* @expectedExceptionMessageRegExp /Connection to tcp:\/\/\[2a00:801:f::195\]:80 failed:/ | ||
*/ | ||
public function connectingDirectlyToAnIPv6AddressShouldFailWhenIPv6IsntAvailable() | ||
{ | ||
if ($this->ipv6() === true) { | ||
// IPv6 supported on this system | ||
throw new \RuntimeException('Connection to tcp://[2a00:801:f::195]:80 failed:'); | ||
} | ||
WyriHaximus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
$loop = Factory::create(); | ||
|
||
$connector = new Connector($loop); | ||
|
||
$host = current(dns_get_record('ipv6.tlund.se', DNS_AAAA)); | ||
$host = $host['ipv6']; | ||
$host = '[' . $host . ']'; | ||
$ip = Block\await($this->request($host, $connector), $loop, self::TIMEOUT); | ||
|
||
$this->assertFalse(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4), $ip); | ||
$this->assertSame($ip, filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6), $ip); | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
public function parseIpFromPage($body) | ||
{ | ||
$ex = explode('title="Look up on bgp.he.net">', $body); | ||
$ex = explode('<', $ex[1]); | ||
|
||
return $ex[0]; | ||
} | ||
|
||
private function request($host, ConnectorInterface $connector) | ||
{ | ||
$that = $this; | ||
return $connector->connect($host . ':80')->then(function (ConnectionInterface $connection) use ($host) { | ||
$connection->write("GET / HTTP/1.1\r\nHost: " . $host . "\r\n\r\n"); | ||
|
||
return \React\Promise\Stream\buffer($connection); | ||
})->then(function ($response) use ($that) { | ||
return $that->parseIpFromPage($response); | ||
}); | ||
} | ||
|
||
private function ipv4() | ||
{ | ||
if ($this->ipv4 !== null) { | ||
return $this->ipv4; | ||
} | ||
|
||
$this->ipv4 = !!@file_get_contents('http://ipv4.tlund.se/'); | ||
|
||
return $this->ipv4; | ||
} | ||
|
||
private function ipv6() | ||
{ | ||
if ($this->ipv6 !== null) { | ||
return $this->ipv6; | ||
} | ||
|
||
$this->ipv6 = !!@file_get_contents('http://ipv6.tlund.se/'); | ||
|
||
return $this->ipv6; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test expects an exception and has assertions, can you check which is correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, resolved that 👍